简体   繁体   English

如何将OpenCV图像数据从Python转换为C ++?

[英]How to convert OpenCV image data from Python to C++?

How can I pass an OpenCV 3 image from Python 3 to C++? 如何将OpenCV 3映像从Python 3传递到C ++? In technical terms, how do I convert a NumPy array to a cv::Mat object and back? 用技术术语来说,如何将NumPy数组转换为cv::Mat对象并返回?

To make my question more specific, let's assume: 为了使我的问题更具体,让我们假设:

  1. I have a Python program that uses OpenCV to capture images from the webcam and display them. 我有一个使用OpenCV从网络摄像头捕获图像并显示它们的Python程序。 (In real life, I'm prototyping further functions there, such as some web server features.) (在现实生活中,我正在为其中的其他功能制作原型,例如某些Web服务器功能。)

    cam.py : cam.py

     import cv2 def main(): cam = cv2.VideoCapture(0) while True: _, img = cam.read() cv2.imshow('cam', img) # TODO: Call the C++ function from the sample below # img = helloWorld(img) cv2.waitKey(16) # let imshow do its work (16 ms -> 60 FPS) cv2.destroyAllWindows() if __name__ == '__main__': main() 

    Run python3 cam.py to try it out. 运行python3 cam.py进行尝试。

  2. I would like to use an existing helloWorld function from some C++ library that processes the OpenCV images. 我想使用某些C ++库中的现有helloWorld函数来处理OpenCV图像。 (In real life, it does some signal processing and extracts information from the images.) For the sake of simplicity, my sample function below just mirrors the image horizontally. (在现实生活中,它会进行一些信号处理并从图像中提取信息。)为简单起见,我下面的示例函数只是水平镜像图像。 The main function is there to check that helloWorld works as expected. main功能是检查helloWorld按预期工作。

    cam.cpp : cam.cpp

     #include <opencv2/highgui/highgui.hpp> using namespace cv; using namespace std; void helloWorld(Mat img) { flip(img, img, 1); } int main() { VideoCapture stream1(0); while (true) { Mat img; stream1.read(img); helloWorld(img); imshow("cam", img); waitKey(16); } return 0; } 

    To compile this code, run g++ -std=c++11 -lopencv_core -lopencv_highgui -lopencv_videoio cam.cpp -o cam , then execute ./cam to try it out. 要编译此代码,请运行g++ -std=c++11 -lopencv_core -lopencv_highgui -lopencv_videoio cam.cpp -o cam ,然后执行./cam进行尝试。

Now what changes should I make to my code so that I can call the helloWorld C++ function out of my Python app? 现在,我应该对代码进行哪些更改,以便可以从Python应用程序中调用helloWorld C ++函数? Luckily, I have access to the C++ source code, so that I can extend and recompile it if necessary. 幸运的是,我可以访问C ++源代码,因此可以在需要时进行扩展和重新编译。

Here you have to do inter process comunication, since you have the python process and the c++ process running simultaneoulsy, so, to achive what you want, instead of calling a function in the C++ program, just read from a shared memory pagefile where you put the mat.data() and you retrieve that in your C++ program, just make sure that the shared memory zone is created before trying to access it. 在这里,您必须进行进程间通信,因为您有同时运行的python进程和c ++进程,因此,要实现所需的功能,而不是在C ++程序中调用函数,只需从放置该文件的共享内存页面文件中读取即可mat.data(),然后在C ++程序中检索它,只需确保在尝试访问共享存储区之前已创建它。

If you really want to call a c++ function as it, you may have to consider compiling your C++ source function/code into a dll, load that dll at runtime in python, and calling that function after that. 如果您确实想调用c ++函数,则可能必须考虑将C ++源函数/代码编译为dll,在运行时在python中加载该dll,然后再调用该函数。

See Artanis's gist Python C Extension Hello World for getting started with the creation of a module allowing you to call C code out of Python. 有关创建允许您从Python调用C代码的模块的入门,请参阅Artanis的要旨Python C扩展Hello World

For converting between the Python 3 NumPy array and the C++ Mat, there are at least 2 places where you can find sample C++ code: 为了在Python 3 NumPy数组和C ++ Mat之间进行转换,至少有2个地方可以找到示例C ++代码:

  1. The file cv2.cpp on the OpenCV repository contains functions that are not exposed in its API : OpenCV存储库上的文件cv2.cpp包含其API中未公开的功能:

    • bool pyopencv_to(PyObject* o, UMat& um, const char* name) and bool pyopencv_to(PyObject* o, UMat& um, const char* name)

    • PyObject* pyopencv_from(const Mat& m) . PyObject* pyopencv_from(const Mat& m)

  2. pyboostcvconverter provides similar standalone converter functions pyboostcvconverter提供类似的独立转换器功能

    • PyObject* fromMatToNDArray(const Mat& m) and PyObject* fromMatToNDArray(const Mat& m)
    • Mat fromNDArrayToMat(PyObject* o) . Mat fromNDArrayToMat(PyObject* o)

Before calling any of these, make sure you call the NumPy function import_array() once to avoid a Segmentation Fault: 11 at runtime. 在调用其中任何一个之前,请确保一次调用NumPy函数import_array()以避免运行时出现Segmentation Fault: 11

I've put it all together in a code sample on GitHub . 我将所有内容汇总到GitHub上代码示例中 Python grabs an image from the camera, passes it to the C++ module, then C++ mirrors the image and passes it back to Python, and finally Python displays the image. Python从相机获取图像,将其传递给C ++模块,然后C ++镜像该图像并将其传递回Python,最后Python显示该图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM