Browse Source

中间版本保存

ManualUV
hesuicong 3 weeks ago
parent
commit
b0c165499c
  1. 265
      libs/MVS/SceneTexture.cpp

265
libs/MVS/SceneTexture.cpp

@ -6935,6 +6935,7 @@ bool MeshTexture::FaceViewSelection3( unsigned minCommonCameras, float fOutlierT
// printf("FaceViewSelection3 2 scene.mesh.vertices.size=%d\n", scene.mesh.vertices.size()); // printf("FaceViewSelection3 2 scene.mesh.vertices.size=%d\n", scene.mesh.vertices.size());
bool bUseVirtualFaces(minCommonCameras > 0); bool bUseVirtualFaces(minCommonCameras > 0);
bUseVirtualFaces = false;
// list all views for each face // list all views for each face
FaceDataViewArr facesDatas; FaceDataViewArr facesDatas;
@ -7673,263 +7674,49 @@ bool MeshTexture::FaceViewSelection3( unsigned minCommonCameras, float fOutlierT
if (!bUseVirtualFaces) if (!bUseVirtualFaces)
{ {
// assign the best view to each face // 分配最佳视图给每个面片
labels.resize(faces.size()); labels.resize(faces.size());
{ labelsInvalid.resize(faces.size());
// normalize quality values
float maxQuality(0);
for (const FaceDataArr& faceDatas: facesDatas) {
for (const FaceData& faceData: faceDatas)
if (maxQuality < faceData.quality)
maxQuality = faceData.quality;
}
Histogram32F hist(std::make_pair(0.f, maxQuality), 1000);
for (const FaceDataArr& faceDatas: facesDatas) {
for (const FaceData& faceData: faceDatas)
hist.Add(faceData.quality);
}
const float normQuality(hist.GetApproximatePermille(0.95f));
#if TEXOPT_INFERENCE == TEXOPT_INFERENCE_LBP
// initialize inference structures
const LBPInference::EnergyType MaxEnergy(fRatioDataSmoothness*(LBPInference::EnergyType)LBPInference::MaxEnergy);
LBPInference inference; {
inference.SetNumNodes(faces.size());
inference.SetSmoothCost(SmoothnessPotts);
// inference.SetSmoothCost(SmoothnessLinear);
// inference.SetSmoothCost(NewSmoothness);
EdgeOutIter ei, eie;
FOREACH(f, faces) {
for (boost::tie(ei, eie) = boost::out_edges(f, graph); ei != eie; ++ei) {
ASSERT(f == (FIndex)ei->m_source);
const FIndex fAdj((FIndex)ei->m_target);
if (f < fAdj) // add edges only once
inference.SetNeighbors(f, fAdj);
}
// set costs for label 0 (undefined)
inference.SetDataCost((Label)0, f, MaxEnergy);
}
}
//* FOREACH(l, labelsInvalid) {
for (const FaceDataArr& faceDatas : facesDatas) { labelsInvalid[l] = NO_ID;
for (const FaceData& faceData : faceDatas) {
if (faceData.quality > maxQuality)
maxQuality = faceData.quality;
}
}
for (const FaceDataArr& faceDatas : facesDatas) {
for (const FaceData& faceData : faceDatas)
hist.Add(faceData.quality);
} }
FOREACH(f, facesDatas) { // 直接为每个面片选择最佳视图(跳过推理)
// if (scene.mesh.invalidFacesRelative.data.contains(f)) FOREACH(f, faces) {
// continue;
const FaceDataArr& faceDatas = facesDatas[f]; const FaceDataArr& faceDatas = facesDatas[f];
const size_t numViews = faceDatas.size(); if (faceDatas.empty()) {
const unsigned minSingleView = 6; // 与虚拟面模式相同的阈值 labels[f] = NO_ID;
bool bInvalidFacesRelative = false;
IIndex invalidView;
float invalidQuality;
// if (numViews <= minSingleView) {
if (true) {
std::vector<std::pair<float, IIndex>> sortedViews;
sortedViews.reserve(faceDatas.size());
for (const FaceData& fd : faceDatas) {
if (fd.bInvalidFacesRelative)
{
bInvalidFacesRelative = true;
// sortedViews.emplace_back(fd.quality, fd.idxView);
invalidView = fd.idxView;
invalidQuality = fd.quality;
}
else
{
// if (fd.quality<=999.0)
{
sortedViews.emplace_back(fd.quality, fd.idxView);
// printf("1fd.quality=%f\n", fd.quality);
}
// else
// printf("2fd.quality=%f\n", fd.quality);
}
}
std::sort(sortedViews.begin(), sortedViews.end(),
[](const auto& a, const auto& b) { return a.first > b.first; });
// 设置数据成本:最佳视角成本最低,其他按质量排序递增
const float baseCostScale = 0.1f; // 基础成本缩放系数
const float costStep = 0.3f; // 相邻视角成本增量
for (const auto& image : images)
{
// printf("image name=%s\n", image.name.c_str());
}
if (bInvalidFacesRelative && sortedViews.size() == 0)
{
// const Label label = (Label)sortedViews[0].second + 1;
const Label label = (Label)invalidView + 1;
float cost = (1.f - invalidQuality / normQuality) * MaxEnergy;
// float cost = 0;
inference.SetDataCost(label, f, cost);
continue; continue;
} }
// printf("sortedViews size=%d\n", sortedViews.size()); float bestQuality = -1.0f;
for (size_t i = 0; i < sortedViews.size(); ++i) { IIndex bestView = NO_ID;
const Label label = (Label)sortedViews[i].second + 1; bool bBestIsInvalid = false;
float cost;
std::string strPath = images[label-1].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);
if (i == 0) {
// if (true) {
// 最佳视角
// cost = (1.f - sortedViews[i].first / normQuality) * MaxEnergy * baseCostScale;
cost = (1.f - sortedViews[i].first / normQuality) * MaxEnergy;
// cost = 0;
inference.SetDataCost(label, f, cost);
} else {
// 其他视角:成本随排名线性增加
int stepIndex = i;
// if (i > 3)
// stepIndex = i - 3;
cost = MaxEnergy * (baseCostScale + costStep * stepIndex);
// 确保成本不超过MaxEnergy
cost = std::min(cost, MaxEnergy);
// cost = MaxEnergy;
inference.SetDataCost(label, f, cost);
}
}
} else {
for (const FaceData& fd : faceDatas) { for (const FaceData& fd : faceDatas) {
const Label label = (Label)fd.idxView + 1; // 跳过无效视图(根据你的需求决定是否跳过)
const float normalizedQuality = fd.quality / normQuality; if (fd.bInvalidFacesRelative) {
const float cost = (1.f - normalizedQuality) * MaxEnergy; // 如果没有有效视图,才考虑无效视图
inference.SetDataCost(label, f, cost); if (bestView == NO_ID) {
} bestView = fd.idxView;
} bestQuality = fd.quality;
} bBestIsInvalid = true;
//*/
// assign the optimal view (label) to each face
// (label 0 is reserved as undefined)
inference.Optimize();
// extract resulting labeling
labels.Memset(0xFF);
FOREACH(l, labels) {
const Label label(inference.GetLabel(l));
ASSERT(label < images.size()+1);
if (label > 0)
labels[l] = label-1;
} }
#endif
#if TEXOPT_INFERENCE == TEXOPT_INFERENCE_TRWS
// find connected components
ASSERT((FIndex)boost::num_vertices(graph) == faces.size());
components.resize(faces.size());
const FIndex nComponents(boost::connected_components(graph, components.data()));
// map face ID from global to component space
typedef cList<NodeID, NodeID, 0, 128, NodeID> NodeIDs;
NodeIDs nodeIDs(faces.size());
NodeIDs sizes(nComponents);
sizes.Memset(0);
FOREACH(c, components)
nodeIDs[c] = sizes[components[c]]++;
// initialize inference structures
const LabelID numLabels(images.size()+1);
CLISTDEFIDX(TRWSInference, FIndex) inferences(nComponents);
FOREACH(s, sizes) {
const NodeID numNodes(sizes[s]);
ASSERT(numNodes > 0);
if (numNodes <= 1)
continue; continue;
TRWSInference& inference = inferences[s];
inference.Init(numNodes, numLabels);
} }
// set data costs if (fd.quality > bestQuality) {
{ bestQuality = fd.quality;
// add nodes bestView = fd.idxView;
CLISTDEF0(EnergyType) D(numLabels); bBestIsInvalid = false;
FOREACH(f, facesDatas) {
TRWSInference& inference = inferences[components[f]];
if (inference.IsEmpty())
continue;
D.MemsetValue(MaxEnergy);
const FaceDataArr& faceDatas = facesDatas[f];
for (const FaceData& faceData: faceDatas) {
const Label label((Label)faceData.idxView);
const float normalizedQuality(faceData.quality>=normQuality ? 1.f : faceData.quality/normQuality);
const EnergyType dataCost(MaxEnergy*(1.f-normalizedQuality));
D[label] = dataCost;
}
const NodeID nodeID(nodeIDs[f]);
inference.AddNode(nodeID, D.Begin());
}
// add edges
EdgeOutIter ei, eie;
FOREACH(f, faces) {
TRWSInference& inference = inferences[components[f]];
if (inference.IsEmpty())
continue;
for (boost::tie(ei, eie) = boost::out_edges(f, graph); ei != eie; ++ei) {
ASSERT(f == (FIndex)ei->m_source);
const FIndex fAdj((FIndex)ei->m_target);
ASSERT(components[f] == components[fAdj]);
if (f < fAdj) // add edges only once
inference.AddEdge(nodeIDs[f], nodeIDs[fAdj]);
}
} }
} }
// assign the optimal view (label) to each face labels[f] = bestView;
#ifdef TEXOPT_USE_OPENMP if (bBestIsInvalid) {
#pragma omp parallel for schedule(dynamic) labelsInvalid[f] = bestView;
for (int i=0; i<(int)inferences.size(); ++i) {
#else
FOREACH(i, inferences) {
#endif
TRWSInference& inference = inferences[i];
if (inference.IsEmpty())
continue;
inference.Optimize();
}
// extract resulting labeling
labels.Memset(0xFF);
FOREACH(l, labels) {
TRWSInference& inference = inferences[components[l]];
if (inference.IsEmpty())
continue;
const Label label(inference.GetLabel(nodeIDs[l]));
ASSERT(label >= 0 && label < numLabels);
if (label < images.size())
labels[l] = label;
} }
#endif
} }
} }

Loading…
Cancel
Save