|
|
|
|
@ -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 |
|
|
|
|
|