|
|
|
@ -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}); |
|
|
|
|