处理脸色发青问题
This commit is contained in:
1 parent
bbddc87ccc
commit
5685a46331
2 files changed
+224
-1
No files matched your search
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in new issue
Block a user