Browse Source

进一步优化

master
hesuicong 4 weeks ago
parent
commit
1421d21597
  1. 128
      libs/MVS/SceneTexture.cpp

128
libs/MVS/SceneTexture.cpp

@ -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) {
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 = medianQuality;
virtualFaceData.quality = 0; virtualFaceData.color = medianColor;
#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;
} }
} }
} }

Loading…
Cancel
Save