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 { @@ -140,7 +140,6 @@ struct TRWSInference {
}
#endif
// S T R U C T S ///////////////////////////////////////////////////
typedef Mesh::Vertex Vertex;
@ -489,6 +488,11 @@ public: @@ -489,6 +488,11 @@ public:
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标准系数,增加数值稳定性处理
@ -2771,6 +2775,7 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA @@ -2771,6 +2775,7 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA
}
std::vector<std::pair<float, Color>> sortedViews;
std::vector<std::pair<float, Color>> sortedLuminViews;
std::vector<std::pair<float, Color>> validViews;
sortedViews.reserve(centerFaceDatas.size());
for (const FaceData& fd : centerFaceDatas) {
@ -2780,10 +2785,12 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA @@ -2780,10 +2785,12 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA
// invalidView = fd.idxView;
// invalidQuality = fd.quality;
sortedViews.emplace_back(fd.quality, fd.color);
sortedLuminViews.emplace_back(MeshTexture::GetLuminance(fd.color), fd.color);
}
else
{
sortedViews.emplace_back(fd.quality, fd.color);
sortedLuminViews.emplace_back(MeshTexture::GetLuminance(fd.color), fd.color);
validViews.emplace_back(fd.quality, fd.color);
}
}
@ -2792,6 +2799,26 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA @@ -2792,6 +2799,26 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA
std::sort(validViews.begin(), validViews.end(),
[](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
Mesh::FaceIdxArr virtualFace;
FaceDataArr virtualFaceDatas;
@ -2915,7 +2942,7 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA @@ -2915,7 +2942,7 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA
// if (faceData.bInvalidFacesRelative)
if (bHasInvalidView)
{
++processedFaces;
// ++processedFaces;
}
else
{
@ -2931,24 +2958,107 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA @@ -2931,24 +2958,107 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA
}
}
float maxLuminance = 150.0f;
float minLuminance = 20.0f;
if (bHasInvalidView)
{
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.color += sortedViews[n].second;
// virtualFaceData.quality = avgQuality;
// virtualFaceData.color = sortedLuminViews[0].second;
break;
}
virtualFaceData.quality /= nSize;
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
virtualFaceData.color /= nSize;
#endif
}
}
else {
// 使用过滤后的视图重新计算平均值
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
{
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)
{
virtualFaceData.quality += validViews[n].first;
@ -2958,6 +3068,79 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA @@ -2958,6 +3068,79 @@ void MeshTexture::CreateVirtualFaces6(FaceDataViewArr& facesDatas, FaceDataViewA
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
virtualFaceData.color /= nSize;
#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

Loading…
Cancel
Save