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

时间:2018-06-27 09:59:52

标签: python c++ opencv

如何将OpenCV 3映像从Python 3传递到C ++?用技术术语来说,如何将NumPy数组转换为cv::Mat对象并返回?

为了使我的问题更具体,让我们假设:

  1. 我有一个使用OpenCV从网络摄像头捕获图像并将其显示的Python程序。 (在现实生活中,我正在为其中的其他功能制作原型,例如一些Web服务器功能。)

    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()
    

    运行python3 cam.py进行尝试。

  2. 我想使用某些C ++库中的现有helloWorld函数来处理OpenCV图像。 (在现实生活中,它会进行一些信号处理并从图像中提取信息。)为简单起见,我下面的示例函数只是水平镜像图像。 main函数可用来检查helloWorld是否按预期工作。

    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;
    }
    

    要编译此代码,请运行g++ -std=c++11 -lopencv_core -lopencv_highgui -lopencv_videoio cam.cpp -o cam,然后执行./cam进行尝试。

现在我应该对代码进行哪些更改,以便可以从Python应用程序中调用helloWorld C ++函数?幸运的是,我可以访问C ++源代码,因此可以在需要时进行扩展和重新编译。

2 个答案:

答案 0 :(得分:2)

在这里,您必须进行进程间通信,因为您有同时运行的python进程和c ++进程,因此,要实现所需的功能,而不是在C ++程序中调用函数,只需从共享内存页面文件中读取即可在其中放置mat.data()并将其检索到C ++程序中的地方,只需确保在尝试访问共享内存区域之前就已创建该共享内存区域。

如果您真的想调用c ++函数,则可能需要考虑将C ++源函数/代码编译为dll,在运行时以python加载该dll,然后再调用该函数。

答案 1 :(得分:2)

有关创建模块的入门,请参见Artanis的要旨Python C Extension Hello World,该模块允许您从Python中调用C代码。

要在Python 3 NumPy数组和C ++ Mat之间进行转换,至少有2个地方可以找到示例C ++代码:

  1. OpenCV存储库中的文件cv2.cpp包含函数that are not exposed in its API

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

    • PyObject* pyopencv_from(const Mat& m)

  2. pyboostcvconverter提供了类似的独立转换器功能

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

在调用任何make sure you call the NumPy function import_array()之前,请在运行时避免Segmentation Fault: 11

我将它们全部放在code sample on GitHub中。 Python从相机获取图像,将其传递到C ++模块,然后C ++镜像该图像并将其传递回Python,最后Python显示该图像。