【问题标题】:How to convert OpenCV image data from Python to C++?如何将 OpenCV 图像数据从 Python 转换为 C++?
【发布时间】:2018-12-06 04:13:27
【问题描述】:

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

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

  1. 我有一个 Python 程序,它使用 OpenCV 从网络摄像头捕获图像并显示它们。 (在现实生活中,我正在那里制作更多功能的原型,例如一些 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. 我想使用处理 OpenCV 图像的某个 C++ 库中的现有 helloWorld 函数。 (在现实生活中,它会进行一些信号处理并从图像中提取信息。)为了简单起见,我下面的示例函数只是水平镜像图像。 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++ 源代码,因此我可以在必要时对其进行扩展和重新编译。

【问题讨论】:

标签: python c++ opencv


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

      • PyObject* pyopencv_from(const Mat&amp; m)

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

      • PyObject* fromMatToNDArray(const Mat&amp; 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 显示图像。

    【讨论】:

    • 图像是通过引用传递还是通过值传递?如果我没记错的话,它们曾经是按价值传递的!?
    猜你喜欢
    • 2017-03-09
    • 2015-06-26
    • 1970-01-01
    • 2014-05-21
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    相关资源
    最近更新 更多