From 1421d21597f95a7ce35796dd1d5c2141a614feee Mon Sep 17 00:00:00 2001 From: hesuicong Date: Sat, 30 May 2026 15:18:09 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=9B=E4=B8=80=E6=AD=A5=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- libs/MVS/SceneTexture.cpp | 128 +++++++++----------------------------- 1 file changed, 30 insertions(+), 98 deletions(-) diff --git a/libs/MVS/SceneTexture.cpp b/libs/MVS/SceneTexture.cpp index 97ec91a..721c17a 100644 --- a/libs/MVS/SceneTexture.cpp +++ b/libs/MVS/SceneTexture.cpp @@ -4345,7 +4345,7 @@ bool MeshTexture::CreateVirtualFaces63(FaceDataViewArr& facesDatas, FaceDataView // 动态法线阈值 const float centerCurvature = meshCurvatures[virtualFaceCenterFaceID]; - const float dynamicThreshold = (centerCurvature < 0.2f) ? 15.0f : 8.0f; + const float dynamicThreshold = (centerCurvature < 0.2f) ? 18.0f : 10.0f; // 放宽角度阈值 const float dynamicCosTh = COS(FD2R(dynamicThreshold)); ASSERT(currentVirtualFaceQueue.IsEmpty()); @@ -4468,32 +4468,20 @@ bool MeshTexture::CreateVirtualFaces63(FaceDataViewArr& facesDatas, FaceDataView } // 按angleDeg从小到大排序 - std::sort(cameraAngles.begin(), cameraAngles.end(), + std::vector> sortedCams = cameraAngles; + std::sort(sortedCams.begin(), sortedCams.end(), [](const std::pair& a, const std::pair& b) { return a.second < b.second; }); IIndexArr filteredCams; - - // 核心优化:根据中心面片质量决定选择多少张视图 - if (centerFaceQuality >= QUALITY_THRESHOLD) { - // 质量高于阈值,尽量使用同一张视图(角度最小的) - if (!cameraAngles.empty()) { - // 只选择角度最小的一张视图 - filteredCams.push_back(cameraAngles[0].first); - } else if (!selectedCams.empty()) { - // 如果没有符合条件的相机,回退到原始选择中的第一个 - filteredCams.push_back(selectedCams[0]); - } - } else { - // 质量低于阈值,可以选择多张视图 - size_t count = std::min(cameraAngles.size(), static_cast(3)); - for (size_t i = 0; i < count; ++i) { - filteredCams.push_back(cameraAngles[i].first); - } + size_t count = std::min(sortedCams.size(), static_cast(3)); + for (size_t i = 0; i < count; ++i) { + filteredCams.push_back(sortedCams[i].first); } if (filteredCams.empty()) { + // 处理空情况 selectedCams = filteredCams; isVirtualFace[virtualFaceCenterFaceID] = false; } else { @@ -4516,15 +4504,18 @@ bool MeshTexture::CreateVirtualFaces63(FaceDataViewArr& facesDatas, FaceDataView if (!IsFaceVisible(facesDatas[currentFaceId], selectedCams)) continue; + // 修改3:调整颜色差异检查 const Color& centerColor = faceColors[virtualFaceCenterFaceID]; const Color& currentColor = faceColors[currentFaceId]; float colorDistance = cv::norm(centerColor - currentColor); - if (colorDistance > 200.0f) { - // continue; // 可选:如果颜色差异太大,跳过 + + // 放宽颜色差异条件 + if (colorDistance > 250.0f) { // 增加阈值 + // 不跳过,继续处理 } - + if (colorDistance > thMaxColorDeviation) { - // continue; // 可选:如果颜色差异太大,跳过 + // 保持原有逻辑 } { @@ -4550,6 +4541,7 @@ bool MeshTexture::CreateVirtualFaces63(FaceDataViewArr& facesDatas, FaceDataView // 计算虚拟面质量并创建虚拟面 for (IIndex idxView: selectedCams) { FaceData& virtualFaceData = virtualFaceDatas.emplace_back(); + virtualFaceData.quality = 0; virtualFaceData.idxView = idxView; #if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA @@ -4587,88 +4579,28 @@ bool MeshTexture::CreateVirtualFaces63(FaceDataViewArr& facesDatas, FaceDataView int validViewsSize = validViews.size(); if (bHasInvalidView) { + // 使用简化逻辑 const Color medianColor = ComputeMedianColorAndQuality(sortedViews).color; const float medianQuality = ComputeMedianColorAndQuality(sortedViews).quality; - const float medianLuminance = ComputeMedianLuminance(sortedViews); - const float colorMAD = ComputeColorMAD(sortedViews, medianColor); - const float luminanceMAD = ComputeLuminanceMAD(sortedViews, medianLuminance); - const float maxColorDeviation = 0.01f * colorMAD; - const float maxLuminanceDeviation = 0.01f * luminanceMAD; - - std::vector validIndices; - for (int n = 0; n < sortedViews.size(); ++n) { - const Color& viewColor = sortedViews[n].second; - const float viewLuminance = MeshTexture::GetLuminance(viewColor); - const float colorDistance = cv::norm(viewColor - medianColor); - const float luminanceDistance = std::abs(viewLuminance - medianLuminance); - - if (colorDistance <= maxColorDeviation && luminanceDistance <= maxLuminanceDeviation) { - if (scene.is_face_normal_visible_map(strName, virtualFaceCenterFaceID)) - validIndices.push_back(n); - } else { - const FIndex currentFaceId = currentVirtualFaceQueue.GetHead(); - const Normal& faceNormal = scene.mesh.faceNormals[currentFaceId]; - const float cosFaceToCenter(ComputeAngleN(normalCenter.ptr(), faceNormal.ptr())); - bool bColorSimilarity = true; - const Color& centerColor = faceColors[virtualFaceCenterFaceID]; - const Color& currentColor = faceColors[currentFaceId]; - float colorDistance2 = cv::norm(centerColor - currentColor); - if (colorDistance2 > thMaxColorDeviation) { - bColorSimilarity = false; - } - - if (cosFaceToCenter 0); - virtualFaceData.quality = 0; - #if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA - virtualFaceData.color = Point3f::ZERO; - #endif + // 直接使用中位数计算 + virtualFaceData.quality = medianQuality; + virtualFaceData.color = medianColor; } else { - const Color medianColor = ComputeMedianColorAndQuality(sortedViews).color; - const float medianQuality = ComputeMedianColorAndQuality(sortedViews).quality; - const float medianLuminance = ComputeMedianLuminance(sortedViews); - const float colorMAD = ComputeColorMAD(sortedViews, medianColor); - const float luminanceMAD = ComputeLuminanceMAD(sortedViews, medianLuminance); - const float maxColorDeviation = 0.01f * colorMAD; - const float maxLuminanceDeviation = 0.05f * luminanceMAD; - - std::vector validIndices; - for (int n = 0; n < sortedViews.size(); ++n) { - const Color& viewColor = sortedViews[n].second; - const float viewLuminance = MeshTexture::GetLuminance(viewColor); - const float colorDistance = cv::norm(viewColor - medianColor); - const float luminanceDistance = std::abs(viewLuminance - medianLuminance); - validIndices.push_back(n); - } - - if (validIndices.empty()) { - virtualFaceData.quality = medianQuality; - virtualFaceData.color = medianColor; - } else { + // 使用有效视图计算 + if (!validViews.empty()) { float totalQuality2 = 0.0f; Color totalColor2 = Color(0,0,0); - for (int idx : validIndices) { - totalQuality2 += validViews[idx].first; - totalColor2 += validViews[idx].second; + for (const auto& v : validViews) { + totalQuality2 += v.first; + totalColor2 += v.second; } - virtualFaceData.quality = totalQuality2 / validIndices.size(); - virtualFaceData.color = totalColor2 / validIndices.size(); + virtualFaceData.quality = totalQuality2 / validViews.size(); + virtualFaceData.color = totalColor2 / validViews.size(); + } else { + // 回退到平均值 + virtualFaceData.quality = avgQuality; + virtualFaceData.color = avgColor; } } }