diff --git a/libs/MVS/SceneTexture.cpp b/libs/MVS/SceneTexture.cpp index f09fa61..4718995 100644 --- a/libs/MVS/SceneTexture.cpp +++ b/libs/MVS/SceneTexture.cpp @@ -4433,7 +4433,76 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView //* // 获取中心面片的法线 (注意变量名是 normalCenter, 不是 centerNormal) const Normal& normalCenter = scene.mesh.faceNormals[virtualFaceCenterFaceID]; - // 过滤selectedCams:只保留夹角小于30度的视图 + + std::map mapSortedcams; + for (IIndex idxView : selectedCams) + { + const Image& imageData = images[idxView]; + // 计算相机在世界坐标系中的朝向向量(相机镜面法线) + const RMatrix& R = imageData.camera.R; + // 相机局部坐标系中的向前向量 (0,0,-1) + Point3f localForward(0.0f, 0.0f, -1.0f); + // 手动计算矩阵乘法:cameraForward = R * localForward + Point3f cameraForward; + cameraForward.x = R(0,0) * localForward.x + R(0,1) * localForward.y + R(0,2) * localForward.z; + cameraForward.y = R(1,0) * localForward.x + R(1,1) * localForward.y + R(1,2) * localForward.z; + cameraForward.z = R(2,0) * localForward.x + R(2,1) * localForward.y + R(2,2) * localForward.z; + + // 手动归一化 cameraForward + float norm = std::sqrt(cameraForward.x * cameraForward.x + + cameraForward.y * cameraForward.y + + cameraForward.z * cameraForward.z); + if (norm > 0.0f) { + cameraForward.x /= norm; + cameraForward.y /= norm; + cameraForward.z /= norm; + } else { + cameraForward = Point3f(0, 0, -1); + } + + Point3f normalPoint(normalCenter.x, normalCenter.y, normalCenter.z); + float cosAngle = cameraForward.dot(normalPoint); + float angleDeg = std::acos(cosAngle) * 180.0f / M_PI; + + std::string strPath = imageData.name; + std::string strName = MeshTexture::GetFileNameWithoutExtension(strPath); + + if (!scene.is_face_delete_edge(strName, virtualFaceCenterFaceID)) { + + if (scene.is_face_edge(strName, virtualFaceCenterFaceID)) + { + if (angleDeg <= 40.0f) + { + mapSortedcams[idxView] = angleDeg; + } + } + else + { + mapSortedcams[idxView] = angleDeg; + } + } + } + + // 将map中的元素放入vector以便排序 + std::vector> sortedCams; + sortedCams.reserve(mapSortedcams.size()); + for (const auto& pair : mapSortedcams) { + sortedCams.emplace_back(pair.first, pair.second); + } + + // 按angleDeg从小到大排序 + std::sort(sortedCams.begin(), sortedCams.end(), + [](const std::pair& a, const std::pair& b) { + return a.second < b.second; // 按angleDeg排序 + }); + + IIndexArr filteredCams; + size_t count = std::min(sortedCams.size(), static_cast(3)); + for (size_t i = 0; i < count; ++i) { + filteredCams.push_back(sortedCams[i].first); + } + + /* IIndexArr filteredCams; // 用于存储过滤后的视图索引 for (IIndex idxView : selectedCams) { const Image& imageData = images[idxView]; @@ -4467,17 +4536,18 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView float angleDeg = std::acos(cosAngle) * 180.0f / M_PI; // 将弧度转换为角度 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 = MeshTexture::GetFileNameWithoutExtension(strPath); + // size_t lastSlash = strPath.find_last_of("/\\"); + // if (lastSlash == std::string::npos) lastSlash = 0; // 若无分隔符,从头开始 + // else lastSlash++; // 跳过分隔符 - // 截取文件名(不含路径和扩展名) - std::string strName = strPath.substr(lastSlash, lastDot - lastSlash); + // // 查找扩展名分隔符 '.' 的位置 + // size_t lastDot = strPath.find_last_of('.'); + // if (lastDot == std::string::npos) lastDot = strPath.size(); // 若无扩展名,截到末尾 + // // 截取文件名(不含路径和扩展名) + // std::string strName = strPath.substr(lastSlash, lastDot - lastSlash); + // printf("CreateVirtualFace %s, %d\n", strName.c_str(), virtualFaceCenterFaceID); if (!scene.is_face_delete_edge(strName, virtualFaceCenterFaceID)) @@ -4486,26 +4556,25 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView { // printf("CreateVirtualFace %s, %d, %f\n", strName.c_str(), virtualFaceCenterFaceID, angleLimit); - if (angleDeg <= 35.0f) + if (angleDeg <= 40.0f) { filteredCams.push_back(idxView); - /* - float brightnessScore = CalculateBrightnessScore(imageData); // 亮度评分函数 - float angleScore = 1.0f - (angleDeg / 45.0f); - float qualityScore = 0.0f; - const FaceDataArr& centerFaceDatas = facesDatas[virtualFaceCenterFaceID]; - for (const FaceData& fd : centerFaceDatas) { - if (fd.idxView == idxView) { - qualityScore = fd.quality; - break; - } - } - qualityScore = std::max(0.0f, std::min(1.0f, qualityScore)); - float overallScore = 0.5f * angleScore + 0.3f * brightnessScore + 0.2f * qualityScore; - if (overallScore > 0.04f) { - filteredCams.push_back(idxView); - } - //*/ + + // float brightnessScore = CalculateBrightnessScore(imageData); // 亮度评分函数 + // float angleScore = 1.0f - (angleDeg / 45.0f); + // float qualityScore = 0.0f; + // const FaceDataArr& centerFaceDatas = facesDatas[virtualFaceCenterFaceID]; + // for (const FaceData& fd : centerFaceDatas) { + // if (fd.idxView == idxView) { + // qualityScore = fd.quality; + // break; + // } + // } + // qualityScore = std::max(0.0f, std::min(1.0f, qualityScore)); + // float overallScore = 0.5f * angleScore + 0.3f * brightnessScore + 0.2f * qualityScore; + // if (overallScore > 0.04f) { + // filteredCams.push_back(idxView); + // } } } @@ -4516,26 +4585,25 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView filteredCams.push_back(idxView); } - /* - float brightnessScore = CalculateBrightnessScore(imageData); // 亮度评分函数 - float angleScore = 1.0f - (angleDeg / 45.0f); - float qualityScore = 0.0f; - const FaceDataArr& centerFaceDatas = facesDatas[virtualFaceCenterFaceID]; - for (const FaceData& fd : centerFaceDatas) { - if (fd.idxView == idxView) { - qualityScore = fd.quality; - break; - } - } - qualityScore = std::max(0.0f, std::min(1.0f, qualityScore)); - float overallScore = 0.5f * angleScore + 0.3f * brightnessScore + 0.2f * qualityScore; - if (overallScore > 0.02f) { - filteredCams.push_back(idxView); - } - //*/ + // float brightnessScore = CalculateBrightnessScore(imageData); // 亮度评分函数 + // float angleScore = 1.0f - (angleDeg / 45.0f); + // float qualityScore = 0.0f; + // const FaceDataArr& centerFaceDatas = facesDatas[virtualFaceCenterFaceID]; + // for (const FaceData& fd : centerFaceDatas) { + // if (fd.idxView == idxView) { + // qualityScore = fd.quality; + // break; + // } + // } + // qualityScore = std::max(0.0f, std::min(1.0f, qualityScore)); + // float overallScore = 0.5f * angleScore + 0.3f * brightnessScore + 0.2f * qualityScore; + // if (overallScore > 0.02f) { + // filteredCams.push_back(idxView); + // } } } } + */ // 确保 selectedCams 是非 const 的,才能对其进行赋值 // 例如,其声明应为:IIndexArr selectedCams = ...; (不能是 const IIndexArr)