清晰化
This commit is contained in:
1 parent
e5411b42b4
commit
fb5839c8e7
1 file changed
+70
-50
+70
-50
@@ -14169,7 +14169,14 @@ bool MeshTexture::RasterizeVirtualFaces(
|
|||||||
|
|
||||||
// 投影到图像
|
// 投影到图像
|
||||||
Point2f imgPt = ProjectPointWithAutoCorrection(cam, P, srcImg);
|
Point2f imgPt = ProjectPointWithAutoCorrection(cam, P, srcImg);
|
||||||
if (!srcImg.image.isInside(imgPt) || !cam.IsInFront(P))
|
// 允许少量越界
|
||||||
|
if (!srcImg.image.isInside(imgPt)) {
|
||||||
|
imgPt.x = std::clamp(imgPt.x, 0.f, srcImg.image.width() - 1.1f);
|
||||||
|
imgPt.y = std::clamp(imgPt.y, 0.f, srcImg.image.height() - 1.1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 放宽前后判断(允许微小负值)
|
||||||
|
if (!cam.IsInFront(P) && cam.Distance(P) < -0.01f)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// 双三次采样
|
// 双三次采样
|
||||||
@@ -14217,89 +14224,93 @@ bool MeshTexture::RasterizeVirtualFaces(
|
|||||||
|
|
||||||
float MeshTexture::EstimatePixelSize(const Point3f& faceCenter, const Normal& faceNormal,
|
float MeshTexture::EstimatePixelSize(const Point3f& faceCenter, const Normal& faceNormal,
|
||||||
const Image& image) {
|
const Image& image) {
|
||||||
// 获取面片的近似面积(使用网格中存储的面片面积,如果有的话)
|
|
||||||
// 如果没有,我们可以通过三角形面积公式计算
|
|
||||||
// 这里假设我们有一个方法获取面片面积,或者通过顶点计算
|
|
||||||
|
|
||||||
// 简化版本:使用面片到相机的距离和相机焦距来估算像素大小
|
|
||||||
const Camera& cam = image.camera;
|
const Camera& cam = image.camera;
|
||||||
// ✅ 转换为 cv::Point3d 进行计算
|
|
||||||
cv::Point3d fc_d(faceCenter.x, faceCenter.y, faceCenter.z);
|
// 转换为 double 进行计算
|
||||||
cv::Point3d camC = cam.C;
|
cv::Point3d P(faceCenter.x, faceCenter.y, faceCenter.z);
|
||||||
|
cv::Point3d C = cam.C;
|
||||||
|
cv::Point3d normal_d(faceNormal.x, faceNormal.y, faceNormal.z);
|
||||||
|
|
||||||
|
// 计算距离
|
||||||
|
double dist = cv::norm(P - C);
|
||||||
|
if (dist < 1e-6) return 0.0f;
|
||||||
|
|
||||||
// 计算视线方向
|
// 计算视线方向
|
||||||
cv::Point3d viewDir_d = camC - fc_d;
|
cv::Point3d viewDir = (C - P) / dist;
|
||||||
double norm = cv::norm(viewDir_d);
|
|
||||||
if (norm > 1e-6) {
|
|
||||||
viewDir_d /= norm; // 手动归一化
|
|
||||||
}
|
|
||||||
|
|
||||||
// 转回 Point3f(如果需要)
|
// 计算夹角余弦(绝对值)
|
||||||
Point3f viewDir(
|
double cosTheta = std::abs(normal_d.dot(viewDir));
|
||||||
static_cast<float>(viewDir_d.x),
|
if (cosTheta < 1e-6) cosTheta = 1e-6;
|
||||||
static_cast<float>(viewDir_d.y),
|
|
||||||
static_cast<float>(viewDir_d.z)
|
|
||||||
);
|
|
||||||
|
|
||||||
// 计算面片在图像平面上的投影面积
|
// 焦距(像素)- 这是关键修正!
|
||||||
// 使用一个近似的正方形面片模型
|
double focal_px = cam.GetFocalLength();
|
||||||
float dist = (float)cv::norm(faceCenter - (Point3f)cam.C);
|
|
||||||
if (dist < 1e-6f) return 0.0f;
|
|
||||||
|
|
||||||
// 估算面片在图像平面上的大小(像素)
|
// 获取面片真实面积(如果可用)
|
||||||
// 假设面片是边长为1米的正方形(实际应根据面片真实面积调整)
|
float faceArea = 1.0f; // 默认值
|
||||||
float approxFaceSize = 1.0f; // 米
|
|
||||||
|
|
||||||
// 计算像素大小:focal_length * (object_size / distance)
|
// 如果有面片面积数据,应该使用真实面积
|
||||||
float pixelSize = cam.GetFocalLength() * (approxFaceSize / dist);
|
// 例如:faceArea = scene.mesh.faceAreas[faceID];
|
||||||
|
|
||||||
|
// 投影面积(像素²)
|
||||||
|
// 公式:A_pixel = A_world * (f/Z)² * |cosθ|
|
||||||
|
double areaPixel = faceArea * (focal_px * focal_px) / (dist * dist) * cosTheta;
|
||||||
|
|
||||||
|
// 返回等效边长(像素)
|
||||||
|
float pixelSize = static_cast<float>(std::sqrt(areaPixel));
|
||||||
|
|
||||||
|
// 调试输出(可选)
|
||||||
|
// DEBUG_EXTRA("PixelSize: %.2f px (dist=%.2f, cosθ=%.2f, focal=%.2f)",
|
||||||
|
// pixelSize, dist, cosTheta, focal_px);
|
||||||
|
|
||||||
// 转换为像素单位(考虑传感器尺寸和图像分辨率)
|
|
||||||
// 这里假设相机内参已经考虑了这些因素
|
|
||||||
return pixelSize;
|
return pixelSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 综合评分函数(完全修正版)
|
// 综合评分函数(完全修正版)
|
||||||
float MeshTexture::ComputeComprehensiveScore(const FaceData& data, const Normal& faceNormal,
|
float MeshTexture::ComputeComprehensiveScore(const FaceData& data, const Normal& faceNormal,
|
||||||
const Point3f& faceCenter, const Image& image) {
|
const Point3f& faceCenter, const Image& image) {
|
||||||
// ✅ 全部使用 OpenCV 的 double 类型进行计算
|
// 基础质量 - 确保不为负
|
||||||
|
float score = std::max(0.01f, data.quality);
|
||||||
|
|
||||||
|
// ---------- 正对程度(大幅放宽)----------
|
||||||
cv::Point3d fc_d(faceCenter.x, faceCenter.y, faceCenter.z);
|
cv::Point3d fc_d(faceCenter.x, faceCenter.y, faceCenter.z);
|
||||||
cv::Point3d camC = image.camera.C;
|
cv::Point3d camC = image.camera.C;
|
||||||
|
cv::Point3d normal_d(faceNormal.x, faceNormal.y, faceNormal.z);
|
||||||
|
|
||||||
// ---------- 正对程度(最重要)----------
|
// 计算视线方向
|
||||||
// 计算视线方向(从面片指向相机)
|
|
||||||
cv::Point3d viewDir = camC - fc_d;
|
cv::Point3d viewDir = camC - fc_d;
|
||||||
double viewDirLen = cv::norm(viewDir);
|
double viewDirLen = cv::norm(viewDir);
|
||||||
if (viewDirLen > 1e-6) {
|
if (viewDirLen > 1e-6) {
|
||||||
viewDir /= viewDirLen;
|
viewDir /= viewDirLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 法线转 double
|
|
||||||
cv::Point3d normal_d(faceNormal.x, faceNormal.y, faceNormal.z);
|
|
||||||
|
|
||||||
// 计算正面度
|
// 计算正面度
|
||||||
double dot = normal_d.dot(viewDir);
|
double dot = normal_d.dot(viewDir);
|
||||||
float frontalness = static_cast<float>((dot + 1.0) * 0.5);
|
float frontalness = static_cast<float>((dot + 1.0) * 0.5);
|
||||||
|
|
||||||
// 基础质量
|
// ✅ 大幅放宽:使用线性而不是平方,减少惩罚
|
||||||
float score = data.quality;
|
score *= (0.3f + 0.7f * frontalness); // 原来是平方
|
||||||
score *= frontalness * frontalness; // 平方增强正面偏好
|
|
||||||
|
|
||||||
// ---------- 距离因子 ----------
|
// ---------- 距离因子(大幅放宽)----------
|
||||||
double dist = cv::norm(fc_d - camC);
|
double dist = cv::norm(fc_d - camC);
|
||||||
double focal = image.camera.GetFocalLength();
|
double focal = image.camera.GetFocalLength();
|
||||||
|
|
||||||
// ✅ 使用 RC 风格的高斯衰减(比线性衰减更好)
|
// ✅ 放宽:使用更小的惩罚系数
|
||||||
double idealDist = 8.0 * focal; // 经验值
|
double idealDist = 10.0 * focal; // 原来是8.0
|
||||||
double relDist = dist / idealDist;
|
double relDist = dist / idealDist;
|
||||||
double distScore = std::exp(-0.5 * relDist * relDist);
|
double distScore = std::exp(-0.2 * relDist * relDist); // 原来是-0.5
|
||||||
score *= static_cast<float>(distScore);
|
score *= static_cast<float>(distScore);
|
||||||
|
|
||||||
// ---------- 分辨率因子 ----------
|
// ---------- 分辨率因子(大幅放宽)----------
|
||||||
float pixelSize = EstimatePixelSize(faceCenter, faceNormal, image);
|
float pixelSize = EstimatePixelSize(faceCenter, faceNormal, image);
|
||||||
float resolutionScore = std::min(1.0f, pixelSize / 50.0f); // 至少50像素
|
float resolutionScore = std::min(1.0f, pixelSize / 20.0f); // 原来是50.0f
|
||||||
score *= resolutionScore;
|
score *= resolutionScore;
|
||||||
|
|
||||||
|
// ✅ 确保最低分数
|
||||||
|
score = std::max(0.01f, score);
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MeshTexture::TextureWithExistingUVVirtualFaces(const IIndexArr& views, int nIgnoreMaskLabel,
|
bool MeshTexture::TextureWithExistingUVVirtualFaces(const IIndexArr& views, int nIgnoreMaskLabel,
|
||||||
float fOutlierThreshold, unsigned nTextureSizeMultiple,
|
float fOutlierThreshold, unsigned nTextureSizeMultiple,
|
||||||
Pixel8U colEmpty, float fSharpnessWeight)
|
Pixel8U colEmpty, float fSharpnessWeight)
|
||||||
@@ -14387,9 +14398,18 @@ bool MeshTexture::TextureWithExistingUVVirtualFaces(const IIndexArr& views, int
|
|||||||
virtualFaceViews[idxVF] = { bestViewID };
|
virtualFaceViews[idxVF] = { bestViewID };
|
||||||
virtualFaceViewWeights[idxVF] = { 1.0f }; // 单视图权重设为1
|
virtualFaceViewWeights[idxVF] = { 1.0f }; // 单视图权重设为1
|
||||||
} else {
|
} else {
|
||||||
virtualFaceViews[idxVF].clear();
|
// virtualFaceViews[idxVF].clear();
|
||||||
virtualFaceViewWeights[idxVF].clear();
|
// virtualFaceViewWeights[idxVF].clear();
|
||||||
++unassignedFaces;
|
// ++unassignedFaces;
|
||||||
|
|
||||||
|
float bestQuality = -1.0f;
|
||||||
|
for (const FaceData& data : vfDatas) {
|
||||||
|
if (data.quality > bestQuality) {
|
||||||
|
bestQuality = data.quality;
|
||||||
|
bestViewID = data.idxView;
|
||||||
|
bestScore = data.quality;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -14449,7 +14469,7 @@ bool MeshTexture::TextureWithExistingUVVirtualFaces(const IIndexArr& views, int
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
DEBUG_EXTRA("Unassigned faces: %zu / %zu", unassignedFaces, numFaces);
|
||||||
DEBUG_EXTRA("Texture generation failed in stable mode");
|
DEBUG_EXTRA("Texture generation failed in stable mode");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user