Browse Source

处理脸色发青问题

master
hesuicong 3 days ago
parent
commit
5685a46331
  1. 223
      libs/MVS/SceneTexture.cpp
  2. 2
      libs/MVS/mask_face_occlusion.py

223
libs/MVS/SceneTexture.cpp

@ -1261,6 +1261,229 @@ bool MeshTexture::ListCameraFaces(FaceDataViewArr& facesDatas, float fOutlierThr
} }
++progress; ++progress;
} }
// Temp
/*
for (int_t idx=0; idx<(int_t)views.size(); ++idx)
{
#pragma omp flush (bAbort)
if (bAbort)
{
++progress;
continue;
}
const IIndex idxView(views[(IIndex)idx]);
Image& imageData = images[idxView];
if (!imageData.IsValid()) {
++progress;
continue;
}
std::string strPath = imageData.name;
size_t lastSlash = strPath.find_last_of("/\\");
if (lastSlash == std::string::npos) lastSlash = 0; // 若无分隔符,从头开始
else lastSlash++; // 跳过分隔符
// 查找扩展名分隔符 '.' 的位置
size_t lastDot = strPath.find_last_of('.');
if (lastDot == std::string::npos) lastDot = strPath.size(); // 若无扩展名,截到末尾
// 截取文件名(不含路径和扩展名)
std::string strName = strPath.substr(lastSlash, lastDot - lastSlash);
// load image
unsigned level(nResolutionLevel);
const unsigned imageSize(imageData.RecomputeMaxResolution(level, nMinResolution));
if ((imageData.image.empty() || MAXF(imageData.width,imageData.height) != imageSize) && !imageData.ReloadImage(imageSize)) {
#ifdef TEXOPT_USE_OPENMP
bAbort = true;
#pragma omp flush (bAbort)
continue;
#else
return false;
#endif
}
imageData.UpdateCamera(scene.platforms);
// compute gradient magnitude
imageData.image.toGray(imageGradMag, cv::COLOR_BGR2GRAY, true);
cv::Mat grad[2];
mGrad[0].resize(imageGradMag.rows, imageGradMag.cols);
grad[0] = cv::Mat(imageGradMag.rows, imageGradMag.cols, cv::DataType<real>::type, (void*)mGrad[0].data());
mGrad[1].resize(imageGradMag.rows, imageGradMag.cols);
grad[1] = cv::Mat(imageGradMag.rows, imageGradMag.cols, cv::DataType<real>::type, (void*)mGrad[1].data());
cv::Sobel(imageGradMag, grad[0], cv::DataType<real>::type, 1, 0, 3, 1.0/8.0);
cv::Sobel(imageGradMag, grad[1], cv::DataType<real>::type, 0, 1, 3, 1.0/8.0);
(TImage<real>::EMatMap)imageGradMag = (mGrad[0].cwiseAbs2()+mGrad[1].cwiseAbs2()).cwiseSqrt();
// apply some blur on the gradient to lower noise/glossiness effects onto face-quality score
cv::GaussianBlur(imageGradMag, imageGradMag, cv::Size(15, 15), 0, 0, cv::BORDER_DEFAULT);
// select faces inside view frustum
Mesh::FaceIdxArr cameraFaces;
Mesh::FacesInserter inserter(cameraFaces);
const TFrustum<float,5> frustum(Matrix3x4f(imageData.camera.P), (float)imageData.width, (float)imageData.height);
octree.Traverse(frustum, inserter);
// project all triangles in this view and keep the closest ones
faceMap.create(imageData.GetSize());
depthMap.create(imageData.GetSize());
std::unordered_set<FIndex> tempFaces;
{
// RasterMesh rasterer(vertices, imageData.camera, depthMap, faceMap);
RasterMesh rasterer(*this, vertices, imageData.camera, depthMap, faceMap, scene.mesh, false);
RasterMesh::Triangle triangle;
RasterMesh::TriangleRasterizer triangleRasterizer(triangle, rasterer);
if (nIgnoreMaskLabel >= 0) {
// import mask
BitMatrix bmask;
// std::cout << "nIgnoreMaskLabel is open" << std::endl;
DepthEstimator::ImportIgnoreMask(imageData, imageData.GetSize(), (uint16_t)OPTDENSE::nIgnoreMaskLabel, bmask, &rasterer.mask);
} else if (nIgnoreMaskLabel == -1) {
// creating mask to discard invalid regions created during image radial undistortion
rasterer.mask = DetectInvalidImageRegions(imageData.image);
#if TD_VERBOSE != TD_VERBOSE_OFF
if (VERBOSITY_LEVEL > 2)
cv::imwrite(String::FormatString("umask%04d.png", idxView), rasterer.mask);
#endif
}
rasterer.Clear();
for (FIndex idxFace : cameraFaces) {
rasterer.validFace = true;
const Face& facet = faces[idxFace];
rasterer.idxFace = idxFace;
bool bExistFace = facesDatas[idxFace].empty();
if (scene.is_face_visible(strName.c_str(), idxFace) || bExistFace)
{
rasterer.Project(facet, triangleRasterizer);
if (!rasterer.validFace)
rasterer.Project(facet, triangleRasterizer);
}
}
tempFaces = PerformLocalDepthConsistencyCheck(depthMap, faceMap, scene.mesh, idxView, strName);
}
// compute the projection area of visible faces
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
CLISTDEF0IDX(uint32_t,FIndex) areas(faces.size());
areas.Memset(0);
#endif
#ifdef TEXOPT_USE_OPENMP
#pragma omp critical
#endif
{
for (int j=0; j<faceMap.rows; ++j) {
for (int i=0; i<faceMap.cols; ++i) {
const FIndex& idxFace = faceMap(j,i);
// ASSERT((idxFace == NO_ID && depthMap(j,i) == 0) || (idxFace != NO_ID && depthMap(j,i) > 0));
if (idxFace == NO_ID)
continue;
FaceDataArr& faceDatas = facesDatas[idxFace];
const Pixel8U& pixel = imageData.image(j, i);
// 假设是8位图像,RGB三个通道任一超过250即视为过曝
if (pixel.r > 250 || pixel.g > 250 || pixel.b > 250) {
// continue;
}
float brightnessPerceptual = (0.299f * pixel.r + 0.587f * pixel.g + 0.114f * pixel.b) / 255.0f;
// printf("brightnessPerceptual=%f\n", brightnessPerceptual);
if (brightnessPerceptual>0.95f)
continue;
{
if (depthMap(j,i)>999.0f)
{
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
uint32_t& area = areas[idxFace];
if (area++ == 0) {
#else
if (faceDatas.empty() || faceDatas.back().idxView != idxView) {
#endif
// create new face-data
FaceData& faceData = faceDatas.emplace_back();
faceData.idxView = idxView;
faceData.quality = imageGradMag(j,i);
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
faceData.color = imageData.image(j,i);
#endif
faceData.bInvalidFacesRelative = true;
} else {
// update face-data
ASSERT(!faceDatas.empty());
FaceData& faceData = faceDatas.back();
ASSERT(faceData.idxView == idxView);
faceData.quality = imageGradMag(j,i);
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
faceData.color = Color(imageData.image(j,i));
#endif
faceData.bInvalidFacesRelative = true;
}
continue;
}
}
uint32_t& area = areas[idxFace];
if (area++ == 0) {
// create new face-data
FaceData& faceData = faceDatas.emplace_back();
faceData.idxView = idxView;
faceData.quality = imageGradMag(j,i);
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
faceData.color = imageData.image(j,i);
#endif
if (depthMap(j,i)>999.0f)
faceData.bInvalidFacesRelative = true;
} else {
// update face-data
ASSERT(!faceDatas.empty());
FaceData& faceData = faceDatas.back();
ASSERT(faceData.idxView == idxView);
faceData.quality += imageGradMag(j,i);
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
faceData.color += Color(imageData.image(j,i));
#endif
if (depthMap(j,i)>999.0f)
faceData.bInvalidFacesRelative = true;
}
}
}
// adjust face quality with camera angle relative to face normal
// tries to increase chances of a camera with perpendicular view on the surface (smoothened normals) to be selected
FOREACH(idxFace, facesDatas) {
FaceDataArr& faceDatas = facesDatas[idxFace];
if (faceDatas.empty() || faceDatas.back().idxView != idxView)
continue;
const Face& f = faces[idxFace];
const Vertex faceCenter((vertices[f[0]] + vertices[f[1]] + vertices[f[2]]) / 3.f);
const Point3f camDir(Cast<Mesh::Type>(imageData.camera.C) - faceCenter);
const Normal& faceNormal = scene.mesh.faceNormals[idxFace];
const float cosFaceCam(MAXF(0.001f, ComputeAngle(camDir.ptr(), faceNormal.ptr())));
faceDatas.back().quality *= SQUARE(cosFaceCam);
}
#if TEXOPT_FACEOUTLIER != TEXOPT_FACEOUTLIER_NA
FOREACH(idxFace, areas) {
const uint32_t& area = areas[idxFace];
if (area > 0) {
Color& color = facesDatas[idxFace].back().color;
color = RGB2YCBCR(Color(color * (1.f/(float)area)));
}
}
#endif
}
++progress;
}
// */
// Temp
#ifdef TEXOPT_USE_OPENMP #ifdef TEXOPT_USE_OPENMP
if (bAbort) if (bAbort)
return false; return false;

2
libs/MVS/mask_face_occlusion.py

@ -1353,7 +1353,7 @@ class ModelProcessor:
face_visible = v0_visible | v1_visible | v2_visible face_visible = v0_visible | v1_visible | v2_visible
# 使用与CPU版本相同的后续处理 # 使用与CPU版本相同的后续处理
shrunk_visibility = self._shrink_face_visibility(face_visible.cpu().numpy(), 10) shrunk_visibility = self._shrink_face_visibility(face_visible.cpu().numpy(), 6)
expanded_visibility = self._expand_face_visibility(face_visible.cpu().numpy(), 30) expanded_visibility = self._expand_face_visibility(face_visible.cpu().numpy(), 30)
shrunk_visibility2 = self._shrink_face_visibility(face_visible.cpu().numpy(), 50) shrunk_visibility2 = self._shrink_face_visibility(face_visible.cpu().numpy(), 50)
expanded_edge = expanded_visibility & ~shrunk_visibility2 expanded_edge = expanded_visibility & ~shrunk_visibility2

Loading…
Cancel
Save