因毕设需要,需从 python 将图像数据传给 C++,接收 C++ 处理好后的图像。

    新建 C++ 文件接收从 Python传来的数据

    1. #include <opencv2/opencv.hpp>
    2. cv::BackgroundSubtractorMOG2 mog(100, 16, false);
    3. extern "C" void getfg(int rows, int cols, unsigned char* imgData,
    4. unsigned char *fgD) {
    5. cv::Mat img(rows, cols, CV_8UC3, (void *) imgData);
    6. cv::Mat fg(rows, cols, CV_8UC1, fgD);
    7. mog(img, fg);
    8. }
    9. extern "C" void getbg(int rows, int cols, unsigned char *bgD) {
    10. cv::Mat bg = cv::Mat(rows, cols, CV_8UC3, bgD);
    11. mog.getBackgroundImage(bg);
    12. }

    所有与 python 交互的 API 必须在 extern "C"中,如果交互 API 过多,上述代码也可以写成如下形式

    1. #include <opencv2/opencv.hpp>
    2. cv::BackgroundSubtractorMOG2 mog(100, 16, false);
    3. extern "C"{
    4. void getfg(int rows, int cols, unsigned char* imgData,
    5. unsigned char *fgD) {
    6. cv::Mat img(rows, cols, CV_8UC3, (void *) imgData);
    7. cv::Mat fg(rows, cols, CV_8UC1, fgD);
    8. mog(img, fg);
    9. }
    10. void getbg(int rows, int cols, unsigned char *bgD) {
    11. cv::Mat bg = cv::Mat(rows, cols, CV_8UC3, bgD);
    12. mog.getBackgroundImage(bg);
    13. }
    14. }

    图像数据通过 unsigned char *data 传输进来,通过Mat image(h,w,CV_8UC3,data)转换成C++ OpenCV可识别数据,如果是灰度图,则是CV_8UC1,数据通过指针链接,在C中是直接修改存在内存中的数据,无需传回。
    之后将 C 编译成动态链接库,CmakeLists设置如下

    1. add_library(prj SHARED
    2. main.cpp
    3. main.h libmain.cpp)
    4. target_link_libraries(prj ${OpenCV_LIBS})

    与C++交互的文件设置如下

    1. import ctypes
    2. # 链接动态库
    3. libmog = ctypes.cdll.LoadLibrary('path/to/libmain.so')
    4. def getfg(img):
    5. (rows, cols) = (img.shape[0], img.shape[1])
    6. res = np.zeros(dtype=np.uint8, shape=(rows, cols))
    7. libmain.getfg(img.shape[0], img.shape[1],
    8. img.ctypes.data_as(ctypes.c_char_p),
    9. res.ctypes.data_as(ctypes.c_char_p)
    10. return res
    11. def getbg(img):
    12. (rows, cols) = (img.shape[0], img.shape[1])
    13. res = np.zeros(dtype=np.uint8, shape=(rows, cols, 3))
    14. libmain.getbg(rows, cols, res.ctypes.data_as(ctypes.c_char_p))
    15. return res

    对于需要指针传输的数据,需要用ctypes.data_as(ctypes.c_char_p)将其转换成C++可读取的数据形式

    参考文章
    stackoverflow