进一步优化
This commit is contained in:
1 parent
3693365bdf
commit
1421d21597
1 file changed
+30
-98
+30
-98
@@ -4345,7 +4345,7 @@ bool MeshTexture::CreateVirtualFaces63(FaceDataViewArr& facesDatas, FaceDataView
|
||||
|
||||
// 动态法线阈值
|
||||
const float centerCurvature = meshCurvatures[virtualFaceCenterFaceID];
|
||||
const float dynamicThreshold = (centerCurvature < 0.2f) ? 15.0f : 8.0f;
|
||||
const float dynamicThreshold = (centerCurvature < 0.2f) ? 18.0f : 10.0f; // 放宽角度阈值
|
||||
const float dynamicCosTh = COS(FD2R(dynamicThreshold));
|
||||
|
||||
ASSERT(currentVirtualFaceQueue.IsEmpty());
|
||||
@@ -4468,32 +4468,20 @@ bool MeshTexture::CreateVirtualFaces63(FaceDataViewArr& facesDatas, FaceDataView
|
||||
}
|
||||
|
||||
// 按angleDeg从小到大排序
|
||||
std::sort(cameraAngles.begin(), cameraAngles.end(),
|
||||
std::vector<std::pair<IIndex, float>> sortedCams = cameraAngles;
|
||||
std::sort(sortedCams.begin(), sortedCams.end(),
|
||||
[](const std::pair<IIndex, float>& a, const std::pair<IIndex, float>& b) {
|
||||
return a.second < b.second;
|
||||
});
|
||||
|
||||
IIndexArr filteredCams;
|
||||
|
||||
// 核心优化:根据中心面片质量决定选择多少张视图
|
||||
if (centerFaceQuality >= QUALITY_THRESHOLD) {
|
||||
// 质量高于阈值,尽量使用同一张视图(角度最小的)
|
||||
if (!cameraAngles.empty()) {
|
||||
// 只选择角度最小的一张视图
|
||||
filteredCams.push_back(cameraAngles[0].first);
|
||||
} else if (!selectedCams.empty()) {
|
||||
// 如果没有符合条件的相机,回退到原始选择中的第一个
|
||||
filteredCams.push_back(selectedCams[0]);
|
||||
}
|
||||
} else {
|
||||
// 质量低于阈值,可以选择多张视图
|
||||
size_t count = std::min(cameraAngles.size(), static_cast<size_t>(3));
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
filteredCams.push_back(cameraAngles[i].first);
|
||||
}
|
||||
size_t count = std::min(sortedCams.size(), static_cast<size_t>(3));
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
filteredCams.push_back(sortedCams[i].first);
|
||||
}
|
||||
|
||||
if (filteredCams.empty()) {
|
||||
// 处理空情况
|
||||
selectedCams = filteredCams;
|
||||
isVirtualFace[virtualFaceCenterFaceID] = false;
|
||||
} else {
|
||||
@@ -4516,15 +4504,18 @@ bool MeshTexture::CreateVirtualFaces63(FaceDataViewArr& facesDatas, FaceDataView
|
||||
if (!IsFaceVisible(facesDatas[currentFaceId], selectedCams))
|
||||
continue;
|
||||
|
||||
// 修改3:调整颜色差异检查
|
||||
const Color& centerColor = faceColors[virtualFaceCenterFaceID];
|
||||
const Color& currentColor = faceColors[currentFaceId];
|
||||
float colorDistance = cv::norm(centerColor - currentColor);
|
||||
if (colorDistance > 200.0f) {
|
||||
// continue; // 可选:如果颜色差异太大,跳过
|
||||
|
||||
// 放宽颜色差异条件
|
||||
if (colorDistance > 250.0f) { // 增加阈值
|
||||
// 不跳过,继续处理
|
||||
}
|
||||
|
||||
|
||||
if (colorDistance > thMaxColorDeviation) {
|
||||
// continue; // 可选:如果颜色差异太大,跳过
|
||||
// 保持原有逻辑
|
||||
}
|
||||
|
||||
{
|
||||
@@ -4550,6 +4541,7 @@ bool MeshTexture::CreateVirtualFaces63(FaceDataViewArr& facesDatas, FaceDataView
|
||||
// 计算虚拟面质量并创建虚拟面
|
||||
for (IIndex idxView: selectedCams) {
|
||||
FaceData& virtualFaceData = virtualFaceDatas.emplace_back();
|
||||
|
||||
virtualFaceData.quality = 0;
|
||||
virtualFaceData.idxView = idxView;
|
||||
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
|
||||
@@ -4587,88 +4579,28 @@ bool MeshTexture::CreateVirtualFaces63(FaceDataViewArr& facesDatas, FaceDataView
|
||||
|
||||
int validViewsSize = validViews.size();
|
||||
if (bHasInvalidView) {
|
||||
// 使用简化逻辑
|
||||
const Color medianColor = ComputeMedianColorAndQuality(sortedViews).color;
|
||||
const float medianQuality = ComputeMedianColorAndQuality(sortedViews).quality;
|
||||
const float medianLuminance = ComputeMedianLuminance(sortedViews);
|
||||
const float colorMAD = ComputeColorMAD(sortedViews, medianColor);
|
||||
const float luminanceMAD = ComputeLuminanceMAD(sortedViews, medianLuminance);
|
||||
const float maxColorDeviation = 0.01f * colorMAD;
|
||||
const float maxLuminanceDeviation = 0.01f * luminanceMAD;
|
||||
|
||||
std::vector<int> validIndices;
|
||||
for (int n = 0; n < sortedViews.size(); ++n) {
|
||||
const Color& viewColor = sortedViews[n].second;
|
||||
const float viewLuminance = MeshTexture::GetLuminance(viewColor);
|
||||
const float colorDistance = cv::norm(viewColor - medianColor);
|
||||
const float luminanceDistance = std::abs(viewLuminance - medianLuminance);
|
||||
|
||||
if (colorDistance <= maxColorDeviation && luminanceDistance <= maxLuminanceDeviation) {
|
||||
if (scene.is_face_normal_visible_map(strName, virtualFaceCenterFaceID))
|
||||
validIndices.push_back(n);
|
||||
} else {
|
||||
const FIndex currentFaceId = currentVirtualFaceQueue.GetHead();
|
||||
const Normal& faceNormal = scene.mesh.faceNormals[currentFaceId];
|
||||
const float cosFaceToCenter(ComputeAngleN(normalCenter.ptr(), faceNormal.ptr()));
|
||||
bool bColorSimilarity = true;
|
||||
const Color& centerColor = faceColors[virtualFaceCenterFaceID];
|
||||
const Color& currentColor = faceColors[currentFaceId];
|
||||
float colorDistance2 = cv::norm(centerColor - currentColor);
|
||||
if (colorDistance2 > thMaxColorDeviation) {
|
||||
bColorSimilarity = false;
|
||||
}
|
||||
|
||||
if (cosFaceToCenter<dynamicCosTh) {
|
||||
if (nInvalidViewCount<=2) {
|
||||
validIndices.push_back(n);
|
||||
} else {
|
||||
validIndices.push_back(n);
|
||||
}
|
||||
} else {
|
||||
if (nInvalidViewCount<=2) {
|
||||
validIndices.push_back(n);
|
||||
} else {
|
||||
validIndices.push_back(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 计算虚拟面数据
|
||||
ASSERT(processedFaces > 0);
|
||||
virtualFaceData.quality = 0;
|
||||
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
|
||||
virtualFaceData.color = Point3f::ZERO;
|
||||
#endif
|
||||
// 直接使用中位数计算
|
||||
virtualFaceData.quality = medianQuality;
|
||||
virtualFaceData.color = medianColor;
|
||||
} else {
|
||||
const Color medianColor = ComputeMedianColorAndQuality(sortedViews).color;
|
||||
const float medianQuality = ComputeMedianColorAndQuality(sortedViews).quality;
|
||||
const float medianLuminance = ComputeMedianLuminance(sortedViews);
|
||||
const float colorMAD = ComputeColorMAD(sortedViews, medianColor);
|
||||
const float luminanceMAD = ComputeLuminanceMAD(sortedViews, medianLuminance);
|
||||
const float maxColorDeviation = 0.01f * colorMAD;
|
||||
const float maxLuminanceDeviation = 0.05f * luminanceMAD;
|
||||
|
||||
std::vector<int> validIndices;
|
||||
for (int n = 0; n < sortedViews.size(); ++n) {
|
||||
const Color& viewColor = sortedViews[n].second;
|
||||
const float viewLuminance = MeshTexture::GetLuminance(viewColor);
|
||||
const float colorDistance = cv::norm(viewColor - medianColor);
|
||||
const float luminanceDistance = std::abs(viewLuminance - medianLuminance);
|
||||
validIndices.push_back(n);
|
||||
}
|
||||
|
||||
if (validIndices.empty()) {
|
||||
virtualFaceData.quality = medianQuality;
|
||||
virtualFaceData.color = medianColor;
|
||||
} else {
|
||||
// 使用有效视图计算
|
||||
if (!validViews.empty()) {
|
||||
float totalQuality2 = 0.0f;
|
||||
Color totalColor2 = Color(0,0,0);
|
||||
for (int idx : validIndices) {
|
||||
totalQuality2 += validViews[idx].first;
|
||||
totalColor2 += validViews[idx].second;
|
||||
for (const auto& v : validViews) {
|
||||
totalQuality2 += v.first;
|
||||
totalColor2 += v.second;
|
||||
}
|
||||
virtualFaceData.quality = totalQuality2 / validIndices.size();
|
||||
virtualFaceData.color = totalColor2 / validIndices.size();
|
||||
virtualFaceData.quality = totalQuality2 / validViews.size();
|
||||
virtualFaceData.color = totalColor2 / validViews.size();
|
||||
} else {
|
||||
// 回退到平均值
|
||||
virtualFaceData.quality = avgQuality;
|
||||
virtualFaceData.color = avgColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user