python和C++共享内存传输图像的示例

时间:2021-05-22

原理

python没有办法直接和c++共享内存交互,需要间接调用c++打包好的库来实现

流程

  • C++共享内存打包成库
  • python调用C++库往共享内存存图像数据
  • C++测试代码从共享内存读取图像数据

实现

1.c++打包库

创建文件

example.cpp

#include <iostream>#include <cassert>#include <stdlib.h>#include <sys/shm.h>#include "opencv2/core.hpp"#include "opencv2/imgproc.hpp"#include "opencv2/highgui.hpp"#include "opencv2/videoio.hpp"#define key 650#define image_size_max 1920*1080*3using namespace std;using namespace cv;typedef struct{int rows;int cols;uchar dataPointer[image_size_max];}image_head;int dump(int cam_num,int row_image, int col_image, void* block_data_image){int shm_id = shmget(key+cam_num,sizeof(image_head),IPC_CREAT);if(shm_id == -1){cout<<"shmget error"<<endl;return -1;}cout << " shem id is "<<shm_id<<endl;image_head *buffer_head;buffer_head = (image_head*) shmat(shm_id, NULL, 0);if((long)buffer_head == -1){cout<<"Share memary can't get pointer"<<endl;return -1;}assert(row_image*col_image*3<=image_size_max);image_head image_dumper;image_dumper.rows=row_image;image_dumper.cols=col_image;uchar* ptr_tmp_image=(uchar*) block_data_image;for (int i=0;i<row_image*col_image*3;i++){image_dumper.dataPointer[i] = *ptr_tmp_image;ptr_tmp_image++;}memcpy(buffer_head,&image_dumper,sizeof(image_dumper));return 1;}extern "C"{int dump_(int cam_num,int row_image, int col_image, void* block_data_image){int result=dump(cam_num,row_image, col_image, block_data_image);return result;}}

CMakeLists.txt 

# cmake needs this linecmake_minimum_required(VERSION 2.8)# Define project nameproject(opencv_example_project)# Find OpenCV, you may need to set OpenCV_DIR variable# to the absolute path to the directory containing OpenCVConfig.cmake file# via the command line or GUIfind_package(OpenCV REQUIRED)# If the package has been found, several variables will# be set, you can find the full list with descriptions# in the OpenCVConfig.cmake file.# Print some message showing some of themmessage(STATUS "OpenCV library status:")message(STATUS " version: ${OpenCV_VERSION}")message(STATUS " libraries: ${OpenCV_LIBS}")message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")if(CMAKE_VERSION VERSION_LESS "2.8.11")# Add OpenCV headers location to your include pathsinclude_directories(${OpenCV_INCLUDE_DIRS})endif()# Declare the executable target built from your sourcesadd_library(opencv_example SHARED example.cpp)add_executable(test_example test_run.cpp)# Link your application with OpenCV librariestarget_link_libraries(opencv_example ${OpenCV_LIBS})target_link_libraries(test_example ${OpenCV_LIBS})

  最后生成库

2.python调用C++动态库进行存图

#!/usr/bin/env pythonimport sys#sys.path.append("/usr/lib/python3/dist-packages")#sys.path.append("/home/frank/Documents/215/code/parrot-groundsdk/.python/py3/lib/python3.5/site-packages")import cv2import ctypesimport numpy as npll = ctypes.cdll.LoadLibrarylib = ll("./build/libopencv_example.so")lib.dump_.restype = ctypes.c_intcount = 1#path = "/home/frank/Documents/215/2020.10.24/python_ctypes/image/"while count < 30:path = "./image/"+str(count)+".jpg"print(path)image=cv2.imread(path)#cv2.imshow("test",image)#cv2.waitKey(0)image_data = np.asarray(image, dtype=np.uint8)image_data = image_data.ctypes.data_as(ctypes.c_void_p)value = lib.dump_(0,image.shape[0], image.shape[1], image_data)print(value)count += 1if count == 30:count = 1

3.C++读取共享内存获取图像

#include <iostream>#include <stdlib.h>#include <sys/shm.h>#include "opencv2/core.hpp"#include "opencv2/imgproc.hpp"#include "opencv2/highgui.hpp"#include "opencv2/videoio.hpp"#define key 650#define image_size_max 1920*1080*3using namespace cv;using namespace std;typedef struct{int rows;int cols;uchar dataPointer[image_size_max];}image_head;int main(){int count = 1;while(true){int shm_id = shmget(key+0,sizeof(image_head) ,IPC_CREAT);if(shm_id == -1){cout<<"shmget error"<<endl;return -1;}cout << " shem id is "<<shm_id<<endl;image_head* buffer_head;buffer_head = (image_head*)shmat(shm_id, NULL, 0);if((long)buffer_head == -1){perror("Share memary can't get pointer\n");return -1;}image_head image_dumper;memcpy(&image_dumper, buffer_head, sizeof(image_head));cout<<image_dumper.rows<<" "<<image_dumper.cols<<endl;uchar* data_raw_image=image_dumper.dataPointer;cv::Mat image(image_dumper.rows, image_dumper.cols, CV_8UC3);uchar* pxvec =image.ptr<uchar>(0);int count = 0;for (int row = 0; row < image_dumper.rows; row++){pxvec = image.ptr<uchar>(row);for(int col = 0; col < image_dumper.cols; col++){for(int c = 0; c < 3; c++){pxvec[col*3+c] = data_raw_image[count];count++;}}}cv::imshow("Win",image);cv::waitKey(1);}return 1;}

以上就是python和C++共享内存传输图像的示例的详细内容,更多关于python和c++传输图像的资料请关注其它相关文章!

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章