diff --git a/libs/MVS/SceneTexture.cpp b/libs/MVS/SceneTexture.cpp index 1de3c41..fb7f2b5 100644 --- a/libs/MVS/SceneTexture.cpp +++ b/libs/MVS/SceneTexture.cpp @@ -794,31 +794,102 @@ bool MeshTexture::ListCameraFaces(FaceDataViewArr& facesDatas, float fOutlierThr Mesh::Octree octree; Mesh::FacesInserter::CreateOctree(octree, scene.mesh); - #ifdef TEXOPT_USE_OPENMP - #pragma omp critical(invalid_faces_access) - #endif - { - // scene.mesh.invalidFaces.clear(); - } + // #ifdef TEXOPT_USE_OPENMP + // #pragma omp critical(invalid_faces_access) + // #endif + // { + // // scene.mesh.invalidFaces.clear(); + // } std::vector faceViewCount(faces.size(), 0); - std::vector> faceViewColors(faces.size()); // 存储每个面片在各个视图下的颜色 - std::vector> faceViewQualities(faces.size()); // 存储每个面片在各个视图下的质量 - // extract array of faces viewed by each image IIndexArr views(_views); if (views.empty()) { views.resize(images.size()); std::iota(views.begin(), views.end(), IIndex(0)); } + + Util::Progress progress(_T("Initialized views"), views.size()); + FaceMap faceMap; + DepthMap depthMap; + + // Temp + /* + Util::Progress progress1(_T("Initialized views"), views.size()); + for (IIndex idxView: views) { + Image& imageData = images[idxView]; + if (!imageData.IsValid()) { + ++progress; + continue; + } + + std::string strPath = imageData.name; + size_t lastSlash = strPath.find_last_of("/\\"); + if (lastSlash == std::string::npos) lastSlash = 0; + else lastSlash++; + + size_t lastDot = strPath.find_last_of('.'); + if (lastDot == std::string::npos) lastDot = strPath.size(); + + std::string strName = strPath.substr(lastSlash, lastDot - lastSlash); + + // load image + unsigned level(nResolutionLevel); + const unsigned imageSize(imageData.RecomputeMaxResolution(level, nMinResolution)); + if ((imageData.image.empty() || MAXF(imageData.width,imageData.height) != imageSize) && !imageData.ReloadImage(imageSize)) { + return false; + } + + imageData.UpdateCamera(scene.platforms); + + // select faces inside view frustum + Mesh::FaceIdxArr cameraFaces; + Mesh::FacesInserter inserter(cameraFaces); + const TFrustum frustum(Matrix3x4f(imageData.camera.P), (float)imageData.width, (float)imageData.height); + octree.Traverse(frustum, inserter); + + // project all triangles in this view and keep the closest ones + faceMap.create(imageData.GetSize()); + depthMap.create(imageData.GetSize()); + + RasterMesh rasterer(*this, vertices, imageData.camera, depthMap, faceMap, scene.mesh, false); + RasterMesh::Triangle triangle; + RasterMesh::TriangleRasterizer triangleRasterizer(triangle, rasterer); + + // 简化后的可见性检查 + for (FIndex idxFace : cameraFaces) { + rasterer.validFace = true; + const Face& facet = faces[idxFace]; + rasterer.idxFace = idxFace; + + // 只进行基本的可见性检查 + if (scene.is_face_visible(strName.c_str(), idxFace)) { + // 尝试投影 + rasterer.Project(facet, triangleRasterizer); + + // 如果投影成功,增加计数 + if (rasterer.validFace) { + faceViewCount[idxFace]++; + } + } + } + + ++progress; + } + //*/ + // Temp + + std::vector> faceViewColors(faces.size()); // 存储每个面片在各个视图下的颜色 + std::vector> faceViewQualities(faces.size()); // 存储每个面片在各个视图下的质量 + facesDatas.resize(faces.size()); // viewDepthMaps.resize(views.size()); // 初始化深度图存储 - Util::Progress progress(_T("Initialized views"), views.size()); typedef float real; TImage imageGradMag; TImage::EMat mGrad[2]; - FaceMap faceMap; - DepthMap depthMap; + + Util::Progress progress2(_T("Processing views"), views.size()); + #ifdef TEXOPT_USE_OPENMP bool bAbort(false); #pragma omp parallel for private(imageGradMag, mGrad, faceMap, depthMap) @@ -957,29 +1028,34 @@ bool MeshTexture::ListCameraFaces(FaceDataViewArr& facesDatas, float fOutlierThr const Face& facet = faces[idxFace]; rasterer.idxFace = idxFace; - bool skipVisibilityCheck = false; + bool normal_visible_check = false; int coverage = faceViewCount[idxFace]; - if (coverage < 5) { - skipVisibilityCheck = true; - } + // if (coverage<2||coverage>=8) { + // normal_visible_check = true; + // } bool is_face_visible = scene.is_face_visible(strName.c_str(), idxFace); - // bool is_face_normal_visible_map = scene.is_face_normal_visible_map(strName.c_str(), idxFace); + bool is_face_normal_visible_map = scene.is_face_normal_visible_map(strName.c_str(), idxFace); + bool is_face_edge = scene.is_face_edge(strName.c_str(), idxFace); + bool is_face_delete_edge = scene.is_face_delete_edge(strName.c_str(), idxFace); - // if (is_face_visible && is_face_normal_visible_map) - if (is_face_visible) - // if (skipVisibilityCheck || scene.is_face_visible(strName.c_str(), idxFace)) + if (!is_face_edge) + is_face_normal_visible_map = true; + + if (is_face_visible && is_face_normal_visible_map) + // if (is_face_visible) { rasterer.Project(facet, triangleRasterizer); if (!rasterer.validFace) rasterer.Project(facet, triangleRasterizer); - // 如果投影成功,增加面片覆盖率计数 - // if (rasterer.validFace) { - // faceViewCount[idxFace]++; - // } + // 如果投影成功,增加面片覆盖率计数 + // if (rasterer.validFace) + // { + // faceViewCount[idxFace]++; + // } } } @@ -1146,94 +1222,6 @@ bool MeshTexture::ListCameraFaces(FaceDataViewArr& facesDatas, float fOutlierThr ++progress; } - // Temp - /* - // 第一步:计算每个面片的最终颜色(基于最接近平均颜色的3个视图) - #if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA - Colors faceFinalColors; // 存储每个面片的最终颜色 - std::vector faceFinalQualities(faces.size(), 0.0f); // 存储每个面片的最终质量 - - // 使用循环初始化 - for (size_t i = 0; i < faces.size(); ++i) { - faceFinalColors.push_back(Color::ZERO); - } - - for (FIndex idxFace = 0; idxFace < faces.size(); ++idxFace) { - const std::vector& colors = faceViewColors[idxFace]; - const std::vector& qualities = faceViewQualities[idxFace]; - - if (colors.empty()) { - continue; - } - - // 1. 计算所有视图颜色的平均值 - Color avgColor = Color::ZERO; - for (const Color& color : colors) { - avgColor += color; - } - avgColor /= (float)colors.size(); - - // 2. 计算每个视图颜色与平均值的差异 - std::vector> colorDistances; // (距离, 索引) - colorDistances.reserve(colors.size()); - - for (size_t i = 0; i < colors.size(); ++i) { - float distance = cv::norm(colors[i] - avgColor); - colorDistances.emplace_back(distance, i); - } - - // 3. 按距离排序(从小到大) - std::sort(colorDistances.begin(), colorDistances.end(), - [](const std::pair& a, const std::pair& b) { - return a.first < b.first; - }); - - const Image& imageData = images[idxView]; - std::string strPath = imageData.name; - size_t lastSlash = strPath.find_last_of("/\\"); - if (lastSlash == std::string::npos) lastSlash = 0; // 若无分隔符,从头开始 - else lastSlash++; // 跳过分隔符 - // 查找扩展名分隔符 '.' 的位置 - size_t lastDot = strPath.find_last_of('.'); - if (lastDot == std::string::npos) lastDot = strPath.size(); // 若无扩展名,截到末尾 - // 截取文件名(不含路径和扩展名) - std::string strName = strPath.substr(lastSlash, lastDot - lastSlash); - bool is_face_normal_visible_map = scene.is_face_normal_visible_map(strName.c_str(), idxFace); - - // 4. 只保留最接近的3个视图 - size_t numToKeep = colorDistances.size(); // std::min((size_t)3, colorDistances.size()); - Color finalColor = Color::ZERO; - float finalQuality = 0.0f; - - for (size_t i = 0; i < numToKeep; ++i) { - int viewIdx = colorDistances[i].second; - finalColor += colors[viewIdx]; - finalQuality += qualities[viewIdx]; - } - - // 5. 计算最终颜色和质量 - finalColor /= (float)numToKeep; - finalQuality /= (float)numToKeep; - - faceFinalColors[idxFace] = finalColor; - faceFinalQualities[idxFace] = finalQuality; - - // 第二步:更新facesDatas,只保留最终颜色和质量 - FaceDataArr& faceDatas = facesDatas[idxFace]; - if (!faceDatas.empty()) { - // 只保留第一个FaceData,并用最终颜色和质量更新它 - faceDatas.resize(1); - FaceData& faceData = faceDatas.back(); - faceData.quality = finalQuality; - faceData.color = finalColor; - // 注意:这里不再保留原始的idxView,因为颜色是多个视图的混合 - // 您可能需要根据需要调整idxView的值 - } - } - #endif - //*/ - // Temp - #ifdef TEXOPT_USE_OPENMP if (bAbort) return false; diff --git a/libs/MVS/mask_face_occlusion.py b/libs/MVS/mask_face_occlusion.py index f885628..71fc22f 100755 --- a/libs/MVS/mask_face_occlusion.py +++ b/libs/MVS/mask_face_occlusion.py @@ -1420,7 +1420,7 @@ class ModelProcessor: angles_deg = torch.acos(torch.clamp(cos_angles, -1.0, 1.0)) * 180.0 / torch.pi # 4. 创建法线可见性掩码(夹角 ≤ 45度) - normal_visible_mask = angles_deg <= 70.0 + normal_visible_mask = angles_deg <= 40.0 # 5. 结合遮挡可见性和法线可见性 face_normal_visible = face_visible & normal_visible_mask @@ -1428,8 +1428,8 @@ class ModelProcessor: # 使用与CPU版本相同的后续处理 shrunk_visibility = self._shrink_face_visibility(face_visible.cpu().numpy(), 9) - expanded_visibility = self._expand_face_visibility(face_visible.cpu().numpy(), 30) - shrunk_visibility2 = self._shrink_face_visibility(face_visible.cpu().numpy(), 50) + expanded_visibility = self._expand_face_visibility(face_visible.cpu().numpy(), 0) + shrunk_visibility2 = self._shrink_face_visibility(face_visible.cpu().numpy(), 0) expanded_edge = expanded_visibility & ~shrunk_visibility2 delete_edge = face_visible.cpu().numpy() & ~shrunk_visibility