Browse Source

中间版本

ManualUV
hesuicong 2 weeks ago
parent
commit
9d29df54a9
  1. 114
      libs/MVS/SceneTexture.cpp

114
libs/MVS/SceneTexture.cpp

@ -14268,78 +14268,66 @@ bool MeshTexture::RasterizeVirtualFaces( @@ -14268,78 +14268,66 @@ bool MeshTexture::RasterizeVirtualFaces(
}
if (!validIndices) continue;
for (int y = minY; y <= maxY; ++y) {
for (int x = minX; x <= maxX; ++x) {
Point2f texCoord(
(x + 0.5f) / textureSize,
(y + 0.5f) / textureSize
);
for (int y = minY; y <= maxY; ++y) {
for (int x = minX; x <= maxX; ++x) {
Point2f texCoord(
(x + 0.5f) / textureSize,
(y + 0.5f) / textureSize
);
Point3f bary;
if (!PointInTriangle(texCoord, uv[0], uv[1], uv[2], bary))
continue;
Point3f bary;
if (!PointInTriangle(texCoord, uv[0], uv[1], uv[2], bary))
continue;
// ✅ 透视校正插值
// 计算插值后的1/z
float invZ = bary.x / vertexDepths[0] +
bary.y / vertexDepths[1] +
bary.z / vertexDepths[2];
if (invZ <= 0.0f) continue;
float depth = 1.0f / invZ; // 校正后的深度
// ✅ 透视校正的世界坐标
Point3f P(
(verts[0]->x * bary.x / vertexDepths[0] +
verts[1]->x * bary.y / vertexDepths[1] +
verts[2]->x * bary.z / vertexDepths[2]) * depth,
(verts[0]->y * bary.x / vertexDepths[0] +
verts[1]->y * bary.y / vertexDepths[1] +
verts[2]->y * bary.z / vertexDepths[2]) * depth,
(verts[0]->z * bary.x / vertexDepths[0] +
verts[1]->z * bary.y / vertexDepths[1] +
verts[2]->z * bary.z / vertexDepths[2]) * depth
);
// ✅ 透视校正插值(double 精度)
double invZ = bary.x / vertexDepths[0] +
bary.y / vertexDepths[1] +
bary.z / vertexDepths[2];
if (invZ <= 0.0) continue;
// ✅ 正确的深度测试:只保留更近的像素
if (depth <= 0.0f) continue;
// ✅ 校正后的重心坐标
double u0 = (bary.x / vertexDepths[0]) / invZ;
double u1 = (bary.y / vertexDepths[1]) / invZ;
double u2 = (bary.z / vertexDepths[2]) / invZ;
// ✅ 透视校正的世界坐标(double)
Point3d P_double(
(verts[0]->x * bary.x / vertexDepths[0] +
verts[1]->x * bary.y / vertexDepths[1] +
verts[2]->x * bary.z / vertexDepths[2]) / invZ,
(verts[0]->y * bary.x / vertexDepths[0] +
verts[1]->y * bary.y / vertexDepths[1] +
verts[2]->y * bary.z / vertexDepths[2]) / invZ,
(verts[0]->z * bary.x / vertexDepths[0] +
verts[1]->z * bary.y / vertexDepths[1] +
verts[2]->z * bary.z / vertexDepths[2]) / invZ
verts[0]->x * u0 + verts[1]->x * u1 + verts[2]->x * u2,
verts[0]->y * u0 + verts[1]->y * u1 + verts[2]->y * u2,
verts[0]->z * u0 + verts[1]->z * u1 + verts[2]->z * u2
);
Point2f imgPt = cam.ProjectPoint(P_double);
// 边界检查
if (imgPt.x < 0.5f || imgPt.y < 0.5f ||
imgPt.x >= srcW - 0.5f || imgPt.y >= srcH - 0.5f)
continue;
// ✅ 正确的投影(double → float)
Point2d imgPtDouble = cam.ProjectPoint(P_double);
Point2f imgPt(static_cast<float>(imgPtDouble.x),
static_cast<float>(imgPtDouble.y));
// ✅ 双线性采样(关键!)
Color color = BilinearSample(srcImg.image, imgPt);
if (color[0] < 0 || color[1] < 0 || color[2] < 0) continue;
// ✅ 边界检查
if (imgPt.x < 0.5f || imgPt.y < 0.5f ||
imgPt.x >= srcW - 0.5f || imgPt.y >= srcH - 0.5f)
continue;
// ✅ 单一临界区:原子更新深度和颜色
#pragma omp critical
{
if (depth < depthBuffer(y, x)) {
depthBuffer(y, x) = depth;
colorBuffer(y, x) = cv::Vec3f(color[0], color[1], color[2]); // BGR->RGB
validBuffer(y, x) = 1;
}
}
}
}
}
}
// ✅ 双线性采样
Color color = BilinearSample(srcImg.image, imgPt);
if (color[0] < 0 || color[1] < 0 || color[2] < 0) continue;
// ✅ 深度测试(float 缓冲,double 比较)
float depthFloat = static_cast<float>(1.0 / invZ);
#pragma omp critical
{
if (depthFloat < depthBuffer(y, x)) {
depthBuffer(y, x) = depthFloat;
colorBuffer(y, x) = cv::Vec3f(
color[0], color[1], color[2]
);
validBuffer(y, x) = 1;
}
}
}
}
}
}
// --------------------------------------------------
// 4. 最终写入纹理

Loading…
Cancel
Save