最近搞相机重定位的项目,大多都是在linux系统上写的,使用windows配环境就非常多问题
项目地址:GitHub - jinlinyi/SparsePlanes: [ICCV 2021 (oral)] Planar Surface Reconstruction from Sparse Views
虽然不是最新的研究成果,效果还是不错的,基于纯卷积RCNN的方法。
项目在linux下运行正常,主要是想在windows下使用这个代码,其中有个
KMSolver.cpython-37m-x86_64-linux-gnu.so
的库是预编译好的,仅支持特定的python3.7和linux环境,所以这里想在windows11下用pybind11编译KMSolver用其他版本的python调用C++代码
编译工具:
cmake 3.29.0
vs 2019
pybind11:GitHub - pybind/pybind11: Seamless operability between C++11 and Python
准备代码:
代码地址:GitHub - RoboJackets/hungarian: C++ Implementation of the hungarian algorithm
下载好后需要对代码做一些修改:
新建一个 KMSolver.cpp
#include "../include/pybind11/pybind11.h"
#include "../include/pybind11/eigen.h"
#include "../include/pybind11/stl.h"
#include <iostream>
#if defined(_MSC_VER)
# pragma warning(disable: 4996) // C4996: std::unary_negation is deprecated
#endif
#include <vector>
#include "hungarian.hpp"
namespace py = pybind11;
Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic> solve(Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic> costMatrix, int threshold) {
int num_rows = costMatrix.rows();
int num_cols = costMatrix.cols();
// create a input matrix to km
// note cost above threshold are considered invalid match right away
// and they are treated to be "equally invalid", remaining the default value threshold+1
// to avoid affect matching with the valid costs
Hungarian::Matrix cost2DVec (num_rows, std::vector<int>(num_cols, threshold+1));
for (int i = 0; i < num_rows; i++) {
for (int j = 0; j < num_cols; j++) {
if (costMatrix(i,j) <= threshold) {
cost2DVec[i][j] = costMatrix(i,j);
}
}
}
// solve KM
Hungarian::Result res2DVec = Hungarian::Solve(cost2DVec, Hungarian::MODE_MINIMIZE_COST);
if (!res2DVec.success) {
std::cout << "Matching not successful. Return input matrix itself." << std::endl;
return costMatrix;
}
// convert 2d std vector to eigen matrix
Eigen::Matrix<int, Eigen::Dynamic, Eigen::Dynamic> matchMatrix (num_rows, num_cols);
for (int i = 0; i < num_rows; i++) {
for (int j = 0; j < num_cols; j++) {
if (res2DVec.assignment[i][j] == 1 && cost2DVec[i][j] <= threshold) {
// only accept a match if
// KM agorithm assigns a match and
// the match can be valid in the first place (cost <= threshold)
matchMatrix(i,j) = 1;
} else {
matchMatrix(i,j) = 0;
}
}
}
return matchMatrix;
}
namespace py = pybind11;
PYBIND11_MODULE(KMSolver, m) {
m.def("solve", &solve, py::arg("cost_matrix"), py::arg("threshold"));
}
编辑CMakeLists.txt
cmake_minimum_required(VERSION 3.0.0)
project("Hungarian Algorithm")
set(CMAKE_CXX_STANDARD 11)
FIND_PACKAGE(Eigen3 3.1.0 REQUIRED)
include_directories( ${EIGEN3_INCLUDE_DIRS} )
add_library(hungarian hungarian.cpp hungarian.hpp KMSolver.cpp)
add_executable(test_cases test.cpp) # test.cpp怎么写的不重要
target_link_libraries(test_cases KMSolver)
还需要准备eigen库,一个用于矩阵运算的库,用之前最好用cmake去build一下,以免找不到
GitHub - libigl/eigen: This is a mirror of the latest stable version of Eigen.
在当前路径下创建一个build目录
打开cmake路径和编译器配置好后点生成,之后在build路径下找到Hungarian Algorithm.sln,并双击打开。
点开Hungarian的属性,在常规中做如下设置
更改扩展名
添加include和库路径
包含目录:
G:\DLproject\py_build_tool\pybind11
G:\DLproject\py_build_tool\pybind11\include # pybind11的路径
E:\xxx\xxx\anaconda3\envs\sparseplane_py39\include # 根据自己的python环境来确定
G:\DLproject\SparsePlanes\km\eigen # 这里将eigen放在编译时的根路径下
库目录:
E:\xxx\xxx\anaconda3\envs\sparseplane_py39\libs
增加链接器的附加依赖
这个依赖主要根据库目录中的pythonlib来确定
之后直接生成
一般按上面的步骤来不会报错,在build/release下能看到对应的pyd文件
将该文件复制到SparsePlanes\sparsePlane下,替换之前的.so文件
sparsePlane的windows环境配置好后就能直接在windows上运行了
上面的报错是pytorch3d的问题,具体问题还得折腾一下
代码运行完会在tools/debug下保存处理好的文件,包括mask、匹配的结果、渲染好的3d文件以及对应的贴图。obj文件可以用3D建图工具打开,比如blender,这里因为pytorch3d有问题,3d相关的文件没能保存下来。