Browse Source

颜色溢出进一步优化

master
hesuicong 1 month ago
parent
commit
488f5a3f93
  1. 206
      libs/MVS/SceneTexture.cpp
  2. 6
      libs/MVS/mask_face_occlusion.py

206
libs/MVS/SceneTexture.cpp

@ -794,31 +794,102 @@ bool MeshTexture::ListCameraFaces(FaceDataViewArr& facesDatas, float fOutlierThr @@ -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<int> faceViewCount(faces.size(), 0);
std::vector<std::vector<Color>> faceViewColors(faces.size()); // 存储每个面片在各个视图下的颜色
std::vector<std::vector<float>> 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<float,5> 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<std::vector<Color>> faceViewColors(faces.size()); // 存储每个面片在各个视图下的颜色
std::vector<std::vector<float>> faceViewQualities(faces.size()); // 存储每个面片在各个视图下的质量
facesDatas.resize(faces.size());
// viewDepthMaps.resize(views.size()); // 初始化深度图存储
Util::Progress progress(_T("Initialized views"), views.size());
typedef float real;
TImage<real> imageGradMag;
TImage<real>::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,27 +1028,32 @@ bool MeshTexture::ListCameraFaces(FaceDataViewArr& facesDatas, float fOutlierThr @@ -957,27 +1028,32 @@ 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_edge)
is_face_normal_visible_map = true;
// 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_visible && is_face_normal_visible_map)
// if (is_face_visible)
{
rasterer.Project(facet, triangleRasterizer);
if (!rasterer.validFace)
rasterer.Project(facet, triangleRasterizer);
// 如果投影成功,增加面片覆盖率计数
// if (rasterer.validFace) {
// if (rasterer.validFace)
// {
// faceViewCount[idxFace]++;
// }
}
@ -1146,94 +1222,6 @@ bool MeshTexture::ListCameraFaces(FaceDataViewArr& facesDatas, float fOutlierThr @@ -1146,94 +1222,6 @@ bool MeshTexture::ListCameraFaces(FaceDataViewArr& facesDatas, float fOutlierThr
++progress;
}
// Temp
/*
// 第一步:计算每个面片的最终颜色(基于最接近平均颜色的3个视图)
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
Colors faceFinalColors; // 存储每个面片的最终颜色
std::vector<float> 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<Color>& colors = faceViewColors[idxFace];
const std::vector<float>& 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<std::pair<float, int>> 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<float, int>& a, const std::pair<float, int>& 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;

6
libs/MVS/mask_face_occlusion.py

@ -1420,7 +1420,7 @@ class ModelProcessor: @@ -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: @@ -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

Loading…
Cancel
Save