diff --git a/libs/MVS/Scene.h b/libs/MVS/Scene.h index d669eb4..2f67a26 100644 --- a/libs/MVS/Scene.h +++ b/libs/MVS/Scene.h @@ -171,6 +171,7 @@ public: 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 = ""); + std::string runPython(const std::string& command); bool is_face_visible(const std::string& image_name, int face_index); bool is_face_visible_relative(int face_index); bool is_face_edge(const std::string& image_name, int face_index); diff --git a/libs/MVS/SceneTexture.cpp b/libs/MVS/SceneTexture.cpp index 3984010..abd5aa9 100644 --- a/libs/MVS/SceneTexture.cpp +++ b/libs/MVS/SceneTexture.cpp @@ -37,12 +37,13 @@ #include #include -#include -#include +// #include +// #include #include "ConfigEnv.h" #include "cuda/MeshTextureCUDA.h" +#include -namespace py = pybind11; +// namespace py = pybind11; using namespace MVS; @@ -72,8 +73,6 @@ using namespace MVS; #define TEXOPT_INFERENCE_TRWS 2 #define TEXOPT_INFERENCE TEXOPT_INFERENCE_LBP #define MASK_FACE_OCCLUSION -// #define DISPLAY_DEMO -#define CACHE_MASK #define USE_CUDA // inference algorithm @@ -9590,40 +9589,6 @@ bool Scene::TextureMesh(unsigned nResolutionLevel, unsigned nMinResolution, unsi printf("id=%s\n", id.c_str()); #ifdef MASK_FACE_OCCLUSION - - /* - // 创建遮挡数据 - std::cout << "inputFileName: " << inputFileName << std::endl; - std::cout << "meshFileName: " << meshFileName << std::endl; - try { - py::scoped_interpreter guard{}; // 自动管理解释器生命周期 - py::module_ sys = py::module_::import("sys"); - // 设置命令行参数(模拟Python的argparse) - py::list argv; - argv.append("program_name"); - argv.append("--sparse_dir"); - argv.append(static_cast(inputFileName)); - argv.append("--mesh_path"); - argv.append(static_cast(meshFileName)); - // argv.append("--mask_image"); - // argv.append("63_2"); - sys.attr("argv") = argv; - - py::print(sys.attr("version")); // 打印Python版本 - sys.attr("path").attr("append")("/root/miniconda3/lib/python3.10/site-packages"); - sys.attr("path").attr("append")("/root/code/openMVS/libs/MVS"); - // 调用自定义函数 - py::module_ mymodule = py::module_::import("mask_face_occlusion"); - - // 获取ModelProcessor类 - py::object ModelProcessor = mymodule.attr("ModelProcessor"); - - py::object processor = ModelProcessor(); - py::dict result = processor.attr("process")().cast(); - - printf("result size=%d\n", result.size()); - */ - std::string basePath = ""; size_t lastSlash = baseFileName.find_last_of('/'); size_t secondLastSlash = baseFileName.find_last_of('/', lastSlash - 1); @@ -9633,118 +9598,10 @@ bool Scene::TextureMesh(unsigned nResolutionLevel, unsigned nMinResolution, unsi // printf("basePath=%s\n", basePath.c_str()); -#ifdef CACHE_MASK if (!LoadVisibleFacesData(visible_faces_map, face_visible_relative, edge_faces_map, delete_edge_faces_map, basePath)) -#endif - { - // 创建遮挡数据 - try { - py::scoped_interpreter guard{}; // 自动管理解释器生命周期 - py::module_ sys = py::module_::import("sys"); - - // 设置命令行参数(模拟Python的argparse) - py::list argv; - argv.append("program_name"); - argv.append("--id"); - // argv.append("274658"); // 274658 7613212046 - argv.append(id); - argv.append("--base_path"); - argv.append(basePath.c_str()); - argv.append("--mesh_path"); - argv.append(meshFileName.c_str()); - argv.append("--sparse_dir"); - argv.append(inputFileName.c_str()); - sys.attr("argv") = argv; - - py::print(sys.attr("version")); // 打印Python版本 - - printf("PYTHON_PATH=%s\n", PYTHON_PATH.c_str()); - printf("MVS_PATH=%s\n", MVS_PATH.c_str()); - // sys.attr("path").attr("append")("/home/algo/.conda/envs/py310_pyt210/lib/python3.10/site-packages"); - // sys.attr("path").attr("append")("/home/algo/Documents/openMVS/openMVS/libs/MVS"); - sys.attr("path").attr("append")(PYTHON_PATH.c_str()); - sys.attr("path").attr("append")(MVS_PATH.c_str()); - // 调用自定义函数 - py::module_ mymodule = py::module_::import("mask_face_occlusion"); - - // 获取ModelProcessor类 - py::object ModelProcessor = mymodule.attr("ModelProcessor"); - - py::object processor = ModelProcessor(); - py::dict result = processor.attr("process")().cast(); - - py::dict dict1; - py::dict dict2; - if (result.contains("result1") && result.contains("result2")) { - dict1 = result["result1"].cast(); - dict2 = result["result2"].cast(); - } - py::dict dict3; - if (result.contains("result3")) { - dict3 = result["result3"].cast(); - } - - // printf("dict1 size=%d, dict2 size=%d, dict3 size=%d\n", dict1.size(), dict2.size(), dict3.size()); - - // 处理返回的可见面字典 - for (auto item : dict1) { - std::string image_name = item.first.cast(); - // printf("dict1 mask image name=%s\n", image_name.c_str()); - py::list visible_faces = item.second.cast(); - - std::unordered_set face_set; - for (auto face : visible_faces) { - face_set.insert(face.cast()); - } - visible_faces_map[image_name] = face_set; - } - - for (const auto& entry : visible_faces_map) - { - face_visible_relative.insert(entry.second.begin(), entry.second.end()); - } - - for (auto item : dict2) { - std::string image_name = item.first.cast(); - // printf("dict2 mask image name=%s\n", image_name.c_str()); - py::list edge_faces = item.second.cast(); - - std::unordered_set face_set; - for (auto face : edge_faces) { - face_set.insert(face.cast()); - } - edge_faces_map[image_name] = face_set; - } - - for (auto item : dict3) { - std::string image_name = item.first.cast(); - // printf("dict3 mask image name=%s\n", image_name.c_str()); - py::list delete_edge_faces = item.second.cast(); - - std::unordered_set face_set; - for (auto face : delete_edge_faces) { - face_set.insert(face.cast()); - } - delete_edge_faces_map[image_name] = face_set; - } - -#ifdef CACHE_MASK - SaveVisibleFacesData(visible_faces_map, face_visible_relative, edge_faces_map, delete_edge_faces_map, basePath); -#endif - } - catch (const py::error_already_set &e) { - std::cerr << "Python error: " << e.what() << std::endl; - // 获取详细的Python错误信息 - PyErr_Print(); - return 1; - } - catch (const std::exception &e) { - std::cerr << "C++ error: " << e.what() << std::endl; - return 1; - } + printf("LoadVisibleFacesData error\n"); } - #endif // assign the best view to each face @@ -9811,52 +9668,23 @@ bool Scene::TextureMesh(unsigned nResolutionLevel, unsigned nMinResolution, unsi TD_TIMER_STARTD(); texture.GenerateTexture(bGlobalSeamLeveling, bLocalSeamLeveling, nTextureSizeMultiple, nRectPackingHeuristic, colEmpty, fSharpnessWeight, maxTextureSize, baseFileName, bOriginFaceview); DEBUG_EXTRA("Generating texture atlas and image completed: %u patches, %u image size, %u textures (%s)", texture.texturePatches.size(), mesh.texturesDiffuse[0].width(), mesh.texturesDiffuse.size(), TD_TIMER_GET_FMT().c_str()); - } - #ifdef DISPLAY_DEMO - try { - py::scoped_interpreter guard{}; // 自动管理解释器生命周期 - py::module_ sys = py::module_::import("sys"); - - // 设置命令行参数(模拟Python的argparse) - py::list argv; - argv.append("program_name"); - argv.append("--id"); - argv.append(id); - argv.append("--mask"); - #ifdef MASK_FACE_OCCLUSION - argv.append(1); - #else - argv.append(0); - #endif - sys.attr("argv") = argv; - - py::print(sys.attr("version")); // 打印Python版本 - sys.attr("path").attr("append")("/home/algo/.conda/envs/py310_pyt210/lib/python3.10/site-packages"); - sys.attr("path").attr("append")("/home/algo/Documents/openMVS/openMVS/libs/MVS"); - // 调用自定义函数 - py::module_ mymodule = py::module_::import("display_demo"); - - // 获取ModelProcessor类 - py::object DisplayProcessor = mymodule.attr("DisplayProcessor"); - - py::object processor = DisplayProcessor(); - processor.attr("load_and_show")(); - } - catch (const py::error_already_set &e) { - std::cerr << "Python error: " << e.what() << std::endl; - // 获取详细的Python错误信息 - PyErr_Print(); - return 1; - } - catch (const std::exception &e) { - std::cerr << "C++ error: " << e.what() << std::endl; - return 1; - } -#endif + } return true; } // TextureMesh +std::string Scene::runPython(const std::string& command) { + std::array buffer{}; + std::string result; + std::unique_ptr pipe(popen(command.c_str(), "r"), pclose); + if (!pipe) throw std::runtime_error("popen() failed!"); + + while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { + result += buffer.data(); + } + return result; +} + bool Scene::is_face_visible(const std::string& image_name, int face_index) { #ifndef MASK_FACE_OCCLUSION diff --git a/libs/MVS/mask_face_occlusion.py b/libs/MVS/mask_face_occlusion.py index dbd866d..2044223 100755 --- a/libs/MVS/mask_face_occlusion.py +++ b/libs/MVS/mask_face_occlusion.py @@ -14,6 +14,9 @@ import torch import torch.nn.functional as F from torch.utils.dlpack import to_dlpack, from_dlpack +import os +from typing import Dict, List, Set + class ModelProcessor: def __init__(self): @@ -455,6 +458,8 @@ class ModelProcessor: 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, @@ -1183,8 +1188,82 @@ class ModelProcessor: 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]], + result2: Dict[str, List[int]], + result3: Dict[str, List[int]], + base_path: str) -> None: + """ + 保存遮挡数据到文件 + + Args: + result1: 可见面字典,包含图像名称和对应的可见面列表 + result2: 边面字典,包含图像名称和对应的边面列表 + result3: 删除边面字典,包含图像名称和对应的删除边面列表 + base_path: 基础文件路径 + """ + + print(f"save_occlusion_data {base_path}, {len(result1)}, {len(result2)}, {len(result3)}") + + # 处理返回的可见面字典 - 转换为图像名到面编号集合的映射 + visible_faces_map: Dict[str, Set[int]] = {} + for image_name, face_list in result1.items(): + visible_faces_map[image_name] = set(face_list) + + # 计算所有可见面的并集 + face_visible_relative: Set[int] = set() + for face_set in visible_faces_map.values(): + face_visible_relative.update(face_set) + + # 处理边面字典 + edge_faces_map: Dict[str, Set[int]] = {} + for image_name, face_list in result2.items(): + edge_faces_map[image_name] = set(face_list) + + # 处理删除边面字典 + delete_edge_faces_map: Dict[str, Set[int]] = {} + for image_name, face_list in result3.items(): + delete_edge_faces_map[image_name] = set(face_list) + + # 保存 visible_faces_map + try: + with open(base_path + "_visible_faces_map.txt", "w", encoding='utf-8') as map_file: + for image_name, face_set in visible_faces_map.items(): + # 写入图像名称和所有面ID,用空格分隔 + line = image_name + " " + " ".join(str(face) for face in face_set) + "\n" + map_file.write(line) + except IOError as e: + print(f"Error writing visible_faces_map file: {e}") + + # 保存 face_visible_relative + try: + with open(base_path + "_face_visible_relative.txt", "w", encoding='utf-8') as relative_file: + for face in face_visible_relative: + relative_file.write(str(face) + "\n") + except IOError as e: + print(f"Error writing face_visible_relative file: {e}") + + # 保存 edge_faces_map + try: + with open(base_path + "_edge_faces_map.txt", "w", encoding='utf-8') as map_file2: + for image_name, face_set in edge_faces_map.items(): + line = image_name + " " + " ".join(str(face) for face in face_set) + "\n" + map_file2.write(line) + except IOError as e: + print(f"Error writing edge_faces_map file: {e}") + + # 保存 delete_edge_faces_map + try: + with open(base_path + "_delete_edge_faces_map.txt", "w", encoding='utf-8') as map_file3: + for image_name, face_set in delete_edge_faces_map.items(): + line = image_name + " " + " ".join(str(face) for face in face_set) + "\n" + map_file3.write(line) + except IOError as e: + print(f"Error writing delete_edge_faces_map file: {e}") + def process(self): print("process")