Compare commits

..
86 Commits
Author SHA1 Message Date
hesuicong 7ffaf9cef2 关闭虚拟面增长优化 2026-08-24 15:09:48 +08:00
hesuicong ccd621f0b1 解决大模型贴图卡住的问题 2026-08-24 11:35:50 +08:00
hesuicong 9008e27d93 还原 2026-08-22 14:43:26 +08:00
hesuicong 2fefb4738c 解决一个崩溃的Bug 2026-08-21 14:48:20 +08:00
hesuicong 3dff609cb8 高光抑制 2026-08-19 15:59:23 +08:00
hesuicong 033dca0dd9 面选择调整 2026-08-19 14:45:05 +08:00
hesuicong 03eee01348 rect添加限制 2026-08-14 15:36:48 +08:00
hesuicong c49c3df5ad 色差问题优化 2026-08-14 14:56:42 +08:00
hesuicong 8577d13579 取消一些注释 2026-08-06 14:27:22 +08:00
hesuicong 982106fec2 解决构建虚拟面邻居图时的一个崩溃Bug 2026-08-06 14:25:15 +08:00
hesuicong 617f8ea2b5 优化虚拟面生成,增强法线和几何约束 2026-08-05 17:41:18 +08:00
hesuicong 715bf75c74 平坦区域虚拟面增长优化 2026-07-29 11:15:08 +08:00
hesuicong 068a06820d 区域生长策略 2026-07-28 17:59:30 +08:00
hesuicong debbe84898 临时代码 2026-07-28 16:41:08 +08:00
hesuicong 9dd09bfc11 代码优化 2026-07-27 14:41:36 +08:00
hesuicong f38ada2abd 更新 2026-07-21 16:17:06 +08:00
hesuicong 72dae852bb 简化相机选择逻辑 2026-07-08 17:36:52 +08:00
hesuicong 97b429ec98 解决色块的问题 2026-07-07 15:23:11 +08:00
hesuicong 4724b2e754 优化接口调用 2026-07-03 17:01:57 +08:00
hesuicong 4cc5558629 优化 2026-07-02 16:01:09 +08:00
hesuicong 0d3dd2909a 去掉一些注释 2026-07-02 15:24:10 +08:00
hesuicong d157312fba 多视图混合采样替换patch 2026-07-02 14:41:00 +08:00
hesuicong b28b78ee93 参数优化 2026-06-29 16:07:31 +08:00
hesuicong b9d12648a1 参数进一步优化 2026-06-29 11:51:52 +08:00
hesuicong 78aaaefb1a 兼容性更大 2026-06-26 09:39:23 +08:00
hesuicong 8ff037ff5e 参数优化 2026-06-25 18:17:47 +08:00
hesuicong 9696034738 参数优化 2026-06-25 16:54:03 +08:00
hesuicong 7f967e5434 参数优化 2026-06-25 10:45:15 +08:00
hesuicong eda58b268f 参数优化 2026-06-24 14:47:15 +08:00
hesuicong e21b2f572b 优化参数 2026-06-23 17:05:09 +08:00
hesuicong 54c7ea1240 评分系统优化 2026-06-23 16:47:53 +08:00
hesuicong b47e0ab82f 添加评分系统来处理视图选择 2026-06-23 15:53:04 +08:00
hesuicong 9c3e97f447 单视图投射进一步优化 2026-06-22 14:54:09 +08:00
hesuicong c927ce7db7 小臂问题优化 2026-06-16 10:38:05 +08:00
hesuicong 65d8242c9c 小臂测试优化 2026-06-15 18:02:34 +08:00
hesuicong 383bd34431 进一步调优版本 2026-06-13 16:25:06 +08:00
hesuicong ec1a89b078 两轮填数据方式 2026-06-12 17:31:09 +08:00
hesuicong b469eb83ff 供面片决策的筛选视图决策宽松,每一个面片一旦优势命中后,剔除所有视图 2026-06-11 17:56:40 +08:00
hesuicong 4048de2dc4 优化筛选逻辑 2026-06-11 16:13:33 +08:00
hesuicong 9ab39219b1 最佳视图选择逻辑优化 2026-06-10 18:34:36 +08:00
hesuicong 68cb2ea1fc 优化bug 2026-06-06 17:47:04 +08:00
hesuicong 3159aa8b5e 一个失误 2026-06-05 14:35:24 +08:00
hesuicong ef9de71d44 单视图优化 2026-06-05 14:13:53 +08:00
hesuicong 1421d21597 进一步优化 2026-05-30 15:18:09 +08:00
hesuicong 3693365bdf 算法优化 2026-05-29 18:05:56 +08:00
hesuicong 03929e5b95 视图排序优化 2026-05-28 18:13:42 +08:00
hesuicong 1086eb09c5 优化染色版本 2026-05-28 10:54:42 +08:00
hesuicong 7d0487ea30 针对小黄点过多和手指染色问题的参数优化 2026-05-25 14:40:16 +08:00
hesuicong cbe065a6a1 参数进一步优化 2026-05-22 17:42:12 +08:00
hesuicong 488f5a3f93 颜色溢出进一步优化 2026-05-21 14:57:14 +08:00
hesuicong e18f91e894 颜色溢出优化 2026-05-20 17:50:50 +08:00
hesuicong eafae796c2 删除保留的函数,简化 2026-04-16 09:16:33 +08:00
hesuicong 35ac5deff9 参数优化 2026-04-14 14:47:15 +08:00
hesuicong f9e7f3f18b 解决线上问题 2026-04-11 17:59:47 +08:00
hesuicong d035a20e91 参数优化 2026-04-03 10:24:05 +08:00
hesuicong d11d956b58 参数优化 2026-04-01 16:39:20 +08:00
hesuicong 743835d1b0 参数优化 2026-03-27 17:41:10 +08:00
hesuicong 4968fcc954 优化参数 2026-03-27 11:40:58 +08:00
hesuicong dbe42abf1f 优化脸色发青问题 2026-03-26 17:28:05 +08:00
hesuicong 5685a46331 处理脸色发青问题 2026-03-24 16:47:59 +08:00
hesuicong bbddc87ccc 优化过滤算法 2026-03-23 11:05:51 +08:00
hesuicong 634590e6d4 处理脸部青黄问题 2026-03-21 15:58:56 +08:00
hesuicong 955419e110 参数优化 2026-03-19 16:43:04 +08:00
hesuicong 1483610ed5 优化参数 2026-03-16 09:39:00 +08:00
hesuicong 6bd6b27f17 鼻子黑 2026-03-11 18:16:15 +08:00
hesuicong 37ebcdf0fd 鼻子黑的问题优化 2026-03-11 18:08:17 +08:00
hesuicong ef09d2521a 白痕优化 2026-03-06 17:05:01 +08:00
hesuicong 60f024abaf 优化性能 2026-03-03 16:02:18 +08:00
hesuicong 469f3df88d 优化性能 2026-03-03 16:01:18 +08:00
hesuicong bc461bd595 添加调试单视图信息 2026-02-24 17:43:34 +08:00
hesuicong 5e4872f41d 去小黄点bug修复 2026-02-09 10:16:06 +08:00
hesuicong f123063221 染色处理 2026-01-23 17:17:35 +08:00
hesuicong be5adbf434 优化明暗问题 2026-01-23 16:48:33 +08:00
hesuicong 94b3aee50a Merge branch 'master' of https://git.suwa3d.com/hesuicong/openMVS 2026-01-23 16:46:28 +08:00
hesuicong 53111c6275 染色问题处理 2026-01-23 16:45:56 +08:00
kehan 86627b5d24 将python缓存从库中忽略 2026-01-22 14:53:25 +08:00
kehan 7f14d73b13 修改了路径符合线上代码格式 2026-01-22 14:51:53 +08:00
hesuicong 3e6410b290 针对线上做进一步优化 2026-01-20 17:43:46 +08:00
hesuicong 9e3c78c92e 处理色彩斑驳的问题 2026-01-20 10:06:34 +08:00
hesuicong cb545049c2 修正路径问题 2026-01-19 09:49:32 +08:00
hesuicong b95b9ca27a 优化 2026-01-16 15:09:48 +08:00
hesuicong bccd31fea6 优化明暗问题 2026-01-13 14:09:48 +08:00
hesuicong f045aa534e 处理贴图问题 2026-01-12 17:01:19 +08:00
hesuicong 338243fa14 明亮问题处理 2026-01-12 16:01:03 +08:00
hesuicong 9c1b1c3944 处理过亮过暗的问题 2026-01-09 16:06:44 +08:00
hesuicong 7baf59740f ignore 2025-12-31 09:56:42 +08:00
11 changed files with 5096 additions and 10623 deletions

