【发布时间】:2022-01-12 08:05:29
【问题描述】:
我是 C++ 和 python 的初学者。我已经在Visual Studio 2019中安装了boost-1.78.0、OPENCV-4.5.5并添加了一个新的动态链接库(DLL)项目,然后成功构建了sln并生成了testSqaure.dll。
我的代码如下:
#define BOOST_PYTHON_STATIC_LIB
#include "pch.h"
#include<boost/python.hpp>
#include<boost/python/numpy.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<cmath>
#include<algorithm>
using boost::python::list;
using boost::python::numpy::ndarray;
using boost::python::object;
using boost::python::extract;
using std::vector;
using std::array;
using std::sqrt;
using std::min;
using cv::Point2f;
using cv::Point;
using cv::pointPolygonTest;
vector<double> ndarray2vec(const ndarray& arr)
{
int input_size = static_cast<int>(arr.shape(0));
double* input_ptr = reinterpret_cast<double*>(arr.get_data());
vector<double> v_arr(input_size);
for (int i = 0; i < input_size; ++i)
{
v_arr[i] = *(input_ptr + i);
}
return v_arr;
}
bool two_line_segment_test(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
{
if (((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)) == 0) return false;
const double px = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4));
const double py = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4));
if ((((x1 <= px) && (px <= x2)) || ((x2 <= px) && (px <= x1))) && (((x3 <= px) && (px <= x4)) || ((x4 <= px) && (px <= x3))) && (((y1 <= py) && (py <= y2)) || ((y2 <= py) && (py <= y1))) && (((y3 <= py) && (py <= y4)) || ((y4 <= py) && (py <= y3))))
{
return true;
}
else return false;
}
object two_triangle_test(ndarray& tri1_side1, ndarray& tri1_side2, ndarray& tri1_side3, ndarray& tri2_side1, ndarray& tri2_side2, ndarray& tri2_side3)
{
vector<double> v_tri1_side1 = ndarray2vec(tri1_side1),
v_tri1_side2 = ndarray2vec(tri1_side2),
v_tri1_side3 = ndarray2vec(tri1_side3),
v_tri2_side1 = ndarray2vec(tri2_side1),
v_tri2_side2 = ndarray2vec(tri2_side2),
v_tri2_side3 = ndarray2vec(tri2_side3);
array<vector<double>, 3> v_tri1_sides = { v_tri1_side1, v_tri1_side2, v_tri1_side3 };
array<vector<double>, 3> v_tri2_sides = { v_tri2_side1, v_tri2_side2, v_tri2_side3 };
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
if (two_line_segment_test(v_tri1_sides[i][0], v_tri1_sides[i][1], v_tri1_sides[i][2], v_tri1_sides[i][3], v_tri2_sides[j][0], v_tri2_sides[j][1], v_tri2_sides[j][2], v_tri2_sides[j][3]))
{
return object(true);
}
}
}
vector<Point2f> tri1(3);
tri1[0] = Point(v_tri1_side1[0], v_tri1_side1[1]);
tri1[1] = Point(v_tri1_side1[2], v_tri1_side1[3]);
tri1[2] = Point(v_tri1_side2[2], v_tri1_side2[3]);
for (auto& side : v_tri2_sides)
{
const int retval = static_cast<int>(pointPolygonTest(tri1, Point(side[0], side[1]), false));
if (retval == 1 || retval == 0) return object(true);
}
vector<Point2f> tri2(3);
tri2[0] = Point(v_tri2_side1[0], v_tri2_side1[1]);
tri2[1] = Point(v_tri2_side1[2], v_tri2_side1[3]);
tri2[2] = Point(v_tri2_side2[2], v_tri2_side2[3]);
for (auto& side : v_tri1_sides)
{
const int retval = static_cast<int>(pointPolygonTest(tri2, Point(side[0], side[1]), false));
if (retval == 1 || retval == 0) return object(true);
}
return object(false);
}
array<double, 2> get_foot_point(const vector<double>& v_point, const vector<double>& v_line_p1, const vector<double>& v_line_p2)
{
const double k = -((v_line_p1[0] - v_point[0]) * (v_line_p2[0] - v_line_p1[0]) + (v_line_p1[1] - v_point[0]) * (v_line_p2[1] - v_line_p1[1]) + 0) / ((v_line_p2[0] - v_line_p1[0]) * (v_line_p2[0] - v_line_p1[0]) + (v_line_p2[1] - v_line_p1[1]) * (v_line_p2[1] - v_line_p1[1]) + 0) * 1.0;
const double xn = k * (v_line_p2[0] - v_line_p1[0]) + v_line_p1[0];
const double yn = k * (v_line_p2[1] - v_line_p1[1]) + v_line_p1[1];
return array<double, 2>{xn, yn};
}
double get_dis_point2line(const vector<double>& v_point, const vector<double>& v_line_p1, const vector<double>& v_line_p2)
{
array<double, 2> footP = get_foot_point(v_point, v_line_p1, v_line_p2);
double dist = 0;
if (((footP[0] - v_line_p1[0]) > 0) ^ ((footP[0] - v_line_p2[0]) > 0))
{
dist = sqrt((footP[0] - v_point[0]) * (footP[0] - v_point[0]) + (footP[1] - v_point[1]) * (footP[1] - v_point[1]));
}
else
{
dist = min(sqrt((v_line_p1[0] - v_point[0]) * (v_line_p1[0] - v_point[0]) + (v_line_p1[1] - v_point[1]) * (v_line_p1[1] - v_point[1])),
sqrt((v_line_p2[0] - v_point[0]) * (v_line_p2[0] - v_point[0]) + (v_line_p2[1] - v_point[1]) * (v_line_p2[1] - v_point[1])));
}
return dist;
}
object circle_triangle_test(const ndarray& center, const object& radius, const ndarray& tri_side1, const ndarray& tri_side2, const ndarray& tri_side3)
{
const double val_radius = extract<double>(radius);
vector<double> v_tri_side1 = ndarray2vec(tri_side1),
v_tri_side2 = ndarray2vec(tri_side2),
v_tri_side3 = ndarray2vec(tri_side3),
v_center = ndarray2vec(center);
array<vector<double>, 3> v_tri_sides = { v_tri_side1, v_tri_side2, v_tri_side3 };
for (int i = 0; i < 3; ++i)
{
if (sqrt((v_tri_sides[i][0] - v_center[0]) * (v_tri_sides[i][0] - v_center[0]) + (v_tri_sides[i][1] - v_center[1]) * (v_tri_sides[i][1] - v_center[1])) <= val_radius)
{
return object(true);
}
}
for (int i = 0; i < 3; ++i)
{
if (get_dis_point2line(v_center, { v_tri_sides[i][0], v_tri_sides[i][1] }, { v_tri_sides[i][2], v_tri_sides[i][3] }) <= val_radius)
{
return object(true);
}
}
return object(false);
}
BOOST_PYTHON_MODULE(testSquare)
{
using namespace boost::python;
def("two_triangle_test", two_triangle_test);
def("circle_triangle_test", circle_triangle_test);
}
这个文件主要写了两个函数,用来检测两个三角形是否重叠,一个圆是否和另一个三角形重叠。
但是当我将testSquare.dll重命名为testSquare.pyd并在.py文件中导入时,发现报错:“ImportError: DLL load failed: The specified module could not be found。”
像这样boost example.cpp生成的DLL文件可以正确导入使用:
#include "pch.h"
#define BOOST_PYTHON_STATIC_LIB
#include<boost/python.hpp>
using boost::python::list;
list Square(list& data)
{
list ret;
for (int i = 0; i < len(data); ++i)
{
ret.append(data[i] * data[i]);
}
return ret;
}
BOOST_PYTHON_MODULE(testSquare)
{
using namespace boost::python;
def("Square", Square);
}
【问题讨论】:
-
OpenCV DLL 是否可访问(在 PATH 中的某个位置,或与 .pyd 相同的目录)?
-
@DanMašek 是的,
..\opencv\build\x64\vc15\bin已添加到系统环境变量 PATH 中。