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

How to convert OpenCV image data from Python to C++?

本文关键字:转换 Python C++ 数据 OpenCV 图像      更新时间:2023-10-16

如何将 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++库中处理 OpenCV 图像的现有helloWorld函数。(在现实生活中,它会进行一些信号处理并从图像中提取信息。为了简单起见,我下面的示例函数只是水平镜像图像。main函数用于检查helloWorld是否按预期工作。

    凸轮.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 应用中调用helloWorldC++ 函数?幸运的是,我可以访问C++源代码,以便在必要时可以扩展和重新编译它。

参见 Artanis 的要点 Python C Extension Hello World,了解如何开始创建允许从 Python 调用 C 代码的模块。

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

  1. OpenCV 存储库上的文件 cv2.cpp 包含未在其 API 中公开的函数:

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

    • PyObject* pyopencv_from(const Mat& m).

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

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

在调用其中任何一个之前,请确保import_array()调用一次 NumPy 函数,以避免在运行时出现Segmentation Fault: 11

我已经在 GitHub 上的代码示例中将它们放在一起。Python 从相机中抓取图像,将其传递给C++模块,然后C++镜像图像并将其传递回 Python,最后 Python 显示图像。

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

如果你真的想调用一个 c++ 函数,你可能不得不考虑将你的C++源函数/代码编译成一个 dll,在 python 中运行时加载该 dll,然后调用该函数。