Browse Source

染色处理

master
hesuicong 2 weeks ago
parent
commit
f123063221
  1. 212
      libs/MVS/SceneTexture.cpp

212
libs/MVS/SceneTexture.cpp

@ -4360,7 +4360,6 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView @@ -4360,7 +4360,6 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView
if (angleDeg <= 45.0f)
{
// filteredCams.push_back(idxView);
//*
float brightnessScore = CalculateBrightnessScore(imageData); // 亮度评分函数
float angleScore = 1.0f - (angleDeg / 45.0f);
@ -4374,9 +4373,7 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView @@ -4374,9 +4373,7 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView
}
qualityScore = std::max(0.0f, std::min(1.0f, qualityScore));
float overallScore = 0.5f * angleScore + 0.3f * brightnessScore + 0.2f * qualityScore;
if (overallScore > 0.04f) {
filteredCams.push_back(idxView);
}
//*/
@ -4400,9 +4397,7 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView @@ -4400,9 +4397,7 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView
}
qualityScore = std::max(0.0f, std::min(1.0f, qualityScore));
float overallScore = 0.5f * angleScore + 0.3f * brightnessScore + 0.2f * qualityScore;
if (overallScore > 0.02f) {
filteredCams.push_back(idxView);
}
//*/
@ -4478,6 +4473,7 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView @@ -4478,6 +4473,7 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView
}
} while (!currentVirtualFaceQueue.IsEmpty());
// compute virtual face quality and create virtual face
for (IIndex idxView: selectedCams) {
FaceData& virtualFaceData = virtualFaceDatas.emplace_back();
virtualFaceData.quality = 0;
@ -4485,30 +4481,218 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView @@ -4485,30 +4481,218 @@ bool MeshTexture::CreateVirtualFaces62(FaceDataViewArr& facesDatas, FaceDataView
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
virtualFaceData.color = Point3f::ZERO;
#endif
int invalidQuality = 0;
Color invalidColor = Point3f::ZERO;
unsigned processedFaces(0);
bool bInvalidFacesRelative = false;
int invalidCount = 0;
for (FIndex fid : virtualFace) {
const FaceDataArr& faceDatas = facesDatas[fid];
for (FaceData& faceData: faceDatas) {
if (faceData.idxView == idxView) {
virtualFaceData.quality += faceData.quality;
int nViewCount = 0;
if (faceData.idxView == idxView)
{
for (const FaceData& fd : faceDatas)
{
if ( faceData.bInvalidFacesRelative)
{
++nViewCount;
}
}
// if (faceData.bInvalidFacesRelative)
if (bHasInvalidView)
{
// invalidQuality += faceData.quality;
// #if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
// invalidColor += faceData.color;
// #endif
++processedFaces;
}
else
{
// virtualFaceData.quality += faceData.quality;
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
virtualFaceData.color += faceData.color;
// virtualFaceData.color += faceData.color;
#endif
++processedFaces;
if (faceData.bInvalidFacesRelative)
++invalidCount;
break;
// break;
}
}
}
}
float maxLuminance = 120.0f;
float minLuminance = 90.0f;
int validViewsSize = validViews.size();
// bHasInvalidView = true;
if (bHasInvalidView)
{
// 使用鲁棒的统计方法计算颜色和亮度的中心值
const Color medianColor = ComputeMedianColorAndQuality(sortedViews).color;
const float medianQuality = ComputeMedianColorAndQuality(sortedViews).quality;
const float medianLuminance = ComputeMedianLuminance(sortedViews);
// 计算颜色和亮度的绝对中位差(MAD)作为偏差阈值
const float colorMAD = ComputeColorMAD(sortedViews, medianColor);
const float luminanceMAD = ComputeLuminanceMAD(sortedViews, medianLuminance);
// 基于MAD设置动态阈值(3倍MAD是统计学上常用的异常值阈值)
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)
{
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;
// Check color similarity
const Color& centerColor = faceColors[virtualFaceCenterFaceID];
const Color& currentColor = faceColors[currentFaceId];
float colorDistance = cv::norm(centerColor - currentColor);
// printf("1colorDistance=%f\n", colorDistance);
if (colorDistance > thMaxColorDeviation) {
// printf("2colorDistance=%f\n", colorDistance);
bColorSimilarity = false;
}
// if ((cosFaceToCenter<dynamicCosTh) || !IsFaceVisible(facesDatas[currentFaceId], selectedCams))
if (cosFaceToCenter<dynamicCosTh)
{
if (nInvalidViewCount<=2)
validIndices.push_back(n);
else
{
// if ((colorDistance <= 350.0f))
validIndices.push_back(n);
}
}
else
{
if (nInvalidViewCount<=2)
validIndices.push_back(n);
else
{
// if (bColorSimilarity)
validIndices.push_back(n);
}
}
}
}
if (validIndices.empty()) {
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)
{
// validIndices.push_back(n);
}
}
}
if (validIndices.empty()) {
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 (luminanceDistance <= maxLuminanceDeviation)
{
// validIndices.push_back(n);
}
}
}
{
ASSERT(processedFaces > 0);
virtualFaceData.quality /= processedFaces;
// virtualFaceData.quality /= processedFaces;
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
virtualFaceData.color /= processedFaces;
// virtualFaceData.color /= processedFaces;
#endif
virtualFaceData.bInvalidFacesRelative = (invalidCount > processedFaces / 2);
virtualFaceData.quality = 0;
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
virtualFaceData.color = Point3f::ZERO;
#endif
}
}
else
{
// 使用鲁棒的统计方法计算颜色和亮度的中心值
const Color medianColor = ComputeMedianColorAndQuality(sortedViews).color;
const float medianQuality = ComputeMedianColorAndQuality(sortedViews).quality;
const float medianLuminance = ComputeMedianLuminance(sortedViews);
// 计算颜色和亮度的绝对中位差(MAD)作为偏差阈值
const float colorMAD = ComputeColorMAD(sortedViews, medianColor);
const float luminanceMAD = ComputeLuminanceMAD(sortedViews, medianLuminance);
// 基于MAD设置动态阈值(3倍MAD是统计学上常用的异常值阈值)
const float maxColorDeviation = 0.01f * colorMAD;
// const float maxLuminanceDeviation = 0.01f * luminanceMAD;
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);
// if (colorDistance <= maxColorDeviation &&
// luminanceDistance <= maxLuminanceDeviation)
// if (luminanceDistance <= maxLuminanceDeviation)
{
validIndices.push_back(n);
}
}
if (validIndices.empty()) {
virtualFaceData.quality = medianQuality;
virtualFaceData.color = medianColor;
}
else {
// 使用过滤后的视图重新计算平均值
float totalQuality2 = 0.0f;
Color totalColor2 = Color(0,0,0);
for (int idx : validIndices) {
totalQuality2 += validViews[idx].first;
totalColor2 += validViews[idx].second;
}
virtualFaceData.quality = totalQuality2 / validIndices.size();
virtualFaceData.color = totalColor2 / validIndices.size();
}
}
// virtualFaceData.bInvalidFacesRelative = (invalidCount > 1);
// virtualFaceData.bInvalidFacesRelative = (invalidCount > processedFaces * 2 / 3);
}
ASSERT(!virtualFaceDatas.empty());
}

Loading…
Cancel
Save