解决明暗色差问题
This commit is contained in:
1 parent
18cd78f2f0
commit
72176c2f28
1 file changed
+195
-12
+195
-12
@@ -140,7 +140,6 @@ struct TRWSInference {
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// S T R U C T S ///////////////////////////////////////////////////
|
||||
|
||||
typedef Mesh::Vertex Vertex;
|
||||
@@ -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
|
||||
}
|
||||
|
||||
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
|
||||
// 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
|
||||
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
|
||||
// if (faceData.bInvalidFacesRelative)
|
||||
if (bHasInvalidView)
|
||||
{
|
||||
++processedFaces;
|
||||
// ++processedFaces;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -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)
|
||||
{
|
||||
virtualFaceData.quality += sortedViews[n].first;
|
||||
virtualFaceData.color += sortedViews[n].second;
|
||||
//*
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
virtualFaceData.quality /= nSize;
|
||||
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
|
||||
virtualFaceData.color /= nSize;
|
||||
#endif
|
||||
|
||||
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 = avgQuality;
|
||||
// virtualFaceData.color = sortedLuminViews[0].second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
#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
|
||||
|
||||
Reference in new issue
Block a user