Browse Source

优化染色版本

master
hesuicong 4 weeks ago
parent
commit
1086eb09c5
  1. 139
      libs/MVS/SceneTexture.cpp

139
libs/MVS/SceneTexture.cpp

@ -476,6 +476,8 @@ public: @@ -476,6 +476,8 @@ public:
bool CreateVirtualFaces7(FaceDataViewArr& facesDatas, FaceDataViewArr& virtualFacesDatas, VirtualFaceIdxsArr& virtualFaces, std::vector<bool>& isVirtualFace, unsigned minCommonCameras=2, float thMaxNormalDeviation=25.f) const;
IIndexArr SelectBestViews(const FaceDataArr& faceDatas, FIndex fid, unsigned minCommonCameras, float ratioAngleToQuality) const;
IIndexArr SelectBestViews2(const FaceDataArr& faceDatas, FIndex fid, unsigned minCommonCameras, float ratioAngleToQuality, FaceDataViewArr& facesDatas) const;
IIndexArr SelectBestView(const FaceDataArr& faceDatas, FIndex fid, unsigned minCommonCameras, float ratioAngleToQuality) const;
bool FaceViewSelection(unsigned minCommonCameras, float fOutlierThreshold, float fRatioDataSmoothness, int nIgnoreMaskLabel, const IIndexArr& views);
@ -1776,6 +1778,97 @@ void MeshTexture::PerformLocalDepthConsistencyCheck(DepthMap& depthMap, FaceMap& @@ -1776,6 +1778,97 @@ void MeshTexture::PerformLocalDepthConsistencyCheck(DepthMap& depthMap, FaceMap&
}
//*/
IIndexArr MeshTexture::SelectBestViews2(const FaceDataArr& faceDatas, FIndex fid, unsigned minCommonCameras, float ratioAngleToQuality, FaceDataViewArr& facesDatas) const
{
ASSERT(!faceDatas.empty());
// 计算每个视图能看到的相邻面片数量
std::unordered_map<IIndex, int> viewCoverageCount;
for (const FaceData& fd : faceDatas) {
if (!fd.bInvalidFacesRelative) {
viewCoverageCount[fd.idxView] = 0;
}
}
// 统计每个视图能看到的面片数
for (const FaceData& fd : faceDatas) {
if (!fd.bInvalidFacesRelative) {
// 统计这个视图能看到的所有相邻面片
const Mesh::FaceFaces& ffaces = faceFaces[fid];
for (int i = 0; i < 3; ++i) {
const FIndex neighborIdx = ffaces[i];
if (neighborIdx != NO_ID) {
const FaceDataArr& neighborDatas = facesDatas[neighborIdx];
for (const FaceData& neighborFd : neighborDatas) {
if (neighborFd.idxView == fd.idxView && !neighborFd.bInvalidFacesRelative) {
viewCoverageCount[fd.idxView]++;
break;
}
}
}
}
}
}
// 重新计算分数,考虑覆盖范围
float maxQuality = 0;
for (const FaceData& faceData: faceDatas)
maxQuality = MAXF(maxQuality, faceData.quality);
const Face& f = faces[fid];
const Vertex faceCenter((vertices[f[0]] + vertices[f[1]] + vertices[f[2]]) / 3.f);
CLISTDEF0IDX(float,IIndex) scores(faceDatas.size());
FOREACH(idxFaceData, faceDatas) {
const FaceData& faceData = faceDatas[idxFaceData];
if (faceData.bInvalidFacesRelative) {
scores[idxFaceData] = -1.0f; // 无效视图分数为负
continue;
}
const Image& imageData = images[faceData.idxView];
const Point3f camDir(Cast<Mesh::Type>(imageData.camera.C) - faceCenter);
const Normal& faceNormal = scene.mesh.faceNormals[fid];
const float cosFaceCam(ComputeAngle(camDir.ptr(), faceNormal.ptr()));
// 计算覆盖范围分数(0-1之间)
float coverageScore = 0.0f;
if (viewCoverageCount.find(faceData.idxView) != viewCoverageCount.end()) {
int maxCoverage = 0;
for (const auto& pair : viewCoverageCount) {
maxCoverage = MAX(maxCoverage, pair.second);
}
if (maxCoverage > 0) {
coverageScore = static_cast<float>(viewCoverageCount[faceData.idxView]) / maxCoverage;
}
}
// 综合角度、质量和覆盖范围
const float angleScore = ratioAngleToQuality * cosFaceCam;
const float qualityScore = (1.0f - ratioAngleToQuality) * faceData.quality / maxQuality;
const float coverageWeight = 0.3f; // 覆盖范围权重
const float combinedScore = 0.4f * angleScore + 0.3f * qualityScore + coverageWeight * coverageScore;
scores[idxFaceData] = combinedScore;
}
// 按分数排序
IIndexArr scorePodium(faceDatas.size());
std::iota(scorePodium.begin(), scorePodium.end(), 0);
scorePodium.Sort([&scores](IIndex i, IIndex j) {
return scores[i] > scores[j];
});
// 选择最佳视图
IIndexArr cameras;
for (IIndex i = 0; i < MIN(minCommonCameras, faceDatas.size()); ++i) {
if (scores[scorePodium[i]] > 0.1f) { // 分数阈值
cameras.push_back(faceDatas[scorePodium[i]].idxView);
}
}
return cameras;
}
// order the camera view scores with highest score first and return the list of first <minCommonCameras> cameras
// ratioAngleToQuality represents the ratio in witch we combine normal angle to quality for a face to obtain the selection score
// - a ratio of 1 means only angle is considered
@ -2962,8 +3055,8 @@ bool MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA @@ -2962,8 +3055,8 @@ bool MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA
ASSERT(posToErase != Mesh::FaceIdxArr::NO_INDEX);
remainingFaces.RemoveAtMove(posToErase);
} else {
// IIndexArr selectedCams = SelectBestViews2(centerFaceDatas, virtualFaceCenterFaceID, minCommonCameras, ratioAngleToQuality, facesDatas);
IIndexArr selectedCams = SelectBestViews(centerFaceDatas, virtualFaceCenterFaceID, minCommonCameras, ratioAngleToQuality);
//*
// 获取中心面片的法线 (注意变量名是 normalCenter, 不是 centerNormal)
const Normal& normalCenter = scene.mesh.faceNormals[virtualFaceCenterFaceID];
@ -4228,6 +4321,16 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView @@ -4228,6 +4321,16 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView
cQueue<FIndex, FIndex, 0> currentVirtualFaceQueue;
std::unordered_set<FIndex> queuedFaces;
// std::vector<std::unordered_set<IIndex>> faceValidCameras(faces.size());
// for (FIndex idxFace = 0; idxFace < faces.size(); ++idxFace) {
// const FaceDataArr& faceDatas = facesDatas[idxFace];
// for (const FaceData& fd : faceDatas) {
// if (!fd.bInvalidFacesRelative) {
// faceValidCameras[idxFace].insert(fd.idxView);
// }
// }
// }
// Precompute average color for each face
Colors faceColors; // 创建一个空列表
faceColors.reserve(faces.size()); // 预分配空间(如果cList有reserve方法且您关心性能)
@ -4326,7 +4429,7 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView @@ -4326,7 +4429,7 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView
remainingFaces.RemoveAtMove(posToErase);
} else {
IIndexArr selectedCams = SelectBestViews(centerFaceDatas, virtualFaceCenterFaceID, minCommonCameras, ratioAngleToQuality);
// IIndexArr selectedCams = SelectBestViews2(centerFaceDatas, virtualFaceCenterFaceID, minCommonCameras, ratioAngleToQuality, facesDatas);
//*
// 获取中心面片的法线 (注意变量名是 normalCenter, 不是 centerNormal)
const Normal& normalCenter = scene.mesh.faceNormals[virtualFaceCenterFaceID];
@ -4383,7 +4486,7 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView @@ -4383,7 +4486,7 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView
{
// printf("CreateVirtualFace %s, %d, %f\n", strName.c_str(), virtualFaceCenterFaceID, angleLimit);
if (angleDeg <= 45.0f)
if (angleDeg <= 35.0f)
{
filteredCams.push_back(idxView);
/*
@ -4455,22 +4558,40 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView @@ -4455,22 +4558,40 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView
do {
const FIndex currentFaceId = currentVirtualFaceQueue.GetHead();
currentVirtualFaceQueue.PopHead();
// check for condition to add in current virtual face
// normal angle smaller than thMaxNormalDeviation degrees
const Normal& faceNormal = scene.mesh.faceNormals[currentFaceId];
const float cosFaceToCenter(ComputeAngleN(normalCenter.ptr(), faceNormal.ptr()));
// if (cosFaceToCenter < cosMaxNormalDeviation)
if (cosFaceToCenter < dynamicCosTh)
continue;
// if (cosFaceToCenter < dynamicCosTh) // 使用动态阈值
// continue;
// printf("dynamicCosTh=%f\n", dynamicCosTh);
// if (cosFaceToCenter < 0.99) // 对应60度,比原来的更宽松
// continue;
if (cosFaceToCenter < dynamicCosTh) // 使用动态阈值
continue;
// check if current face is seen by all cameras in selectedCams
ASSERT(!selectedCams.empty());
if (!IsFaceVisible(facesDatas[currentFaceId], selectedCams))
continue;
// Check color similarity
// 3. 放宽颜色差异条件
const Color& centerColor = faceColors[virtualFaceCenterFaceID];
const Color& currentColor = faceColors[currentFaceId];
float colorDistance = cv::norm(centerColor - currentColor);
if (colorDistance > 200.0f) { // 从200.0f放宽到250.0f
// continue; // 如果颜色差异太大,跳过
}
// check if current face is seen by all cameras in selectedCams
// ASSERT(!selectedCams.empty());
// if (!IsFaceVisible(facesDatas[currentFaceId], selectedCams))
// continue;
// // Check color similarity
// const Color& centerColor = faceColors[virtualFaceCenterFaceID];
// const Color& currentColor = faceColors[currentFaceId];
// if (cv::norm(centerColor) > 1e-5 && cv::norm(currentColor) > 1e-5)
{
float colorDistance = cv::norm(centerColor - currentColor);
@ -7040,7 +7161,7 @@ bool MeshTexture::FaceViewSelection3( unsigned minCommonCameras, float fOutlierT @@ -7040,7 +7161,7 @@ bool MeshTexture::FaceViewSelection3( unsigned minCommonCameras, float fOutlierT
}
}
*/
// construct and use virtual faces for patch creation instead of actual mesh faces;
// the virtual faces are composed of coplanar triangles sharing same views
if (bUseVirtualFaces) {
@ -7058,7 +7179,7 @@ bool MeshTexture::FaceViewSelection3( unsigned minCommonCameras, float fOutlierT @@ -7058,7 +7179,7 @@ bool MeshTexture::FaceViewSelection3( unsigned minCommonCameras, float fOutlierT
CreateVirtualFaces62(facesDatas, virtualFacesDatas, virtualFaces, isVirtualFace, minCommonCameras);
TD_TIMER_STARTD();
// CreateVirtualFaces7(facesDatas, virtualFacesDatas, virtualFaces, isVirtualFace, minCommonCameras);
DEBUG_EXTRA("CreateVirtualFaces7 completed: %s", TD_TIMER_GET_FMT().c_str());
DEBUG_EXTRA("CreateVirtualFaces completed: %s", TD_TIMER_GET_FMT().c_str());
size_t controlCounter(0);
FOREACH(idxVF, virtualFaces) {

Loading…
Cancel
Save