diff --git a/libs/MVS/SceneTexture.cpp b/libs/MVS/SceneTexture.cpp index 4d27028..edf3dff 100644 --- a/libs/MVS/SceneTexture.cpp +++ b/libs/MVS/SceneTexture.cpp @@ -140,7 +140,6 @@ struct TRWSInference { } #endif - // S T R U C T S /////////////////////////////////////////////////// typedef Mesh::Vertex Vertex; @@ -489,6 +488,11 @@ public: v[0] + v1 * T(1.772) ); } + + static inline float GetLuminance(const Color& rgb) { + Color ycbcr = MeshTexture::RGB2YCBCR(rgb); + return ycbcr[0]; // Y分量就是亮度 + } //*/ /* // 采用ITU-R BT.601标准系数,增加数值稳定性处理 @@ -2771,6 +2775,7 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA } std::vector> sortedViews; + std::vector> sortedLuminViews; std::vector> validViews; sortedViews.reserve(centerFaceDatas.size()); for (const FaceData& fd : centerFaceDatas) { @@ -2780,10 +2785,12 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA // invalidView = fd.idxView; // invalidQuality = fd.quality; sortedViews.emplace_back(fd.quality, fd.color); + sortedLuminViews.emplace_back(MeshTexture::GetLuminance(fd.color), fd.color); } else { sortedViews.emplace_back(fd.quality, fd.color); + sortedLuminViews.emplace_back(MeshTexture::GetLuminance(fd.color), fd.color); validViews.emplace_back(fd.quality, fd.color); } } @@ -2792,6 +2799,26 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA std::sort(validViews.begin(), validViews.end(), [](const auto& a, const auto& b) { return a.first > b.first; }); + int nSize = sortedViews.size(); + // 计算初始平均值 + float totalQuality = 0.0f; + Color totalColor(0,0,0); + for (int n = 0; n < nSize; ++n) { + totalQuality += sortedViews[n].first; + totalColor += sortedViews[n].second; + } + const float avgQuality = totalQuality / nSize; + const Color avgColor = totalColor / nSize; + + float totalLuminance = MeshTexture::GetLuminance(totalColor); + float avgLuminance = totalLuminance / nSize; + + std::sort(sortedLuminViews.begin(), sortedLuminViews.end(), + [avgLuminance](const auto& a, const auto& b) { + float luminDistA = cv::norm(avgLuminance - a.first); + float luminDistB = cv::norm(avgLuminance - b.first); + return luminDistA < luminDistB; }); + // select the common cameras Mesh::FaceIdxArr virtualFace; FaceDataArr virtualFaceDatas; @@ -2915,7 +2942,7 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA // if (faceData.bInvalidFacesRelative) if (bHasInvalidView) { - ++processedFaces; + // ++processedFaces; } else { @@ -2931,24 +2958,107 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA } } + float maxLuminance = 150.0f; + float minLuminance = 20.0f; if (bHasInvalidView) { if (validViews.size()<=0) { - int nSize = (sortedViews.size()>1) ? 1 : sortedViews.size(); - for (int n=0; n 3) ? 3 : sortedViews.size(); + + // // 计算初始平均值 + // float totalQuality = 0.0f; + // Color totalColor(0,0,0); + // for (int n = 0; n < nSize; ++n) { + // totalQuality += sortedViews[n].first; + // totalColor += sortedViews[n].second; + // } + // const float avgQuality = totalQuality / nSize; + // const Color avgColor = totalColor / nSize; + + // 过滤偏差过大的视图 + std::vector validIndices; + float maxColorDeviation = 0.01f; // 颜色偏差阈值 + float maxLuminanceDeviation = 0.01f; + + for (int n = 0; n < nSize; ++n) { + const Color& viewColor = sortedViews[n].second; + float colorDistance = cv::norm(avgColor - viewColor); + // printf("colorDistance=%f\n", colorDistance); + + float viewLuminance = MeshTexture::GetLuminance(viewColor); + float luminanceDistance = cv::norm(avgLuminance - viewLuminance); + // printf("viewLuminance=%f\n", viewLuminance); + + if ((colorDistance<=maxColorDeviation)&& + (viewLuminance<=maxLuminance)&& + (viewLuminance>=minLuminance)){ + // if ((colorDistance <= maxColorDeviation) && + // (luminanceDistance <= maxLuminanceDeviation)) { + validIndices.push_back(n); + } } - virtualFaceData.quality /= nSize; - #if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA - virtualFaceData.color /= nSize; - #endif + + if (validIndices.empty()) { + for (int n = 0; n < nSize; ++n) { + const Color& viewColor = sortedViews[n].second; + float colorDistance = cv::norm(avgColor - viewColor); + + if (colorDistance <= maxColorDeviation) { + validIndices.push_back(n); + } + } + } + + float totalLuminance = MeshTexture::GetLuminance(totalColor); + float avgLuminance = totalLuminance / nSize; + for (int n = 0; n < nSize; ++n) { + const Color& viewColor = sortedViews[n].second; + float viewLuminance = MeshTexture::GetLuminance(viewColor); + float luminanceDistance = cv::norm(avgLuminance - viewLuminance); + // printf("luminanceDistance=%f\n", luminanceDistance); + if (luminanceDistance <= maxLuminanceDeviation) { + // validIndices.push_back(n); + } + } + + // 如果所有视图都被排除,保留原始平均值 + if (validIndices.empty()) { + // virtualFaceData.quality = avgQuality; + // virtualFaceData.color = avgColor; + // virtualFaceData.quality = avgQuality; + // virtualFaceData.color = sortedLuminViews[0].second; + + for (int n = 0; n < nSize; ++n) { + float lumin = sortedLuminViews[n].first; + + if (lumin>=minLuminance&&lumin<=maxLuminance) + { + // virtualFaceData.quality = avgQuality; + // virtualFaceData.color = sortedLuminViews[0].second; + break; + } + } + } + else { + // 使用过滤后的视图重新计算平均值 + totalQuality = 0.0f; + totalColor = Color(0,0,0); + for (int idx : validIndices) { + totalQuality += sortedViews[idx].first; + totalColor += sortedViews[idx].second; + } + virtualFaceData.quality = totalQuality / validIndices.size(); + virtualFaceData.color = totalColor / validIndices.size(); + } + //*/ } else { - int nSize = (validViews.size()>1) ? 1 : validViews.size(); + /* + // int nSize = (validViews.size()>1) ? 1 : validViews.size(); + int nSize = validViews.size(); for (int n=0; n 3) ? 3 : validViews.size(); + + // 计算初始平均值 + float totalQuality = 0.0f; + Color totalColor(0,0,0); + for (int n = 0; n < nSize; ++n) { + totalQuality += validViews[n].first; + totalColor += validViews[n].second; + } + const float avgQuality = totalQuality / nSize; + const Color avgColor = totalColor / nSize; + + // 过滤偏差过大的视图 + std::vector validIndices; + float maxColorDeviation = 0.5f; // 颜色偏差阈值 + + for (int n = 0; n < nSize; ++n) { + const Color& viewColor = validViews[n].second; + float colorDistance = cv::norm(avgColor - viewColor); + // printf("colorDistance=%f\n", colorDistance); + float viewLuminance = MeshTexture::GetLuminance(viewColor); + // if ((colorDistance<=maxColorDeviation)&& + // (viewLuminance<=maxLuminance)&& + // (viewLuminance>=minLuminance)){ + if (colorDistance <= maxColorDeviation) { + validIndices.push_back(n); + } + } + + // float totalLuminance = MeshTexture::GetLuminance(totalColor); + // float avgLuminance = totalLuminance / nSize; + float maxLuminanceDeviation = 0.01f; + for (int n = 0; n < nSize; ++n) { + const Color& viewColor = sortedViews[n].second; + float viewLuminance = MeshTexture::GetLuminance(viewColor); + float luminanceDistance = cv::norm(avgLuminance - viewLuminance); + // printf("luminanceDistance=%f\n", luminanceDistance); + if (luminanceDistance <= maxLuminanceDeviation) { + // validIndices.push_back(n); + } + } + + // 如果所有视图都被排除,保留原始平均值 + if (validIndices.empty()) { + // virtualFaceData.quality = avgQuality; + // virtualFaceData.color = avgColor; + // virtualFaceData.quality = avgQuality; + // virtualFaceData.color = sortedLuminViews[0].second; + for (int n = 0; n < nSize; ++n) { + float lumin = sortedLuminViews[n].first; + + if (lumin>=minLuminance&&lumin<=maxLuminance) + { + // virtualFaceData.quality = avgQuality; + // virtualFaceData.color = sortedLuminViews[0].second; + break; + } + } + } + else { + // 使用过滤后的视图重新计算平均值 + totalQuality = 0.0f; + totalColor = Color(0,0,0); + for (int idx : validIndices) { + totalQuality += validViews[idx].first; + totalColor += validViews[idx].second; + } + virtualFaceData.quality = totalQuality / validIndices.size(); + virtualFaceData.color = totalColor / validIndices.size(); + } + //*/ } } else