进一步优化
This commit is contained in:
1 parent
3693365bdf
commit
1421d21597
1 file changed
+29
-97
+29
-97
@@ -4345,7 +4345,7 @@ bool MeshTexture::CreateVirtualFaces63(FaceDataViewArr& facesDatas, FaceDataView
|
|||||||
|
|
||||||
// 动态法线阈值
|
// 动态法线阈值
|
||||||
const float centerCurvature = meshCurvatures[virtualFaceCenterFaceID];
|
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));
|
const float dynamicCosTh = COS(FD2R(dynamicThreshold));
|
||||||
|
|
||||||
ASSERT(currentVirtualFaceQueue.IsEmpty());
|
ASSERT(currentVirtualFaceQueue.IsEmpty());
|
||||||
@@ -4468,32 +4468,20 @@ bool MeshTexture::CreateVirtualFaces63(FaceDataViewArr& facesDatas, FaceDataView
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 按angleDeg从小到大排序
|
// 按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) {
|
[](const std::pair<IIndex, float>& a, const std::pair<IIndex, float>& b) {
|
||||||
return a.second < b.second;
|
return a.second < b.second;
|
||||||
});
|
});
|
||||||
|
|
||||||
IIndexArr filteredCams;
|
IIndexArr filteredCams;
|
||||||
|
size_t count = std::min(sortedCams.size(), static_cast<size_t>(3));
|
||||||
// 核心优化:根据中心面片质量决定选择多少张视图
|
for (size_t i = 0; i < count; ++i) {
|
||||||
if (centerFaceQuality >= QUALITY_THRESHOLD) {
|
filteredCams.push_back(sortedCams[i].first);
|
||||||
// 质量高于阈值,尽量使用同一张视图(角度最小的)
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filteredCams.empty()) {
|
if (filteredCams.empty()) {
|
||||||
|
// 处理空情况
|
||||||
selectedCams = filteredCams;
|
selectedCams = filteredCams;
|
||||||
isVirtualFace[virtualFaceCenterFaceID] = false;
|
isVirtualFace[virtualFaceCenterFaceID] = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -4516,15 +4504,18 @@ bool MeshTexture::CreateVirtualFaces63(FaceDataViewArr& facesDatas, FaceDataView
|
|||||||
if (!IsFaceVisible(facesDatas[currentFaceId], selectedCams))
|
if (!IsFaceVisible(facesDatas[currentFaceId], selectedCams))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// 修改3:调整颜色差异检查
|
||||||
const Color& centerColor = faceColors[virtualFaceCenterFaceID];
|
const Color& centerColor = faceColors[virtualFaceCenterFaceID];
|
||||||
const Color& currentColor = faceColors[currentFaceId];
|
const Color& currentColor = faceColors[currentFaceId];
|
||||||
float colorDistance = cv::norm(centerColor - currentColor);
|
float colorDistance = cv::norm(centerColor - currentColor);
|
||||||
if (colorDistance > 200.0f) {
|
|
||||||
// continue; // 可选:如果颜色差异太大,跳过
|
// 放宽颜色差异条件
|
||||||
|
if (colorDistance > 250.0f) { // 增加阈值
|
||||||
|
// 不跳过,继续处理
|
||||||
}
|
}
|
||||||
|
|
||||||
if (colorDistance > thMaxColorDeviation) {
|
if (colorDistance > thMaxColorDeviation) {
|
||||||
// continue; // 可选:如果颜色差异太大,跳过
|
// 保持原有逻辑
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -4550,6 +4541,7 @@ bool MeshTexture::CreateVirtualFaces63(FaceDataViewArr& facesDatas, FaceDataView
|
|||||||
// 计算虚拟面质量并创建虚拟面
|
// 计算虚拟面质量并创建虚拟面
|
||||||
for (IIndex idxView: selectedCams) {
|
for (IIndex idxView: selectedCams) {
|
||||||
FaceData& virtualFaceData = virtualFaceDatas.emplace_back();
|
FaceData& virtualFaceData = virtualFaceDatas.emplace_back();
|
||||||
|
|
||||||
virtualFaceData.quality = 0;
|
virtualFaceData.quality = 0;
|
||||||
virtualFaceData.idxView = idxView;
|
virtualFaceData.idxView = idxView;
|
||||||
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
|
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
|
||||||
@@ -4587,88 +4579,28 @@ bool MeshTexture::CreateVirtualFaces63(FaceDataViewArr& facesDatas, FaceDataView
|
|||||||
|
|
||||||
int validViewsSize = validViews.size();
|
int validViewsSize = validViews.size();
|
||||||
if (bHasInvalidView) {
|
if (bHasInvalidView) {
|
||||||
|
// 使用简化逻辑
|
||||||
const Color medianColor = ComputeMedianColorAndQuality(sortedViews).color;
|
const Color medianColor = ComputeMedianColorAndQuality(sortedViews).color;
|
||||||
const float medianQuality = ComputeMedianColorAndQuality(sortedViews).quality;
|
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) {
|
virtualFaceData.quality = medianQuality;
|
||||||
const Color& viewColor = sortedViews[n].second;
|
virtualFaceData.color = medianColor;
|
||||||
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
|
|
||||||
} else {
|
} else {
|
||||||
const Color medianColor = ComputeMedianColorAndQuality(sortedViews).color;
|
// 使用有效视图计算
|
||||||
const float medianQuality = ComputeMedianColorAndQuality(sortedViews).quality;
|
if (!validViews.empty()) {
|
||||||
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 {
|
|
||||||
float totalQuality2 = 0.0f;
|
float totalQuality2 = 0.0f;
|
||||||
Color totalColor2 = Color(0,0,0);
|
Color totalColor2 = Color(0,0,0);
|
||||||
for (int idx : validIndices) {
|
for (const auto& v : validViews) {
|
||||||
totalQuality2 += validViews[idx].first;
|
totalQuality2 += v.first;
|
||||||
totalColor2 += validViews[idx].second;
|
totalColor2 += v.second;
|
||||||
}
|
}
|
||||||
virtualFaceData.quality = totalQuality2 / validIndices.size();
|
virtualFaceData.quality = totalQuality2 / validViews.size();
|
||||||
virtualFaceData.color = totalColor2 / validIndices.size();
|
virtualFaceData.color = totalColor2 / validViews.size();
|
||||||
|
} else {
|
||||||
|
// 回退到平均值
|
||||||
|
virtualFaceData.quality = avgQuality;
|
||||||
|
virtualFaceData.color = avgColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user