从NumPy数组到Mat(OpenCV)的C ++转换 [英] C++ conversion from NumPy array to Mat (OpenCV)
问题描述
我正在围绕ArUco增强现实库(基于OpenCV)编写一个薄包装。我尝试构建的界面非常简单:
I am writing a thin wrapper around ArUco augmented reality library (which is based on OpenCV). An interface I am trying to build is very simple:
- Python将图像传递给C ++代码;
- C ++代码检测标记并将其位置和其他信息作为元组的返回到Python。
如何在Python中表示图像以将其传递给C ++。对于GUI和相机管理我将使用PyQt,所以最初它将是QImage,但我不能简单地传递给OpenCV(或我可以?)。首先,我试图使用嵌套元组来表示每个像素的行,列和颜色,所以我最后得到了这个示例代码:
However, I couldn't figure out how to represent an image in Python to pass it to C++. For GUI and camera management I am going to use PyQt, so initially it is going to be QImage, but I can't simply pass it to OpenCV (or I can?). At first, I tried to use nested tuples to represent row, column and color of each pixel, so I ended up with this sample code:
using namespace cv;
namespace py = boost::python;
void display(py::tuple pix)
{
/*
Receive image from Python and display it.
*/
Mat img(py::len(pix), py::len(pix[0]), CV_8UC3, Scalar(0, 0, 255));
for (int y = 0; y < py::len(pix); y++)
for (int x = 0; x < py::len(pix[y]); x++)
{
Vec3b rgb;
for (int i = 0; i < 3; i++)
rgb[i] = py::extract<int>(pix[y][x][i]);
img.at<Vec3b>(Point(x, y)) = rgb;
}
imshow("Image", img);
waitKey(0);
}
BOOST_PYTHON_MODULE(aruco)
{
py::def("display", display);
}
原来是慢得令人痛苦,所以我去谷歌搜索解决方案应该更快:使用NumPy数组,所以代码看起来像这样:
It turned out to be painfully slow (a few seconds for a single frame), so I went googling and found solution that should be much faster: use NumPy arrays, so the code would look something like that:
void display(py::object array)
{
Mat img;
// ... some magic here to convert NumPy array to Mat ...
imshow("Image", img);
waitKey(0);
}
<只是一个Python对象)到OpenCV Mat。
However, I have no idea how to convert NumPy Array (which in C++ level is just a Python Object) to OpenCV Mat. I would appreciate any help here.
或者,也许NumPy不是真的需要,所以我可以直接传递QImage Python对象直接到C ++层?或者也许有一个不同的方法来解决这个问题?
Alternatively, maybe NumPy is not really needed, so I could just pass QImage Python object directly to C++ layer? Or maybe there is a different approach to this problem? Any advice is appreciated!
推荐答案
在你的情况下,最好的解决方案是使用自定义boost :: python转换器为cv :: Mat对象。 OpenCV有Python包装,当你使用这个包装你使用Numpy数组 - 你甚至不需要知道这些数组被转换为cv :: Mat对象,而穿越c ++< - > python边界。写这样的转换器为简单类型是很容易,但创建转换器为cv :: Mat不简单。 Fortunetely其他人已经这样做了 - 这里是OpenCV 2.x和此处为3.x.如果你不熟悉boost :: python转换器,本文应该可以帮助你。
希望它有帮助,如果你有任何问题,请告诉我们。
The best solution in your situation is using custom boost::python converter for cv::Mat object. OpenCV has Python wrapper and when you are using this wrapper you are operating on Numpy arrays - you don't even need to know that those arrays are converted to cv::Mat objects while "crossing the c++ <-> python border". Writing such converter for simple type is quite easy, however creating converter for cv::Mat isn't simple. Fortunetely someone else already did this - here is version for OpenCV 2.x and here for 3.x. If you are not familiar with boost::python converters, this article should help you.
Hope it helps, if you wil have any problems, let us know.
这篇关于从NumPy数组到Mat(OpenCV)的C ++转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!