No files matched your search

+1
View File
@@ -7,6 +7,7 @@
# Precompiled Headers # Precompiled Headers
*.gch *.gch
*.pch *.pch
*.pyc
# Compiled Dynamic libraries # Compiled Dynamic libraries
*.so *.so
+1 -1
View File
@@ -52,7 +52,7 @@ ENDIF()
PROJECT(OpenMVS) PROJECT(OpenMVS)
SET(ENV_PYTHON_PATH "/home/algo/.conda/envs/py310_pyt210/lib/python3.10/site-packages") SET(ENV_PYTHON_PATH "/home/algo/.conda/envs/py310_pyt210/lib/python3.10/site-packages")
SET(ENV_MVS_PATH "/home/algo/Documents/openMVS/openMVS.ManualUV/libs/MVS") SET(ENV_MVS_PATH "/home/algo/Documents/openMVS/openMVS/libs/MVS")
CONFIGURE_FILE( CONFIGURE_FILE(
"${CMAKE_CURRENT_SOURCE_DIR}/build/Templates/ConfigEnv.h.in" "${CMAKE_CURRENT_SOURCE_DIR}/build/Templates/ConfigEnv.h.in"
+2 -7
View File
@@ -94,9 +94,6 @@ unsigned nMaxThreads;
int nMaxTextureSize; int nMaxTextureSize;
String strExportType; String strExportType;
String strConfigFileName; String strConfigFileName;
bool bUseExistingUV;
String strUVMeshFileName;
boost::program_options::variables_map vm; boost::program_options::variables_map vm;
} // namespace OPT } // namespace OPT
@@ -166,8 +163,6 @@ bool Application::Initialize(size_t argc, LPCTSTR* argv)
("image-folder", boost::program_options::value<std::string>(&OPT::strImageFolder)->default_value(COLMAP_IMAGES_FOLDER), "folder to the undistorted images") ("image-folder", boost::program_options::value<std::string>(&OPT::strImageFolder)->default_value(COLMAP_IMAGES_FOLDER), "folder to the undistorted images")
("origin-faceview", boost::program_options::value(&OPT::bOriginFaceview)->default_value(false), "use origin faceview selection") ("origin-faceview", boost::program_options::value(&OPT::bOriginFaceview)->default_value(false), "use origin faceview selection")
("id", boost::program_options::value(&OPT::nID)->default_value(0), "id") ("id", boost::program_options::value(&OPT::nID)->default_value(0), "id")
("use-existing-uv", boost::program_options::value(&OPT::bUseExistingUV)->default_value(false), "use existing UV coordinates from the input mesh")
("uv-mesh-file", boost::program_options::value<std::string>(&OPT::strUVMeshFileName), "mesh file with pre-computed UV coordinates")
; ;
// hidden options, allowed both on command line and // hidden options, allowed both on command line and
@@ -1139,12 +1134,12 @@ int main(int argc, LPCTSTR* argv)
if (!scene.TextureMesh(OPT::nResolutionLevel, OPT::nMinResolution, OPT::minCommonCameras, OPT::fOutlierThreshold, OPT::fRatioDataSmoothness, if (!scene.TextureMesh(OPT::nResolutionLevel, OPT::nMinResolution, OPT::minCommonCameras, OPT::fOutlierThreshold, OPT::fRatioDataSmoothness,
OPT::bGlobalSeamLeveling, OPT::bLocalSeamLeveling, OPT::nTextureSizeMultiple, OPT::nRectPackingHeuristic, Pixel8U(OPT::nColEmpty), OPT::bGlobalSeamLeveling, OPT::bLocalSeamLeveling, OPT::nTextureSizeMultiple, OPT::nRectPackingHeuristic, Pixel8U(OPT::nColEmpty),
OPT::fSharpnessWeight, OPT::nIgnoreMaskLabel, OPT::nMaxTextureSize, views, baseFileName, OPT::bOriginFaceview, OPT::fSharpnessWeight, OPT::nIgnoreMaskLabel, OPT::nMaxTextureSize, views, baseFileName, OPT::bOriginFaceview,
OPT::strInputFileName, OPT::strMeshFileName, OPT::bUseExistingUV, OPT::strUVMeshFileName)) OPT::strInputFileName, OPT::strMeshFileName))
return EXIT_FAILURE; return EXIT_FAILURE;
VERBOSE("Mesh texturing completed: %u vertices, %u faces (%s)", scene.mesh.vertices.GetSize(), scene.mesh.faces.GetSize(), TD_TIMER_GET_FMT().c_str()); VERBOSE("Mesh texturing completed: %u vertices, %u faces (%s)", scene.mesh.vertices.GetSize(), scene.mesh.faces.GetSize(), TD_TIMER_GET_FMT().c_str());
// save the final mesh // save the final mesh
scene.mesh.Save(baseFileName+OPT::strExportType,cList<String>(),true,OPT::bUseExistingUV); scene.mesh.Save(baseFileName+OPT::strExportType);
#if TD_VERBOSE != TD_VERBOSE_OFF #if TD_VERBOSE != TD_VERBOSE_OFF
if (VERBOSITY_LEVEL > 2) if (VERBOSITY_LEVEL > 2)
scene.ExportCamerasMLP(baseFileName+_T(".mlp"), baseFileName+OPT::strExportType); scene.ExportCamerasMLP(baseFileName+_T(".mlp"), baseFileName+OPT::strExportType);
File diff suppressed because it is too large. Load diff
+1 -128
View File
@@ -48,7 +48,6 @@ ObjModel::MaterialLib::MaterialLib()
bool ObjModel::MaterialLib::Save(const String& prefix, bool texLossless) const bool ObjModel::MaterialLib::Save(const String& prefix, bool texLossless) const
{ {
DEBUG_EXTRA("MaterialLib::Save %s", prefix.c_str());
std::ofstream out((prefix+".mtl").c_str()); std::ofstream out((prefix+".mtl").c_str());
if (!out.good()) if (!out.good())
return false; return false;
@@ -131,7 +130,7 @@ bool ObjModel::MaterialLib::Load(const String& fileName)
// S T R U C T S /////////////////////////////////////////////////// // S T R U C T S ///////////////////////////////////////////////////
bool ObjModel::Save(const String& fileName, unsigned precision, bool texLossless, bool bUseExistingUV) const bool ObjModel::Save(const String& fileName, unsigned precision, bool texLossless) const
{ {
if (vertices.empty()) if (vertices.empty())
return false; return false;
@@ -141,9 +140,6 @@ bool ObjModel::Save(const String& fileName, unsigned precision, bool texLossless
if (!material_lib.Save(prefix, texLossless)) if (!material_lib.Save(prefix, texLossless))
return false; return false;
if (bUseExistingUV)
return true;
std::ofstream out((prefix + ".obj").c_str()); std::ofstream out((prefix + ".obj").c_str());
if (!out.good()) if (!out.good())
return false; return false;
@@ -273,129 +269,6 @@ bool ObjModel::Load(const String& fileName)
return !vertices.empty(); return !vertices.empty();
} }
bool ObjModel::LoadUV(const String& fileName, SEACAVE::cList<TexCoord,const TexCoord&,0,8192,uint32_t> &faceTexcoords, bool bLoadUV)
{
DEBUG_EXTRA("LoadUV bLoadUV=%b", bLoadUV);
ASSERT(vertices.empty() && groups.empty() && material_lib.materials.empty());
std::ifstream fin(fileName.c_str());
String line, keyword;
std::istringstream in;
while (fin.good()) {
std::getline(fin, line);
if (line.empty() || line[0u] == '#')
continue;
in.str(line);
in >> keyword;
if (keyword == "v") {
Vertex v;
in >> v[0] >> v[1] >> v[2];
if (in.fail())
{
DEBUG_EXTRA("1");
return false;
}
vertices.push_back(v);
// DEBUG_EXTRA("10, %d", vertices.size());
} else if (keyword == "vt") {
TexCoord vt;
in >> vt[0] >> vt[1];
if (in.fail())
{
DEBUG_EXTRA("2");
return false;
}
texcoords.push_back(vt);
} else if (keyword == "vn") {
Normal vn;
in >> vn[0] >> vn[1] >> vn[2];
if (in.fail())
{
DEBUG_EXTRA("3");
return false;
}
normals.push_back(vn);
} else if (keyword == "f") {
Face f;
memset(&f, 0xFF, sizeof(Face));
for (size_t k = 0; k < 3; ++k) {
in >> keyword;
// 更健壮的解析方法,处理各种索引格式
std::vector<String> parts;
size_t start = 0, end = 0;
// 按'/'分割字符串
while ((end = keyword.find('/', start)) != String::npos) {
parts.push_back(keyword.substr(start, end - start));
start = end + 1;
}
parts.push_back(keyword.substr(start));
// 根据分割后的部分数量处理不同情况
if (parts.size() >= 1 && !parts[0].empty()) {
f.vertices[k] = std::stoi(parts[0]) - OBJ_INDEX_OFFSET;
}
if (parts.size() >= 2 && !parts[1].empty()) {
f.texcoords[k] = std::stoi(parts[1]) - OBJ_INDEX_OFFSET;
}
if (parts.size() >= 3 && !parts[2].empty()) {
f.normals[k] = std::stoi(parts[2]) - OBJ_INDEX_OFFSET;
}
}
if (in.fail())
{
DEBUG_EXTRA("4");
return false;
}
if (bLoadUV)
{
for (int i = 0; i < 3; ++i) {
if (f.texcoords[i] != NO_ID && f.texcoords[i] < texcoords.size()) {
faceTexcoords.push_back(texcoords[f.texcoords[i]]);
} else {
// 索引无效(例如面定义中未提供vt索引或索引越界),使用默认值
faceTexcoords.push_back(Point2f(0.0f, 0.0f)); // 默认UV
DEBUG_EXTRA("Invalid texcoords %d", f.texcoords[i])
}
}
// DEBUG_EXTRA("faceTexcoords push_back [(%f,%f),(%f,%f),(%f,%f)]", texcoords[f.texcoords[0]].x, texcoords[f.texcoords[0]].y,
// texcoords[f.texcoords[1]].x, texcoords[f.texcoords[1]].y, texcoords[f.texcoords[2]].x, texcoords[f.texcoords[2]].y);
}
if (groups.empty())
AddGroup("");
groups.back().faces.push_back(f);
// } else if (keyword == "mtllib") {
// in >> keyword;
// if (!material_lib.Load(keyword))
// DEBUG_EXTRA("3");
// return false;
} else if (keyword == "usemtl") {
Group group;
in >> group.material_name;
if (in.fail())
{
DEBUG_EXTRA("5");
return false;
}
groups.push_back(group);
}
in.clear();
}
DEBUG_EXTRA("6, vertices.size=%d, faceTexcoords.size=%d", vertices.size(), faceTexcoords.size());
return !vertices.empty();
}
ObjModel::Group& ObjModel::AddGroup(const String& material_name) ObjModel::Group& ObjModel::AddGroup(const String& material_name)
{ {
+1 -2
View File
@@ -93,10 +93,9 @@ public:
ObjModel() {} ObjModel() {}
// Saves the obj model to an .obj file, its material lib and the materials with the given file name // Saves the obj model to an .obj file, its material lib and the materials with the given file name
bool Save(const String& fileName, unsigned precision=6, bool texLossless=false, bool bUseExistingUV=false) const; bool Save(const String& fileName, unsigned precision=6, bool texLossless=false) const;
// Loads the obj model from an .obj file, its material lib and the materials with the given file name // Loads the obj model from an .obj file, its material lib and the materials with the given file name
bool Load(const String& fileName); bool Load(const String& fileName);
bool LoadUV(const String& fileName, SEACAVE::cList<TexCoord,const TexCoord&,0,8192,uint32_t> &faceTexcoords, bool bLoadUV = false);
// Creates a new group with the given material name // Creates a new group with the given material name
Group& AddGroup(const String& material_name); Group& AddGroup(const String& material_name);
+11 -61
View File
@@ -1191,14 +1191,15 @@ namespace BasicPLY {
} // namespace MeshInternal } // namespace MeshInternal
// import the mesh from the given file // import the mesh from the given file
bool Mesh::Load(const String& fileName, bool bLoadUV) bool Mesh::Load(const String& fileName)
{ {
TD_TIMER_STARTD(); TD_TIMER_STARTD();
const String ext(Util::getFileExt(fileName).ToLower()); const String ext(Util::getFileExt(fileName).ToLower());
bool ret; bool ret;
if (ext == _T(".obj")) if (ext == _T(".obj"))
ret = LoadOBJ(fileName, bLoadUV); ret = LoadOBJ(fileName);
else if (ext == _T(".gltf") || ext == _T(".glb")) else
if (ext == _T(".gltf") || ext == _T(".glb"))
ret = LoadGLTF(fileName, ext == _T(".glb")); ret = LoadGLTF(fileName, ext == _T(".glb"));
else else
ret = LoadPLY(fileName); ret = LoadPLY(fileName);
@@ -1207,43 +1208,6 @@ bool Mesh::Load(const String& fileName, bool bLoadUV)
DEBUG_EXTRA("Mesh loaded: %u vertices, %u faces (%s)", vertices.size(), faces.size(), TD_TIMER_GET_FMT().c_str()); DEBUG_EXTRA("Mesh loaded: %u vertices, %u faces (%s)", vertices.size(), faces.size(), TD_TIMER_GET_FMT().c_str());
return true; return true;
} }
void Mesh::CheckUVValid()
{
for (int_t idxFace = 0; idxFace < (int_t)faces.size(); ++idxFace)
{
FOREACH(idxFace, faces)
{
const FIndex faceID = (FIndex)idxFace;
const TexCoord* uv = &faceTexcoords[faceID * 3];
const Point2f& a = uv[0];
const Point2f& b = uv[1];
const Point2f& c = uv[2];
// DEBUG_EXTRA("a=(%f,%f),b=(%f,%f),c=(%f,%f)", a.x, a.y, b.x, b.y, c.x, c.y);
// 计算边向量
Point2f v0 = b - a;
Point2f v1 = c - a;
float denom = (v0.x * v0.x + v0.y * v0.y) * (v1.x * v1.x + v1.y * v1.y) -
std::pow(v0.x * v1.x + v0.y * v1.y, 2);
// 处理退化三角形情况(面积接近0)
const float epsilon = 1e-10f;
if (std::abs(denom) < epsilon)
{
// DEBUG_EXTRA("PointInTriangle - Degenerate triangle, denom=%.10f", denom);
}
else
{
// DEBUG_EXTRA("PointInTriangle Yes idxFace=%d", idxFace);
}
}
}
}
// import the mesh as a PLY file // import the mesh as a PLY file
bool Mesh::LoadPLY(const String& fileName) bool Mesh::LoadPLY(const String& fileName)
{ {
@@ -1338,29 +1302,17 @@ bool Mesh::LoadPLY(const String& fileName)
return true; return true;
} }
// import the mesh as a OBJ file // import the mesh as a OBJ file
bool Mesh::LoadOBJ(const String& fileName, bool bLoadUV) bool Mesh::LoadOBJ(const String& fileName)
{ {
ASSERT(!fileName.empty()); ASSERT(!fileName.empty());
Release(); Release();
// open and parse OBJ file // open and parse OBJ file
ObjModel model; ObjModel model;
if (bLoadUV) if (!model.Load(fileName)) {
{ DEBUG_EXTRA("error: invalid OBJ file");
if (!model.LoadUV(fileName, faceTexcoords, true)) {
DEBUG_EXTRA("error: LoadUV invalid OBJ file %s", fileName.c_str());
return false; return false;
} }
}
else
{
if (!model.LoadUV(fileName, faceTexcoords)) {
// if (!model.Load(fileName)) {
DEBUG_EXTRA("error: Load invalid OBJ file %s", fileName.c_str());
return false;
}
}
if (model.get_vertices().empty() || model.get_groups().empty()) { if (model.get_vertices().empty() || model.get_groups().empty()) {
DEBUG_EXTRA("error: invalid mesh file"); DEBUG_EXTRA("error: invalid mesh file");
@@ -1388,13 +1340,11 @@ bool Mesh::LoadOBJ(const String& fileName, bool bLoadUV)
for (const ObjModel::Face& f: group.faces) { for (const ObjModel::Face& f: group.faces) {
ASSERT(f.vertices[0] != NO_ID); ASSERT(f.vertices[0] != NO_ID);
faces.emplace_back(f.vertices[0], f.vertices[1], f.vertices[2]); faces.emplace_back(f.vertices[0], f.vertices[1], f.vertices[2]);
/*
if (f.texcoords[0] != NO_ID) { if (f.texcoords[0] != NO_ID) {
for (int i=0; i<3; ++i) for (int i=0; i<3; ++i)
faceTexcoords.emplace_back(model.get_texcoords()[f.texcoords[i]]); faceTexcoords.emplace_back(model.get_texcoords()[f.texcoords[i]]);
faceTexindices.emplace_back((TexIndex)groupIdx); faceTexindices.emplace_back((TexIndex)groupIdx);
} }
*/
if (f.normals[0] != NO_ID) { if (f.normals[0] != NO_ID) {
Normal& n = faceNormals.emplace_back(Normal::ZERO); Normal& n = faceNormals.emplace_back(Normal::ZERO);
for (int i=0; i<3; ++i) for (int i=0; i<3; ++i)
@@ -1495,13 +1445,13 @@ bool Mesh::LoadGLTF(const String& fileName, bool bBinary)
/*----------------------------------------------------------------*/ /*----------------------------------------------------------------*/
// export the mesh to the given file // export the mesh to the given file
bool Mesh::Save(const String& fileName, const cList<String>& comments, bool bBinary, bool bUseExistingUV) const bool Mesh::Save(const String& fileName, const cList<String>& comments, bool bBinary) const
{ {
TD_TIMER_STARTD(); TD_TIMER_STARTD();
const String ext(Util::getFileExt(fileName).ToLower()); const String ext(Util::getFileExt(fileName).ToLower());
bool ret; bool ret;
if (ext == _T(".obj")) if (ext == _T(".obj"))
ret = SaveOBJ(fileName, bUseExistingUV); ret = SaveOBJ(fileName);
else else
if (ext == _T(".gltf") || ext == _T(".glb")) if (ext == _T(".gltf") || ext == _T(".glb"))
ret = SaveGLTF(fileName, ext == _T(".glb")); ret = SaveGLTF(fileName, ext == _T(".glb"));
@@ -1588,7 +1538,7 @@ bool Mesh::SavePLY(const String& fileName, const cList<String>& comments, bool b
return true; return true;
} }
// export the mesh as a OBJ file // export the mesh as a OBJ file
bool Mesh::SaveOBJ(const String& fileName, bool bUseExistingUV) const bool Mesh::SaveOBJ(const String& fileName) const
{ {
ASSERT(!fileName.empty()); ASSERT(!fileName.empty());
Util::ensureFolder(fileName); Util::ensureFolder(fileName);
@@ -1647,7 +1597,7 @@ bool Mesh::SaveOBJ(const String& fileName, bool bUseExistingUV) const
pMaterial->diffuse_map = texturesDiffuse[idxTexture]; pMaterial->diffuse_map = texturesDiffuse[idxTexture];
} }
return model.Save(fileName, 6U, true, bUseExistingUV); return model.Save(fileName, 6U, true);
} }
// export the mesh as a GLTF file // export the mesh as a GLTF file
template <typename T> template <typename T>
+4 -6
View File
@@ -262,8 +262,8 @@ public:
bool TransferTexture(Mesh& mesh, const FaceIdxArr& faceSubsetIndices={}, unsigned borderSize=3, unsigned textureSize=4096); bool TransferTexture(Mesh& mesh, const FaceIdxArr& faceSubsetIndices={}, unsigned borderSize=3, unsigned textureSize=4096);
// file IO // file IO
bool Load(const String& fileName, bool bLoadUV=false); bool Load(const String& fileName);
bool Save(const String& fileName, const cList<String>& comments=cList<String>(), bool bBinary=true, bool bUseExistingUV=false) const; bool Save(const String& fileName, const cList<String>& comments=cList<String>(), bool bBinary=true) const;
bool Save(const FacesChunkArr&, const String& fileName, const cList<String>& comments=cList<String>(), bool bBinary=true) const; bool Save(const FacesChunkArr&, const String& fileName, const cList<String>& comments=cList<String>(), bool bBinary=true) const;
static bool Save(const VertexArr& vertices, const String& fileName, bool bBinary=true); static bool Save(const VertexArr& vertices, const String& fileName, bool bBinary=true);
@@ -271,15 +271,13 @@ public:
static inline VIndex GetVertex(const Face& f, VIndex v) { const uint32_t idx(FindVertex(f, v)); ASSERT(idx != NO_ID); return f[idx]; } static inline VIndex GetVertex(const Face& f, VIndex v) { const uint32_t idx(FindVertex(f, v)); ASSERT(idx != NO_ID); return f[idx]; }
static inline VIndex& GetVertex(Face& f, VIndex v) { const uint32_t idx(FindVertex(f, v)); ASSERT(idx != NO_ID); return f[idx]; } static inline VIndex& GetVertex(Face& f, VIndex v) { const uint32_t idx(FindVertex(f, v)); ASSERT(idx != NO_ID); return f[idx]; }
void CheckUVValid();
protected: protected:
bool LoadPLY(const String& fileName); bool LoadPLY(const String& fileName);
bool LoadOBJ(const String& fileName, bool bLoadUV); bool LoadOBJ(const String& fileName);
bool LoadGLTF(const String& fileName, bool bBinary=true); bool LoadGLTF(const String& fileName, bool bBinary=true);
bool SavePLY(const String& fileName, const cList<String>& comments=cList<String>(), bool bBinary=true, bool bTexLossless=true) const; bool SavePLY(const String& fileName, const cList<String>& comments=cList<String>(), bool bBinary=true, bool bTexLossless=true) const;
bool SaveOBJ(const String& fileName, bool bUseExistingUV) const; bool SaveOBJ(const String& fileName) const;
bool SaveGLTF(const String& fileName, bool bBinary=true) const; bool SaveGLTF(const String& fileName, bool bBinary=true) const;
#ifdef _USE_CUDA #ifdef _USE_CUDA
+7 -16
View File
@@ -65,6 +65,8 @@ public:
std::map<std::string, std::unordered_set<int>> visible_faces_map; std::map<std::string, std::unordered_set<int>> visible_faces_map;
std::map<std::string, std::unordered_set<int>> edge_faces_map; std::map<std::string, std::unordered_set<int>> edge_faces_map;
std::map<std::string, std::unordered_set<int>> delete_edge_faces_map; std::map<std::string, std::unordered_set<int>> delete_edge_faces_map;
std::map<std::string, std::unordered_set<int>> delete_edge_faces_map2;
std::map<std::string, std::unordered_set<int>> face_normal_visible_map;
std::unordered_set<int> face_visible_relative; std::unordered_set<int> face_visible_relative;
public: public:
@@ -163,34 +165,23 @@ public:
std::unordered_set<int>& face_visible_relative, std::unordered_set<int>& face_visible_relative,
std::map<std::string, std::unordered_set<int>>& edge_faces_map, std::map<std::string, std::unordered_set<int>>& edge_faces_map,
std::map<std::string, std::unordered_set<int>>& delete_edge_faces_map, std::map<std::string, std::unordered_set<int>>& delete_edge_faces_map,
std::map<std::string, std::unordered_set<int>>& delete_edge_faces_map2,
std::map<std::string, std::unordered_set<int>>& face_normal_visible_map,
std::string& basePath); std::string& basePath);
bool LoadVisibleFacesData() {
std::map<std::string, std::unordered_set<int>> visible_faces_map;
std::unordered_set<int> face_visible_relative;
std::map<std::string, std::unordered_set<int>> edge_faces_map;
std::map<std::string, std::unordered_set<int>> delete_edge_faces_map;
std::string basePath = GetDefaultBasePath(); // 你需要实现这个函数
return LoadVisibleFacesData(visible_faces_map, face_visible_relative,
edge_faces_map, delete_edge_faces_map, basePath);
}
std::string GetDefaultBasePath() {
// 根据你的需求实现这个函数
// 例如:返回一个默认的路径,或者从配置中读取
return "default_path";
}
// Mesh texturing // Mesh texturing
bool TextureMesh(unsigned nResolutionLevel, unsigned nMinResolution, unsigned minCommonCameras=0, float fOutlierThreshold=0.f, float fRatioDataSmoothness=0.3f, bool TextureMesh(unsigned nResolutionLevel, unsigned nMinResolution, unsigned minCommonCameras=0, float fOutlierThreshold=0.f, float fRatioDataSmoothness=0.3f,
bool bGlobalSeamLeveling=true, bool bLocalSeamLeveling=true, unsigned nTextureSizeMultiple=0, unsigned nRectPackingHeuristic=3, Pixel8U colEmpty=Pixel8U(255,127,39), bool bGlobalSeamLeveling=true, bool bLocalSeamLeveling=true, unsigned nTextureSizeMultiple=0, unsigned nRectPackingHeuristic=3, Pixel8U colEmpty=Pixel8U(255,127,39),
float fSharpnessWeight=0.5f, int ignoreMaskLabel=-1, int maxTextureSize=0, const IIndexArr& views=IIndexArr(), const SEACAVE::String& basename = "", bool bOriginFaceview = false, float fSharpnessWeight=0.5f, int ignoreMaskLabel=-1, int maxTextureSize=0, const IIndexArr& views=IIndexArr(), const SEACAVE::String& basename = "", bool bOriginFaceview = false,
const std::string& inputFileName = "", const std::string& meshFileName = "", bool bUseExistingUV = false, const std::string& strUVMeshFileName = ""); const std::string& inputFileName = "", const std::string& meshFileName = "");
std::string runPython(const std::string& command); std::string runPython(const std::string& command);
bool is_face_visible(const std::string& image_name, int face_index); bool is_face_visible(const std::string& image_name, int face_index);
bool is_face_visible_relative(int face_index); bool is_face_visible_relative(int face_index);
bool is_face_edge(const std::string& image_name, int face_index); bool is_face_edge(const std::string& image_name, int face_index);
bool is_face_delete_edge(const std::string& image_name, int face_index); bool is_face_delete_edge(const std::string& image_name, int face_index);
bool is_face_delete_edge2(const std::string& image_name, int face_index);
bool is_face_normal_visible_map(const std::string& image_name, int face_index);
void SegmentMeshBasedOnCurvature(Mesh::FaceIdxArr& regionMap, float curvatureThreshold); void SegmentMeshBasedOnCurvature(Mesh::FaceIdxArr& regionMap, float curvatureThreshold);
+4132 -9786
View File
File diff suppressed because it is too large. Load diff
+137 -157
View File
@@ -4,7 +4,8 @@ import os
import numpy as np import numpy as np
from scipy.spatial.transform import Rotation from scipy.spatial.transform import Rotation
import sys import sys
sys.path.append("/home/algo/Documents/openMVS/openMVS/libs/MVS/utils") # sys.path.append("/home/algo/Documents/openMVS/openMVS/libs/MVS/utils")
sys.path.append("/root/code/openMVS/libs/MVS/utils")
from colmap_loader import read_cameras_text, read_images_text, read_int_text, write_int_text, read_indices_from_file from colmap_loader import read_cameras_text, read_images_text, read_int_text, write_int_text, read_indices_from_file
# from get_pose_matrix import get_w2c # from get_pose_matrix import get_w2c
import argparse import argparse
@@ -33,6 +34,7 @@ from typing import Dict, List, Set
import struct import struct
import math import math
# import os # import os
from pathlib import Path
CameraModel = collections.namedtuple( CameraModel = collections.namedtuple(
"CameraModel", ["model_id", "model_name", "num_params"] "CameraModel", ["model_id", "model_name", "num_params"]
@@ -1350,14 +1352,90 @@ class ModelProcessor:
face_visible = v0_visible | v1_visible | v2_visible face_visible = v0_visible | v1_visible | v2_visible
# ============ 新增:法线夹角过滤 ============
# 1. 获取面片法线(向量化计算,性能更好)
if not hasattr(self, 'face_normals_tensor'):
# 从mesh获取顶点和面片索引
vertices = np.asarray(self.mesh.vertices) # 形状: (V, 3)
triangles = np.asarray(self.mesh.triangles) # 形状: (F, 3)
# 向量化计算法线
# 获取所有三角形的顶点
v0 = vertices[triangles[:, 0]] # 形状: (F, 3)
v1 = vertices[triangles[:, 1]] # 形状: (F, 3)
v2 = vertices[triangles[:, 2]] # 形状: (F, 3)
# 计算边向量
edge1 = v1 - v0
edge2 = v2 - v0
# 向量化叉积
# np.cross支持批量计算
normals = np.cross(edge1, edge2)
# 计算法线长度
norms = np.linalg.norm(normals, axis=1, keepdims=True)
# 避免除零
norms[norms < 1e-6] = 1.0
# 归一化
normals = normals / norms
# 将退化三角形的法线设为默认值
mask = norms[:, 0] < 1e-6
if np.any(mask):
normals[mask] = np.array([0.0, 0.0, 1.0])
# 转换为GPU张量
self.face_normals_tensor = torch.tensor(normals, device=self.device, dtype=torch.float32)
# 2. 计算摄像机方向(从面片中心指向摄像机)
# 获取面片顶点坐标
v0_pos = self.vertices_tensor[v0_indices]
v1_pos = self.vertices_tensor[v1_indices]
v2_pos = self.vertices_tensor[v2_indices]
# 计算面片中心
face_centers = (v0_pos + v1_pos + v2_pos) / 3.0
# 计算摄像机方向向量
camera_pos = torch.tensor(eye, device=self.device, dtype=torch.float32)
if len(camera_pos.shape) == 1:
camera_pos = camera_pos.unsqueeze(0) # 从(3)变为(1,3)
# 方向:从面片中心指向摄像机
view_dirs = camera_pos - face_centers
view_dirs = view_dirs / torch.norm(view_dirs, dim=1, keepdim=True)
# 3. 计算法线与摄像机方向的夹角
face_normals = self.face_normals_tensor
# 归一化法线
face_normals = face_normals / torch.norm(face_normals, dim=1, keepdim=True)
# 计算点积(余弦值)
cos_angles = torch.sum(face_normals * view_dirs, dim=1)
# 计算角度(弧度转角度)
angles_deg = torch.acos(torch.clamp(cos_angles, -1.0, 1.0)) * 180.0 / torch.pi
# 4. 创建法线可见性掩码(夹角 ≤ 45度)
normal_visible_mask = angles_deg <= 40.0
# 5. 结合遮挡可见性和法线可见性
face_normal_visible = face_visible & normal_visible_mask
# ============ 法线夹角过滤结束 ============
# 使用与CPU版本相同的后续处理 # 使用与CPU版本相同的后续处理
shrunk_visibility = self._shrink_face_visibility(face_visible.cpu().numpy(), 6) 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(), 0)
shrunk_visibility2 = self._shrink_face_visibility(face_visible.cpu().numpy(), 50) shrunk_visibility2 = self._shrink_face_visibility(face_visible.cpu().numpy(), 0)
shrunk_visibility3 = self._shrink_face_visibility(face_visible.cpu().numpy(), 100)
expanded_edge = expanded_visibility & ~shrunk_visibility2 expanded_edge = expanded_visibility & ~shrunk_visibility2
delete_edge = face_visible.cpu().numpy() & ~shrunk_visibility delete_edge = face_visible.cpu().numpy() & ~shrunk_visibility
delete_edge2 = face_visible.cpu().numpy() & ~shrunk_visibility3
return shrunk_visibility, expanded_edge, delete_edge return shrunk_visibility, expanded_edge, delete_edge, delete_edge2, face_normal_visible
""" """
def _gen_depth_image_gpu(self, cam_data, render): def _gen_depth_image_gpu(self, cam_data, render):
@@ -1388,6 +1466,8 @@ class ModelProcessor:
visible_faces_dict = {} visible_faces_dict = {}
edge_faces_dict = {} edge_faces_dict = {}
delete_edge_faces_dict = {} delete_edge_faces_dict = {}
delete_edge_faces_dict2 = {}
face_normal_visible_dict = {}
total_start = time.time() total_start = time.time()
@@ -1413,13 +1493,15 @@ class ModelProcessor:
# continue # continue
start_time = time.time() start_time = time.time()
face_visibility, face_edge, face_delete_edge = self._flag_model_gpu(camera_data) face_visibility, face_edge, face_delete_edge, face_delete_edge2, face_normal_visible = self._flag_model_gpu(camera_data)
processing_time = time.time() - start_time processing_time = time.time() - start_time
visible_faces = np.where(face_visibility)[0].tolist() visible_faces = np.where(face_visibility)[0].tolist()
visible_faces_dict[img_name] = visible_faces visible_faces_dict[img_name] = visible_faces
edge_faces_dict[img_name] = np.where(face_edge)[0].tolist() edge_faces_dict[img_name] = np.where(face_edge)[0].tolist()
delete_edge_faces_dict[img_name] = np.where(face_delete_edge)[0].tolist() delete_edge_faces_dict[img_name] = np.where(face_delete_edge)[0].tolist()
delete_edge_faces_dict2[img_name] = np.where(face_delete_edge2)[0].tolist()
face_normal_visible_dict[img_name] = np.where(face_normal_visible.cpu().numpy())[0].tolist()
print(f"图像 {img_name} 处理完成,耗时: {processing_time:.2f}秒,可见面数量{len(visible_faces)}") print(f"图像 {img_name} 处理完成,耗时: {processing_time:.2f}秒,可见面数量{len(visible_faces)}")
@@ -1427,12 +1509,14 @@ class ModelProcessor:
print(f"所有图像处理完成,总耗时: {total_time:.2f}秒") print(f"所有图像处理完成,总耗时: {total_time:.2f}秒")
print(f"平均每张图像耗时: {total_time/len(images):.2f}秒") print(f"平均每张图像耗时: {total_time/len(images):.2f}秒")
self.save_occlusion_data(visible_faces_dict, edge_faces_dict, delete_edge_faces_dict, self.asset_dir) self.save_occlusion_data(visible_faces_dict, edge_faces_dict, delete_edge_faces_dict, delete_edge_faces_dict2, face_normal_visible_dict, self.asset_dir)
return { return {
"result1": visible_faces_dict, "result1": visible_faces_dict,
"result2": edge_faces_dict, "result2": edge_faces_dict,
"result3": delete_edge_faces_dict "result3": delete_edge_faces_dict,
"result4": delete_edge_faces_dict2,
"result5": face_normal_visible_dict
} }
#""" #"""
@@ -1926,64 +2010,6 @@ class ModelProcessor:
depth = render.render_to_depth_image(z_in_view_space=True) depth = render.render_to_depth_image(z_in_view_space=True)
return np.asarray(depth) return np.asarray(depth)
def sort_vertices(vertices_original):
return sorted(
(v for v in vertices_original),
key=lambda v: (v.co.x, v.co.y, v.co.z)
)
def _flag_model(self, camera_data, face_points):
"""标记可见顶点"""
vertex_visible = []
vertex_occlusion = []
depth_images = []
render = o3d.visualization.rendering.OffscreenRenderer(camera_data['width'], camera_data['height'])
material = o3d.visualization.rendering.MaterialRecord()
render.scene.add_geometry("mesh", self.mesh, material)
# 生成深度图
depth_image = self._gen_depth_image(camera_data, render)
# 计算可见性
R = self.qvec2rotmat(camera_data['qvec']).T
eye = -R @ camera_data['tvec']
# eye = camera_data['tvec']
# final_visible_list, final_occlusion_list, final_vertex_difference_list = self._compute_vertex_in_frustum(
final_visible_list, final_occlusion_list = self._compute_vertex_in_frustum(
camera_data['fx'], camera_data['fy'],
camera_data['cx'], camera_data['cy'],
R, eye,
camera_data['height'], camera_data['width'],
depth_image,camera_data['qvec'], camera_data['tvec']
)
print("_flag_model", len(final_occlusion_list), len(self.mesh.vertices), len(self.mesh.vertex_colors))
# 获取三角形面片数组
triangles = np.asarray(self.mesh.triangles)
face_visible_bitmap = np.zeros(len(triangles), dtype=bool)
# 遍历所有面片
for face_idx, face in enumerate(triangles):
v0, v1, v2 = face
face_visible_bitmap[face_idx] = any([ # any all
final_visible_list[v0],
final_visible_list[v1],
final_visible_list[v2]
])
shrunk_visibility = self._shrink_face_visibility(face_visible_bitmap, 6) # 6 10
expanded_visibility = self._expand_face_visibility(face_visible_bitmap, 30)
shrunk_visibility2 = self._shrink_face_visibility(face_visible_bitmap, 50)
expanded_edge = expanded_visibility & ~shrunk_visibility2
delete_edge = face_visible_bitmap & ~shrunk_visibility
return shrunk_visibility, expanded_edge, delete_edge
def _flag_contour(self, camera_data, face_points): def _flag_contour(self, camera_data, face_points):
"""标记可见顶点""" """标记可见顶点"""
vertex_visible = [] vertex_visible = []
@@ -2073,97 +2099,11 @@ class ModelProcessor:
face_visible_bitmap = np.ones(len(triangles), dtype=bool) # 临时填充 face_visible_bitmap = np.ones(len(triangles), dtype=bool) # 临时填充
return face_visible_bitmap, face_edge return face_visible_bitmap, face_edge
"""
def _mask_face_occlusion(self):
# 读取相机数据
cameras = read_cameras_text(os.path.join(self.pose_path, "cameras.txt"))
images = read_images_text(os.path.join(self.pose_path, "images.txt"))
# cameras = read_cameras_text(os.path.join(self.pose_path, "backup_cameras.txt"))
# images = read_images_text(os.path.join(self.pose_path, "backup_images.txt"))
face_points_sorted_path = os.path.join(self.pose_path, "face_points_sorted.txt")
print("face_points_sorted_path=", face_points_sorted_path)
#face_points = read_int_text(face_points_sorted_path)
face_points = read_indices_from_file(face_points_sorted_path)
# face_points = {}
camera_data = {}
for img in images.values():
if self.mask_image == img.name[:-4]:
camera = cameras[img.camera_id]
camera_data = {
"qvec": img.qvec,
"tvec": img.tvec,
"fx": camera.params[0],
"fy": camera.params[1],
"cx": camera.params[2],
"cy": camera.params[3],
"width": camera.width,
"height": camera.height,
"name": img.name[:-4]
}
# print(face_points)
self._flag_model(camera_data, face_points)
"""
def _mask_occlusion(self):
# 读取相机数据
cameras = read_cameras_text(os.path.join(self.pose_path, "cameras.txt"))
images = read_images_text(os.path.join(self.pose_path, "images.txt"))
camera_data = {}
countour_faces_dict = {}
visible_faces_dict = {}
edge_faces_dict = {}
delete_edge_faces_dict = {}
total_start = time.time()
n = 0
for img in images.values():
camera = cameras[img.camera_id]
camera_data = {
"qvec": img.qvec,
"tvec": img.tvec,
"fx": camera.params[0],
"fy": camera.params[1],
"cx": camera.params[2],
"cy": camera.params[3],
"width": camera.width,
"height": camera.height,
"name": img.name[:-4]
}
img_name = img.name[:-4]
# if (img_name!="73_8" and img_name!="52_8" and img_name!="62_8"):
# if (img_name!="52_8" and img_name!="62_8"):
# if (img_name!="52_8"):
# continue
start_time = time.time()
face_visibility, face_edge, face_delete_edge = self._flag_model(camera_data, None)
processing_time = time.time() - start_time
visible_faces = np.where(face_visibility)[0].tolist()
visible_faces_dict[img.name[:-4]] = visible_faces
edge_faces_dict[img.name[:-4]] = np.where(face_edge)[0].tolist()
delete_edge_faces_dict[img.name[:-4]] = np.where(face_delete_edge)[0].tolist()
n += 1
print(f"图像={img_name},耗时={processing_time:.2f}秒,可见面数={len(visible_faces)}")
total_time = time.time() - total_start
print(f"所有图像处理完成,总耗时: {total_time:.2f}秒")
print(f"平均每张图像耗时: {total_time/len(images):.2f}秒")
self.save_occlusion_data(visible_faces_dict, edge_faces_dict, delete_edge_faces_dict, self.asset_dir)
return {"result1": visible_faces_dict, "result2": edge_faces_dict, "result3": delete_edge_faces_dict}
def save_occlusion_data(self, result1: Dict[str, List[int]], def save_occlusion_data(self, result1: Dict[str, List[int]],
result2: Dict[str, List[int]], result2: Dict[str, List[int]],
result3: Dict[str, List[int]], result3: Dict[str, List[int]],
result4: Dict[str, List[int]],
result5: Dict[str, List[int]],
base_path: str) -> None: base_path: str) -> None:
""" """
保存遮挡数据到文件 保存遮挡数据到文件
@@ -2175,6 +2115,8 @@ class ModelProcessor:
base_path: 基础文件路径 base_path: 基础文件路径
""" """
os.makedirs(base_path, exist_ok = True)
print(f"save_occlusion_data {base_path}, {len(result1)}, {len(result2)}, {len(result3)}") print(f"save_occlusion_data {base_path}, {len(result1)}, {len(result2)}, {len(result3)}")
# 处理返回的可见面字典 - 转换为图像名到面编号集合的映射 # 处理返回的可见面字典 - 转换为图像名到面编号集合的映射
@@ -2197,9 +2139,19 @@ class ModelProcessor:
for image_name, face_list in result3.items(): for image_name, face_list in result3.items():
delete_edge_faces_map[image_name] = set(face_list) delete_edge_faces_map[image_name] = set(face_list)
delete_edge_faces_map2: Dict[str, Set[int]] = {}
for image_name, face_list in result4.items():
delete_edge_faces_map2[image_name] = set(face_list)
face_normal_visible_map: Dict[str, Set[int]] = {}
for image_name, face_list in result5.items():
face_normal_visible_map[image_name] = set(face_list)
# 保存 visible_faces_map # 保存 visible_faces_map
try: try:
with open(base_path + "/_visible_faces_map.txt", "w", encoding='utf-8') as map_file: file_name = "_visible_faces_map.txt"
file_path = Path(base_path) / file_name
with open(file_path, "w", encoding='utf-8') as map_file:
for image_name, face_set in visible_faces_map.items(): for image_name, face_set in visible_faces_map.items():
# 写入图像名称和所有面ID,用空格分隔 # 写入图像名称和所有面ID,用空格分隔
line = image_name + " " + " ".join(str(face) for face in face_set) + "\n" line = image_name + " " + " ".join(str(face) for face in face_set) + "\n"
@@ -2209,7 +2161,9 @@ class ModelProcessor:
# 保存 face_visible_relative # 保存 face_visible_relative
try: try:
with open(base_path + "/_face_visible_relative.txt", "w", encoding='utf-8') as relative_file: file_name = "_face_visible_relative.txt"
file_path = Path(base_path) / file_name
with open(file_path, "w", encoding='utf-8') as relative_file:
for face in face_visible_relative: for face in face_visible_relative:
relative_file.write(str(face) + "\n") relative_file.write(str(face) + "\n")
except IOError as e: except IOError as e:
@@ -2217,7 +2171,9 @@ class ModelProcessor:
# 保存 edge_faces_map # 保存 edge_faces_map
try: try:
with open(base_path + "/_edge_faces_map.txt", "w", encoding='utf-8') as map_file2: file_name = "_edge_faces_map.txt"
file_path = Path(base_path) / file_name
with open(file_path, "w", encoding='utf-8') as map_file2:
for image_name, face_set in edge_faces_map.items(): for image_name, face_set in edge_faces_map.items():
line = image_name + " " + " ".join(str(face) for face in face_set) + "\n" line = image_name + " " + " ".join(str(face) for face in face_set) + "\n"
map_file2.write(line) map_file2.write(line)
@@ -2226,13 +2182,37 @@ class ModelProcessor:
# 保存 delete_edge_faces_map # 保存 delete_edge_faces_map
try: try:
with open(base_path + "/_delete_edge_faces_map.txt", "w", encoding='utf-8') as map_file3: file_name = "_delete_edge_faces_map.txt"
file_path = Path(base_path) / file_name
with open(file_path, "w", encoding='utf-8') as map_file3:
for image_name, face_set in delete_edge_faces_map.items(): for image_name, face_set in delete_edge_faces_map.items():
line = image_name + " " + " ".join(str(face) for face in face_set) + "\n" line = image_name + " " + " ".join(str(face) for face in face_set) + "\n"
map_file3.write(line) map_file3.write(line)
except IOError as e: except IOError as e:
print(f"Error writing delete_edge_faces_map file: {e}") print(f"Error writing delete_edge_faces_map file: {e}")
# 保存 delete_edge_faces_map2
try:
file_name = "_delete_edge_faces_map2.txt"
file_path = Path(base_path) / file_name
with open(file_path, "w", encoding='utf-8') as map_file4:
for image_name, face_set in delete_edge_faces_map2.items():
line = image_name + " " + " ".join(str(face) for face in face_set) + "\n"
map_file4.write(line)
except IOError as e:
print(f"Error writing delete_edge_faces_map2 file: {e}")
# 保存 face_normal_visible_map
try:
file_name = "_face_normal_visible_map.txt"
file_path = Path(base_path) / file_name
with open(file_path, "w", encoding='utf-8') as map_file5:
for image_name, face_set in face_normal_visible_map.items():
line = image_name + " " + " ".join(str(face) for face in face_set) + "\n"
map_file5.write(line)
except IOError as e:
print(f"Error writing _face_normal_visible_map file: {e}")
def process(self): def process(self):
print("process") print("process")