Browse Source

进一步优化

ManualUV
hesuicong 7 days ago
parent
commit
ddb42d08f4
  1. 66
      libs/MVS/SceneTexture.cpp

66
libs/MVS/SceneTexture.cpp

@ -616,6 +616,8 @@ public:
unsigned nTextureSizeMultiple, unsigned nTextureSizeMultiple,
Pixel8U colEmpty, Pixel8U colEmpty,
float fSharpnessWeight); float fSharpnessWeight);
float ComputeViewWeight(const Image& image, const Vertex& faceCenter, const Vertex& normal);
float ComputeProjectedArea(const Vertex& faceCenter, const Vertex& normal, const Camera& camera);
void FillTextureGaps(Image8U3& texture, Pixel8U colEmpty); void FillTextureGaps(Image8U3& texture, Pixel8U colEmpty);
void ApplyColorConsistencyOptimization( void ApplyColorConsistencyOptimization(
Image8U3& texture, Image8U3& texture,
@ -13855,6 +13857,57 @@ void MeshTexture::ApplyColorConsistencyOptimization(
} }
} }
// 改进的视图权重计算
float MeshTexture::ComputeViewWeight(const Image& image, const Vertex& faceCenter, const Vertex& normal)
{
// 1. 视角质量(法线与视线夹角)
Vertex cameraPos(image.camera.C.x, image.camera.C.y, image.camera.C.z);
Vertex viewDir = cameraPos - faceCenter;
float distance = cv::norm(viewDir);
if (distance < 1e-6f) return 0.0f;
viewDir = viewDir / distance;
float cosAngle = std::abs(viewDir.dot(normal));
float angleScore = cosAngle; // 角度越接近0度,得分越高
// 2. 距离衰减
float distanceScore = 1.0f / (1.0f + distance * 0.001f);
// 3. 图像分辨率
// 计算3D面在图像中的投影面积
float areaInPixels = ComputeProjectedArea(faceCenter, normal, image.camera);
float resolutionScore = std::min(1.0f, areaInPixels / 100.0f);
// 4. 图像质量(可选,如果有质量评估的话)
// float qualityScore = image.GetQualityScore();
// 综合权重
float weight = angleScore * 0.4f + distanceScore * 0.3f + resolutionScore * 0.3f;
return std::max(0.0f, std::min(1.0f, weight));
}
float MeshTexture::ComputeProjectedArea(const Vertex& faceCenter, const Vertex& normal,
const Camera& camera)
{
// 简化的投影面积计算
// 假设三角面是单位面积,根据相机距离和夹角计算投影面积
Vertex cameraPos(camera.C.x, camera.C.y, camera.C.z);
Vertex viewDir = cameraPos - faceCenter;
float distance = cv::norm(viewDir);
if (distance < 1e-6f) return 0.0f;
viewDir = viewDir / distance;
float cosAngle = std::abs(viewDir.dot(normal));
// 投影面积 = 原始面积 * cos(夹角) / 距离²
float projectionArea = cosAngle / (distance * distance);
return std::max(0.0f, projectionArea);
}
Mesh::Image8U3Arr MeshTexture::GenerateTextureAtlasWith3DBridge( Mesh::Image8U3Arr MeshTexture::GenerateTextureAtlasWith3DBridge(
const LabelArr& faceLabels, const LabelArr& faceLabels,
const IIndexArr& views, const IIndexArr& views,
@ -14059,6 +14112,8 @@ Mesh::Image8U3Arr MeshTexture::GenerateTextureAtlasWith3DBridge(
// 找出每个面的其他可见视图 // 找出每个面的其他可见视图
std::vector<std::vector<IIndex>> faceVisibleViews(scene.mesh.faces.size()); std::vector<std::vector<IIndex>> faceVisibleViews(scene.mesh.faces.size());
std::vector<Vertex> faceNormals(scene.mesh.faces.size());
#ifdef _USE_OPENMP #ifdef _USE_OPENMP
#pragma omp parallel for schedule(dynamic) #pragma omp parallel for schedule(dynamic)
#endif #endif
@ -14076,6 +14131,12 @@ Mesh::Image8U3Arr MeshTexture::GenerateTextureAtlasWith3DBridge(
normal = crossProduct / (float)normVal; // 归一化 normal = crossProduct / (float)normVal; // 归一化
} }
if (normVal > 0) {
faceNormals[idxFace] = crossProduct / (float)normVal; // 归一化
} else {
faceNormals[idxFace] = Vertex(0, 0, 1); // 默认法向量
}
// 计算面中心 // 计算面中心
Vertex faceCenter(0, 0, 0); Vertex faceCenter(0, 0, 0);
for (int v = 0; v < 3; ++v) { for (int v = 0; v < 3; ++v) {
@ -14119,8 +14180,11 @@ Mesh::Image8U3Arr MeshTexture::GenerateTextureAtlasWith3DBridge(
float resolution = 1.0f / (float)projDist; float resolution = 1.0f / (float)projDist;
const Vertex& faceNormal = faceNormals[idxFace];
// 综合得分 // 综合得分
float score = viewAngle * resolution; // float score = viewAngle * resolution;
float score = ComputeViewWeight(images[i], faceCenter, faceNormal);
if (score > 0.1f) { // 阈值 if (score > 0.1f) { // 阈值
viewScores.push_back({score, i}); viewScores.push_back({score, i});

Loading…
Cancel
Save