Browse Source

解决明暗色差问题

master
hesuicong 5 months ago
parent
commit
72176c2f28
  1. 205
      libs/MVS/SceneTexture.cpp

205
libs/MVS/SceneTexture.cpp

@ -140,7 +140,6 @@ struct TRWSInference {
} }
#endif #endif
// S T R U C T S /////////////////////////////////////////////////// // S T R U C T S ///////////////////////////////////////////////////
typedef Mesh::Vertex Vertex; typedef Mesh::Vertex Vertex;
@ -489,6 +488,11 @@ public:
v[0] + v1 * T(1.772) v[0] + v1 * T(1.772)
); );
} }
static inline float GetLuminance(const Color& rgb) {
Color ycbcr = MeshTexture::RGB2YCBCR(rgb);
return ycbcr[0]; // Y分量就是亮度
}
//*/ //*/
/* /*
// 采用ITU-R BT.601标准系数,增加数值稳定性处理 // 采用ITU-R BT.601标准系数,增加数值稳定性处理
@ -2771,6 +2775,7 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA
} }
std::vector<std::pair<float, Color>> sortedViews; std::vector<std::pair<float, Color>> sortedViews;
std::vector<std::pair<float, Color>> sortedLuminViews;
std::vector<std::pair<float, Color>> validViews; std::vector<std::pair<float, Color>> validViews;
sortedViews.reserve(centerFaceDatas.size()); sortedViews.reserve(centerFaceDatas.size());
for (const FaceData& fd : centerFaceDatas) { for (const FaceData& fd : centerFaceDatas) {
@ -2780,10 +2785,12 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA
// invalidView = fd.idxView; // invalidView = fd.idxView;
// invalidQuality = fd.quality; // invalidQuality = fd.quality;
sortedViews.emplace_back(fd.quality, fd.color); sortedViews.emplace_back(fd.quality, fd.color);
sortedLuminViews.emplace_back(MeshTexture::GetLuminance(fd.color), fd.color);
} }
else else
{ {
sortedViews.emplace_back(fd.quality, fd.color); sortedViews.emplace_back(fd.quality, fd.color);
sortedLuminViews.emplace_back(MeshTexture::GetLuminance(fd.color), fd.color);
validViews.emplace_back(fd.quality, fd.color); validViews.emplace_back(fd.quality, fd.color);
} }
} }
@ -2792,6 +2799,26 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA
std::sort(validViews.begin(), validViews.end(), std::sort(validViews.begin(), validViews.end(),
[](const auto& a, const auto& b) { return a.first > b.first; }); [](const auto& a, const auto& b) { return a.first > b.first; });
int nSize = sortedViews.size();
// 计算初始平均值
float totalQuality = 0.0f;
Color totalColor(0,0,0);
for (int n = 0; n < nSize; ++n) {
totalQuality += sortedViews[n].first;
totalColor += sortedViews[n].second;
}
const float avgQuality = totalQuality / nSize;
const Color avgColor = totalColor / nSize;
float totalLuminance = MeshTexture::GetLuminance(totalColor);
float avgLuminance = totalLuminance / nSize;
std::sort(sortedLuminViews.begin(), sortedLuminViews.end(),
[avgLuminance](const auto& a, const auto& b) {
float luminDistA = cv::norm(avgLuminance - a.first);
float luminDistB = cv::norm(avgLuminance - b.first);
return luminDistA < luminDistB; });
// select the common cameras // select the common cameras
Mesh::FaceIdxArr virtualFace; Mesh::FaceIdxArr virtualFace;
FaceDataArr virtualFaceDatas; FaceDataArr virtualFaceDatas;
@ -2915,7 +2942,7 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA
// if (faceData.bInvalidFacesRelative) // if (faceData.bInvalidFacesRelative)
if (bHasInvalidView) if (bHasInvalidView)
{ {
++processedFaces; // ++processedFaces;
} }
else else
{ {
@ -2931,24 +2958,107 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA
} }
} }
float maxLuminance = 150.0f;
float minLuminance = 20.0f;
if (bHasInvalidView) if (bHasInvalidView)
{ {
if (validViews.size()<=0) if (validViews.size()<=0)
{ {
int nSize = (sortedViews.size()>1) ? 1 : sortedViews.size(); //*
for (int n=0; n<nSize; ++n) // int nSize = sortedViews.size(); // (sortedViews.size() > 3) ? 3 : sortedViews.size();
// // 计算初始平均值
// float totalQuality = 0.0f;
// Color totalColor(0,0,0);
// for (int n = 0; n < nSize; ++n) {
// totalQuality += sortedViews[n].first;
// totalColor += sortedViews[n].second;
// }
// const float avgQuality = totalQuality / nSize;
// const Color avgColor = totalColor / nSize;
// 过滤偏差过大的视图
std::vector<int> validIndices;
float maxColorDeviation = 0.01f; // 颜色偏差阈值
float maxLuminanceDeviation = 0.01f;
for (int n = 0; n < nSize; ++n) {
const Color& viewColor = sortedViews[n].second;
float colorDistance = cv::norm(avgColor - viewColor);
// printf("colorDistance=%f\n", colorDistance);
float viewLuminance = MeshTexture::GetLuminance(viewColor);
float luminanceDistance = cv::norm(avgLuminance - viewLuminance);
// printf("viewLuminance=%f\n", viewLuminance);
if ((colorDistance<=maxColorDeviation)&&
(viewLuminance<=maxLuminance)&&
(viewLuminance>=minLuminance)){
// if ((colorDistance <= maxColorDeviation) &&
// (luminanceDistance <= maxLuminanceDeviation)) {
validIndices.push_back(n);
}
}
if (validIndices.empty()) {
for (int n = 0; n < nSize; ++n) {
const Color& viewColor = sortedViews[n].second;
float colorDistance = cv::norm(avgColor - viewColor);
if (colorDistance <= maxColorDeviation) {
validIndices.push_back(n);
}
}
}
float totalLuminance = MeshTexture::GetLuminance(totalColor);
float avgLuminance = totalLuminance / nSize;
for (int n = 0; n < nSize; ++n) {
const Color& viewColor = sortedViews[n].second;
float viewLuminance = MeshTexture::GetLuminance(viewColor);
float luminanceDistance = cv::norm(avgLuminance - viewLuminance);
// printf("luminanceDistance=%f\n", luminanceDistance);
if (luminanceDistance <= maxLuminanceDeviation) {
// validIndices.push_back(n);
}
}
// 如果所有视图都被排除,保留原始平均值
if (validIndices.empty()) {
// virtualFaceData.quality = avgQuality;
// virtualFaceData.color = avgColor;
// virtualFaceData.quality = avgQuality;
// virtualFaceData.color = sortedLuminViews[0].second;
for (int n = 0; n < nSize; ++n) {
float lumin = sortedLuminViews[n].first;
if (lumin>=minLuminance&&lumin<=maxLuminance)
{ {
virtualFaceData.quality += sortedViews[n].first; // virtualFaceData.quality = avgQuality;
virtualFaceData.color += sortedViews[n].second; // virtualFaceData.color = sortedLuminViews[0].second;
break;
} }
virtualFaceData.quality /= nSize; }
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA }
virtualFaceData.color /= nSize; else {
#endif // 使用过滤后的视图重新计算平均值
totalQuality = 0.0f;
totalColor = Color(0,0,0);
for (int idx : validIndices) {
totalQuality += sortedViews[idx].first;
totalColor += sortedViews[idx].second;
}
virtualFaceData.quality = totalQuality / validIndices.size();
virtualFaceData.color = totalColor / validIndices.size();
}
//*/
} }
else else
{ {
int nSize = (validViews.size()>1) ? 1 : validViews.size(); /*
// int nSize = (validViews.size()>1) ? 1 : validViews.size();
int nSize = validViews.size();
for (int n=0; n<nSize; ++n) for (int n=0; n<nSize; ++n)
{ {
virtualFaceData.quality += validViews[n].first; virtualFaceData.quality += validViews[n].first;
@ -2958,6 +3068,79 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA #if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
virtualFaceData.color /= nSize; virtualFaceData.color /= nSize;
#endif #endif
*/
//*
int nSize = validViews.size(); // (validViews.size() > 3) ? 3 : validViews.size();
// 计算初始平均值
float totalQuality = 0.0f;
Color totalColor(0,0,0);
for (int n = 0; n < nSize; ++n) {
totalQuality += validViews[n].first;
totalColor += validViews[n].second;
}
const float avgQuality = totalQuality / nSize;
const Color avgColor = totalColor / nSize;
// 过滤偏差过大的视图
std::vector<int> validIndices;
float maxColorDeviation = 0.5f; // 颜色偏差阈值
for (int n = 0; n < nSize; ++n) {
const Color& viewColor = validViews[n].second;
float colorDistance = cv::norm(avgColor - viewColor);
// printf("colorDistance=%f\n", colorDistance);
float viewLuminance = MeshTexture::GetLuminance(viewColor);
// if ((colorDistance<=maxColorDeviation)&&
// (viewLuminance<=maxLuminance)&&
// (viewLuminance>=minLuminance)){
if (colorDistance <= maxColorDeviation) {
validIndices.push_back(n);
}
}
// float totalLuminance = MeshTexture::GetLuminance(totalColor);
// float avgLuminance = totalLuminance / nSize;
float maxLuminanceDeviation = 0.01f;
for (int n = 0; n < nSize; ++n) {
const Color& viewColor = sortedViews[n].second;
float viewLuminance = MeshTexture::GetLuminance(viewColor);
float luminanceDistance = cv::norm(avgLuminance - viewLuminance);
// printf("luminanceDistance=%f\n", luminanceDistance);
if (luminanceDistance <= maxLuminanceDeviation) {
// validIndices.push_back(n);
}
}
// 如果所有视图都被排除,保留原始平均值
if (validIndices.empty()) {
// virtualFaceData.quality = avgQuality;
// virtualFaceData.color = avgColor;
// virtualFaceData.quality = avgQuality;
// virtualFaceData.color = sortedLuminViews[0].second;
for (int n = 0; n < nSize; ++n) {
float lumin = sortedLuminViews[n].first;
if (lumin>=minLuminance&&lumin<=maxLuminance)
{
// virtualFaceData.quality = avgQuality;
// virtualFaceData.color = sortedLuminViews[0].second;
break;
}
}
}
else {
// 使用过滤后的视图重新计算平均值
totalQuality = 0.0f;
totalColor = Color(0,0,0);
for (int idx : validIndices) {
totalQuality += validViews[idx].first;
totalColor += validViews[idx].second;
}
virtualFaceData.quality = totalQuality / validIndices.size();
virtualFaceData.color = totalColor / validIndices.size();
}
//*/
} }
} }
else else

Loading…
Cancel
Save