From 9d29df54a990c8fd708db680515cdaf63b0821bb Mon Sep 17 00:00:00 2001 From: hesuicong Date: Fri, 31 Jul 2026 14:48:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=AD=E9=97=B4=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs/MVS/SceneTexture.cpp | 114 +++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 63 deletions(-) diff --git a/libs/MVS/SceneTexture.cpp b/libs/MVS/SceneTexture.cpp index 84fc378..969a31e 100644 --- a/libs/MVS/SceneTexture.cpp +++ b/libs/MVS/SceneTexture.cpp @@ -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(imgPtDouble.x), + static_cast(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(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. 最终写入纹理