解决缝隙问题
This commit is contained in:
1 parent
351a0a274f
commit
c5f93374f4
1 file changed
+49
-18
+49
-18
@@ -16416,6 +16416,10 @@ bool MeshTexture::RasterizeVirtualFaces(
|
|||||||
outTextures.emplace_back(textureSize, textureSize);
|
outTextures.emplace_back(textureSize, textureSize);
|
||||||
Image8U3& atlas = outTextures.back();
|
Image8U3& atlas = outTextures.back();
|
||||||
atlas.setTo(cv::Scalar(colEmpty.b, colEmpty.g, colEmpty.r));
|
atlas.setTo(cv::Scalar(colEmpty.b, colEmpty.g, colEmpty.r));
|
||||||
|
|
||||||
|
// Pixel8U emptyMarker(255, 0, 255); // BGR: (255, 0, 255) → 品红
|
||||||
|
// atlas.setTo(cv::Scalar(emptyMarker.b, emptyMarker.g, emptyMarker.r));
|
||||||
|
|
||||||
m_texelScores.assign(textureSize * textureSize, TexelScore{});
|
m_texelScores.assign(textureSize * textureSize, TexelScore{});
|
||||||
m_texelPatchID.assign(textureSize * textureSize, NO_ID);
|
m_texelPatchID.assign(textureSize * textureSize, NO_ID);
|
||||||
|
|
||||||
@@ -16543,11 +16547,16 @@ bool MeshTexture::RasterizeVirtualFaces(
|
|||||||
float u = (float)px / (float)textureSize;
|
float u = (float)px / (float)textureSize;
|
||||||
float v_coord = (float)py / (float)textureSize;
|
float v_coord = (float)py / (float)textureSize;
|
||||||
|
|
||||||
// 计算重心坐标
|
// 计算重心坐标
|
||||||
float b0, b1, b2;
|
float b0, b1, b2;
|
||||||
if (!ComputeBarycentric(u, v_coord, uv[0], uv[1], uv[2], b0, b1, b2)) {
|
bool inside = ComputeBarycentric(u, v_coord, uv[0], uv[1], uv[2], b0, b1, b2);
|
||||||
continue;
|
|
||||||
}
|
// // 统一用宽松容差判断
|
||||||
|
// const float EPS_BARY = 1e-2f;
|
||||||
|
// if (b0 < -EPS_BARY || b1 < -EPS_BARY || b2 < -EPS_BARY) {
|
||||||
|
// continue; // 真正不在三角形内
|
||||||
|
// }
|
||||||
|
// // 否则继续执行(即使 ComputeBarycentric 返回 false,但坐标只是略微越界)
|
||||||
|
|
||||||
// 3D 插值点
|
// 3D 插值点
|
||||||
Point3f P = v[0] * b0 + v[1] * b1 + v[2] * b2;
|
Point3f P = v[0] * b0 + v[1] * b1 + v[2] * b2;
|
||||||
@@ -16611,10 +16620,15 @@ bool MeshTexture::RasterizeVirtualFaces(
|
|||||||
float u = (float)px / (float)textureSize;
|
float u = (float)px / (float)textureSize;
|
||||||
float v_coord = (float)py / (float)textureSize;
|
float v_coord = (float)py / (float)textureSize;
|
||||||
|
|
||||||
|
// 计算重心坐标
|
||||||
float b0, b1, b2;
|
float b0, b1, b2;
|
||||||
if (!ComputeBarycentric(u, v_coord, uv[0], uv[1], uv[2], b0, b1, b2)) {
|
bool inside = ComputeBarycentric(u, v_coord, uv[0], uv[1], uv[2], b0, b1, b2);
|
||||||
continue;
|
|
||||||
}
|
// // 统一用宽松容差判断
|
||||||
|
// const float EPS_BARY = 1e-2f;
|
||||||
|
// if (b0 < -EPS_BARY || b1 < -EPS_BARY || b2 < -EPS_BARY) {
|
||||||
|
// continue; // 真正不在三角形内
|
||||||
|
// }
|
||||||
|
|
||||||
Point3f P = v[0] * b0 + v[1] * b1 + v[2] * b2;
|
Point3f P = v[0] * b0 + v[1] * b1 + v[2] * b2;
|
||||||
|
|
||||||
@@ -16719,7 +16733,17 @@ bool MeshTexture::RasterizeVirtualFaces(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 再与 mainFloat 混合(低频占主导,主视图补充细节)
|
// 再与 mainFloat 混合(低频占主导,主视图补充细节)
|
||||||
cv::Mat finalPatch = filledLowFreq * 0.7f + mainFloat * 0.3f;
|
// cv::Mat finalPatch = filledLowFreq * 0.7f + mainFloat * 0.3f;
|
||||||
|
// cv::Mat finalPatch = filledLowFreq * 0.85f + highFreq * 0.15f;
|
||||||
|
|
||||||
|
// 对高频做 soft clamp,防止个别极端值拉白发白
|
||||||
|
cv::Mat highFreqClamped;
|
||||||
|
cv::max(highFreq, -0.2f, highFreqClamped);
|
||||||
|
cv::min(highFreqClamped, 0.2f, highFreqClamped);
|
||||||
|
|
||||||
|
cv::Mat finalPatch = filledLowFreq * 0.8f + highFreqClamped * 0.2f;
|
||||||
|
// cv::Mat finalPatch = mainFloat;
|
||||||
|
// cv::Mat finalPatch = lowFreqPatch;
|
||||||
|
|
||||||
// 钳制到 [0, 1]
|
// 钳制到 [0, 1]
|
||||||
cv::Mat clampedPatch;
|
cv::Mat clampedPatch;
|
||||||
@@ -16737,7 +16761,9 @@ bool MeshTexture::RasterizeVirtualFaces(
|
|||||||
for (int x = 0; x < patchW; ++x) {
|
for (int x = 0; x < patchW; ++x) {
|
||||||
cv::Vec3b color = finalPatch8U.at<cv::Vec3b>(y, x);
|
cv::Vec3b color = finalPatch8U.at<cv::Vec3b>(y, x);
|
||||||
|
|
||||||
if (color[0] == 0 && color[1] == 0 && color[2] == 0) continue;
|
float mx = mapX.at<float>(y, x);
|
||||||
|
float my = mapY.at<float>(y, x);
|
||||||
|
if (mx < 0 || my < 0) continue; // 真正的空洞才跳过
|
||||||
|
|
||||||
int atlasX = x + minX, atlasY = y + minY;
|
int atlasX = x + minX, atlasY = y + minY;
|
||||||
if (atlasX<0||atlasX>=textureSize||atlasY<0||atlasY>=textureSize) continue;
|
if (atlasX<0||atlasX>=textureSize||atlasY<0||atlasY>=textureSize) continue;
|
||||||
@@ -16757,14 +16783,14 @@ bool MeshTexture::RasterizeVirtualFaces(
|
|||||||
|
|
||||||
// 如果已有更高分的 texel,跳过(保持高分优先)
|
// 如果已有更高分的 texel,跳过(保持高分优先)
|
||||||
if (currentScore > m_texelScores[idx].score) {
|
if (currentScore > m_texelScores[idx].score) {
|
||||||
// 如果有旧值,做加权混合
|
// // 如果有旧值,做加权混合
|
||||||
if (m_texelScores[idx].score > 0 && weight < 1.0f) {
|
// if (m_texelScores[idx].score > 0 && weight < 1.0f) {
|
||||||
cv::Vec3b oldColor = atlas.at<cv::Vec3b>(atlasY, atlasX);
|
// cv::Vec3b oldColor = atlas.at<cv::Vec3b>(atlasY, atlasX);
|
||||||
float oldWeight = 1.0f - weight;
|
// float oldWeight = 1.0f - weight;
|
||||||
color[0] = (uchar)(color[0] * weight + oldColor[0] * oldWeight);
|
// color[0] = (uchar)(color[0] * weight + oldColor[0] * oldWeight);
|
||||||
color[1] = (uchar)(color[1] * weight + oldColor[1] * oldWeight);
|
// color[1] = (uchar)(color[1] * weight + oldColor[1] * oldWeight);
|
||||||
color[2] = (uchar)(color[2] * weight + oldColor[2] * oldWeight);
|
// color[2] = (uchar)(color[2] * weight + oldColor[2] * oldWeight);
|
||||||
}
|
// }
|
||||||
|
|
||||||
atlas.at<cv::Vec3b>(atlasY, atlasX) = color;
|
atlas.at<cv::Vec3b>(atlasY, atlasX) = color;
|
||||||
m_texelScores[idx].score = currentScore;
|
m_texelScores[idx].score = currentScore;
|
||||||
@@ -16843,6 +16869,11 @@ bool MeshTexture::RasterizeVirtualFaces(
|
|||||||
|
|
||||||
// cv::imwrite("/home/algo/Documents/openMVS/data/546893/out.546893/debug_atlas_before_return.png", atlas);
|
// cv::imwrite("/home/algo/Documents/openMVS/data/546893/out.546893/debug_atlas_before_return.png", atlas);
|
||||||
|
|
||||||
|
cv::Mat mask;
|
||||||
|
cv::compare(atlas, cv::Scalar(colEmpty.b, colEmpty.g, colEmpty.r), mask, cv::CMP_EQ);
|
||||||
|
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(9, 9));
|
||||||
|
// cv::morphologyEx(atlas, atlas, cv::MORPH_CLOSE, kernel);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user