有优化
This commit is contained in:
1 parent
93dbc93c72
commit
32a270b287
1 file changed
+42
-41
+42
-41
@@ -14616,73 +14616,70 @@ void MeshTexture::AlignPatchColors(Image8U3& atlas,
|
|||||||
const std::vector<IIndex>& texelPatchID,
|
const std::vector<IIndex>& texelPatchID,
|
||||||
int textureSize)
|
int textureSize)
|
||||||
{
|
{
|
||||||
if (atlas.empty() || texelPatchID.empty()) return;
|
if (atlas.empty()) return;
|
||||||
|
const IIndex NP = (IIndex)rcPatches.size();
|
||||||
|
if (NP == 0) return;
|
||||||
|
|
||||||
// ---------- 一次遍历:记录每个 patch 的"向外边界颜色" ----------
|
// 每个 patch 的边界颜色累加(自己侧 + 邻居侧)
|
||||||
// 边界像素的定义:它自己和某个邻居属于不同 patch。
|
struct Acc { cv::Vec3d self = {0,0,0}, nb = {0,0,0}; int selfCnt = 0, nbCnt = 0; };
|
||||||
// 对于这条边,颜色贡献到"我的 patch",同时也贡献到"邻居的 patch"。
|
std::vector<Acc> acc(NP);
|
||||||
struct Acc { cv::Vec3d sum = {0,0,0}; int count = 0; };
|
|
||||||
std::map<IIndex, Acc> myBorder; // patch -> 自己这侧的边界颜色累加
|
|
||||||
std::map<IIndex, Acc> neighborBorder; // patch -> 所有邻居边界颜色的累加
|
|
||||||
|
|
||||||
const int dx4[] = { -1, 1, 0, 0 };
|
const int dx4[] = { -1, 1, 0, 0 };
|
||||||
const int dy4[] = { 0, 0,-1, 1 };
|
const int dy4[] = { 0, 0,-1, 1 };
|
||||||
|
|
||||||
|
// 一次遍历:只处理边界像素
|
||||||
for (int y = 1; y < textureSize - 1; ++y) {
|
for (int y = 1; y < textureSize - 1; ++y) {
|
||||||
for (int x = 1; x < textureSize - 1; ++x) {
|
for (int x = 1; x < textureSize - 1; ++x) {
|
||||||
int idx = y * textureSize + x;
|
int idx = y * textureSize + x;
|
||||||
if (texelPatchID[idx] == NO_ID) continue;
|
if (texelPatchID[idx] == NO_ID) continue;
|
||||||
IIndex myPatch = texelPatchID[idx];
|
IIndex pid = texelPatchID[idx];
|
||||||
const Pixel8U& myPx = atlas(y, x);
|
if (pid >= NP) continue;
|
||||||
cv::Vec3f myColor(myPx[2], myPx[1], myPx[0]); // BGR -> RGB
|
|
||||||
|
const Pixel8U& px = atlas(y, x);
|
||||||
|
cv::Vec3d color(px[2], px[1], px[0]);
|
||||||
|
|
||||||
for (int d = 0; d < 4; ++d) {
|
for (int d = 0; d < 4; ++d) {
|
||||||
int nx = x + dx4[d], ny = y + dy4[d];
|
int nx = x + dx4[d], ny = y + dy4[d];
|
||||||
int nidx = ny * textureSize + nx;
|
int nidx = ny * textureSize + nx;
|
||||||
IIndex nbPatch = texelPatchID[nidx];
|
if (texelPatchID[nidx] == NO_ID || texelPatchID[nidx] == pid) continue;
|
||||||
if (nbPatch == NO_ID || nbPatch == myPatch) continue;
|
|
||||||
|
|
||||||
// 这条边存在:两侧都记录
|
IIndex npid = texelPatchID[nidx];
|
||||||
myBorder[myPatch].sum += cv::Vec3d(myColor);
|
if (npid >= NP) continue;
|
||||||
myBorder[myPatch].count++;
|
const Pixel8U& npx = atlas(ny, nx);
|
||||||
neighborBorder[myPatch].sum += cv::Vec3d(atlas(ny, nx)[2],
|
cv::Vec3d ncolor(npx[2], npx[1], npx[0]);
|
||||||
atlas(ny, nx)[1],
|
|
||||||
atlas(ny, nx)[0]);
|
acc[pid].self += color; acc[pid].selfCnt++;
|
||||||
neighborBorder[myPatch].count++;
|
acc[npid].nb += color; acc[npid].nbCnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------- 计算增益(O(patch 数),不再扫全图)----------
|
// 计算每个 patch 的增益(向邻居对齐)
|
||||||
std::map<IIndex, cv::Vec3f> patchGain;
|
std::vector<cv::Vec3f> gain(NP, cv::Vec3f(1, 1, 1));
|
||||||
for (const auto& entry : myBorder) {
|
for (IIndex i = 0; i < NP; ++i) {
|
||||||
IIndex pid = entry.first;
|
if (acc[i].selfCnt == 0 || acc[i].nbCnt == 0) continue;
|
||||||
if (entry.second.count == 0 || neighborBorder[pid].count == 0) continue;
|
cv::Vec3d selfMean = acc[i].self / acc[i].selfCnt;
|
||||||
|
cv::Vec3d nbMean = acc[i].nb / acc[i].nbCnt;
|
||||||
cv::Vec3d myMean = entry.second.sum / entry.second.count;
|
|
||||||
cv::Vec3d nbMean = neighborBorder[pid].sum / neighborBorder[pid].count;
|
|
||||||
|
|
||||||
cv::Vec3f gain(1, 1, 1);
|
|
||||||
for (int c = 0; c < 3; ++c) {
|
for (int c = 0; c < 3; ++c) {
|
||||||
if (myMean[c] > 1.0f)
|
if (selfMean[c] > 1.0f) {
|
||||||
gain[c] = (float)(nbMean[c] / myMean[c]);
|
float g = (float)(nbMean[c] / selfMean[c]);
|
||||||
gain[c] = std::max(0.5f, std::min(2.0f, gain[c]));
|
gain[i][c] = std::max(0.7f, std::min(1.4f, g)); // 保守范围
|
||||||
|
}
|
||||||
}
|
}
|
||||||
patchGain[pid] = gain;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------- 应用增益 ----------
|
// 应用增益(整个 patch 统一乘)
|
||||||
for (int y = 0; y < textureSize; ++y) {
|
for (int y = 0; y < textureSize; ++y) {
|
||||||
for (int x = 0; x < textureSize; ++x) {
|
for (int x = 0; x < textureSize; ++x) {
|
||||||
int idx = y * textureSize + x;
|
int idx = y * textureSize + x;
|
||||||
if (texelPatchID[idx] == NO_ID) continue;
|
if (texelPatchID[idx] == NO_ID) continue;
|
||||||
auto it = patchGain.find(texelPatchID[idx]);
|
IIndex pid = texelPatchID[idx];
|
||||||
if (it == patchGain.end()) continue;
|
if (pid >= NP) continue;
|
||||||
const cv::Vec3f& gain = it->second;
|
if (gain[pid] == cv::Vec3f(1,1,1)) continue;
|
||||||
Pixel8U& px = atlas(y, x);
|
Pixel8U& px = atlas(y, x);
|
||||||
px[2] = cv::saturate_cast<uchar>(px[2] * gain[0]);
|
px[2] = cv::saturate_cast<uchar>(px[2] * gain[pid][0]);
|
||||||
px[1] = cv::saturate_cast<uchar>(px[1] * gain[1]);
|
px[1] = cv::saturate_cast<uchar>(px[1] * gain[pid][1]);
|
||||||
px[0] = cv::saturate_cast<uchar>(px[0] * gain[2]);
|
px[0] = cv::saturate_cast<uchar>(px[0] * gain[pid][2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14920,6 +14917,10 @@ bool MeshTexture::RasterizeVirtualFaces(
|
|||||||
DEBUG_EXTRA("Patch avg color computed: %d patches, %d with pixels",
|
DEBUG_EXTRA("Patch avg color computed: %d patches, %d with pixels",
|
||||||
NP, NP - std::count(pixelCount.begin(), pixelCount.end(), 0));
|
NP, NP - std::count(pixelCount.begin(), pixelCount.end(), 0));
|
||||||
|
|
||||||
|
for (int iter = 0; iter < 3; ++iter) {
|
||||||
|
AlignPatchColors(atlas, m_texelPatchID, textureSize);
|
||||||
|
}
|
||||||
|
|
||||||
// 5/6/7. 接缝
|
// 5/6/7. 接缝
|
||||||
BuildSeamEdgesFromRCPatches();
|
BuildSeamEdgesFromRCPatches();
|
||||||
if (!rcSeamEdges.empty()) {
|
if (!rcSeamEdges.empty()) {
|
||||||
@@ -14935,7 +14936,7 @@ bool MeshTexture::RasterizeVirtualFaces(
|
|||||||
DEBUG_EXTRA("Seam blending completed: %zu edges (%s)", seamEdges.size(), TD_TIMER_GET_FMT().c_str());
|
DEBUG_EXTRA("Seam blending completed: %zu edges (%s)", seamEdges.size(), TD_TIMER_GET_FMT().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
AlignPatchColors(atlas, m_texelPatchID, textureSize);
|
// AlignPatchColors(atlas, m_texelPatchID, textureSize);
|
||||||
// FeatherTextureSeams(atlas, m_texelPatchID, textureSize, 3);
|
// FeatherTextureSeams(atlas, m_texelPatchID, textureSize, 3);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user