1、使用C++代码开辟图片的共享内存,由于实际需求需要保证图片的接收和发送同步进行(发一张图片,接收之后再发下一张),需要开辟标志位flag的共享内存,通过读取、修改flag的值来判断图片的接收情况。example.cpp
1 #include <iostream> 2 #include <cassert> 3 #include <stdlib.h> 4 #include <sys/shm.h> 5 #include "opencv2/core.hpp" 6 #include "opencv2/imgproc.hpp" 7 #include "opencv2/highgui.hpp" 8 #include "opencv2/videoio.hpp" 9 10 #define key 650 11 #define key_1 763 12 #define image_size_max 1920*1080*3 13 14 using namespace std; 15 using namespace cv; 16 17 typedef struct{ 18 int rows; 19 int cols; 20 uchar dataPointer[image_size_max]; 21 }image_head; 22 23 int dump(int row_image, int col_image, void* block_data_image) 24 { 25 int shm_id = shmget(key,sizeof(image_head),IPC_CREAT); 26 if(shm_id == -1) 27 { 28 cout<<"shmget error"<<endl; 29 return -1; 30 } 31 cout << "dump shem id is "<<shm_id<<endl; 32 33 image_head *buffer_head; 34 buffer_head = (image_head*) shmat(shm_id, NULL, 0); 35 36 if((long)buffer_head == -1) 37 { 38 cout<<"Share memary can‘t get pointer"<<endl; 39 return -1; 40 } 41 42 assert(row_image*col_image*3<=image_size_max); 43 image_head image_dumper; 44 image_dumper.rows=row_image; 45 image_dumper.cols=col_image; 46 uchar* ptr_tmp_image=(uchar*) block_data_image; 47 for (int i=0;i<row_image*col_image*3;i++) 48 { 49 image_dumper.dataPointer[i] = *ptr_tmp_image; 50 ptr_tmp_image++; 51 } 52 memcpy(buffer_head,&image_dumper,sizeof(image_dumper)); 53 54 shmdt(buffer_head); 55 return 1; 56 } 57 //写标志位 58 void WriteFlag2Share(char value) 59 { 60 int shm_id = shmget(key_1,sizeof(char) ,IPC_CREAT); 61 if(shm_id == -1) 62 { 63 cout<<"shmget error"<<endl; 64 exit(1); 65 } 66 cout << "write shem id is "<<shm_id<<endl; 67 68 char* buffer_head; 69 buffer_head = (char*)shmat(shm_id, NULL, 0); 70 71 if((long)buffer_head == -1) 72 { 73 perror("Share memary can‘t get pointer\n"); 74 exit(1); 75 } 76 memcpy(buffer_head, &value, sizeof(value)); 77 } 78 //读标志位 79 void ReadFlagFromShare(char &value) 80 { 81 int shm_id = shmget(key_1,sizeof(char) ,IPC_CREAT); 82 if(shm_id == -1) 83 { 84 cout<<"shmget error"<<endl; 85 exit(1); 86 } 87 cout << "read shem id is "<<shm_id<<endl; 88 89 char* buffer_head; 90 buffer_head = (char*)shmat(shm_id, NULL, 0); 91 92 if((long)buffer_head == -1) 93 { 94 perror("Share memary can‘t get pointer\n"); 95 exit(1); 96 } 97 memcpy(&value, buffer_head, sizeof(value)); 98 } 99 100 extern "C" 101 { 102 int dump_(int row_image, int col_image, void* block_data_image) 103 { 104 int result=dump(row_image, col_image, block_data_image); 105 return result; 106 } 107 void WriteFlag2Share_(char value) 108 { 109 WriteFlag2Share(value); 110 } 111 void ReadFlagFromShare_(char &value) 112 { 113 ReadFlagFromShare(value); 114 } 115 }
2、测试:接收图片的代码test_recieve.cpp
1 #include <iostream> 2 #include <stdlib.h> 3 #include <sys/shm.h> 4 #include "opencv2/core.hpp" 5 #include "opencv2/imgproc.hpp" 6 #include "opencv2/highgui.hpp" 7 #include "opencv2/videoio.hpp" 8 9 #define key 650 10 #define image_size_max 1920*1080*3 11 12 using namespace cv; 13 using namespace std; 14 15 typedef struct{ 16 int rows; 17 int cols; 18 uchar dataPointer[image_size_max]; 19 }image_head; 20 21 int main() 22 { 23 int count = 1; 24 while(true) 25 { 26 27 int shm_id = shmget(key,sizeof(image_head) ,IPC_CREAT); 28 if(shm_id == -1) 29 { 30 cout<<"shmget error"<<endl; 31 return -1; 32 } 33 cout << " shem id is "<<shm_id<<endl; 34 35 image_head* buffer_head; 36 buffer_head = (image_head*)shmat(shm_id, NULL, 0); 37 38 if((long)buffer_head == -1) 39 { 40 perror("Share memary can‘t get pointer\n"); 41 return -1; 42 } 43 44 image_head image_dumper; 45 memcpy(&image_dumper, buffer_head, sizeof(image_head)); 46 cout<<image_dumper.rows<<" "<<image_dumper.cols<<endl; 47 48 uchar* data_raw_image=image_dumper.dataPointer; 49 50 cv::Mat image(image_dumper.rows, image_dumper.cols, CV_8UC3); 51 cout<<"1"<<endl; 52 uchar* pxvec =image.ptr<uchar>(0); 53 int count = 0; 54 for (int row = 0; row < image_dumper.rows; row++) 55 { 56 pxvec = image.ptr<uchar>(row); 57 for(int col = 0; col < image_dumper.cols; col++) 58 { 59 for(int c = 0; c < 3; c++) 60 { 61 pxvec[col*3+c] = data_raw_image[count]; 62 count++; 63 } 64 } 65 } 66 //shmctl(shm_id, IPC_RMID, 0); 67 shmdt(buffer_head); 68 cv::imshow("Win",image); 69 cv::waitKey(1); 70 71 } 72 return 1; 73 }
3、cmakelist.txt,生成的so文件,用于python代码调用c++中的相关函数。
# cmake needs this line cmake_minimum_required(VERSION 2.8) # Define project name project(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 GUI find_package(OpenCV REQUIRED) # Print some message showing some of them message(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 paths include_directories(${OpenCV_INCLUDE_DIRS}) endif() # Declare the executable target built from your sources add_library(opencv_example SHARED example.cpp) add_executable(test_recieve test_recieve.cpp) # Link your application with OpenCV libraries target_link_libraries(opencv_example ${OpenCV_LIBS}) target_link_libraries(test_recieve ${OpenCV_LIBS})
4、编写python代码来发送图片,当标志位flag为空或者0时发送一张图片,并且发送完图片之后将标志位改为1。
1 import numpy as np 2 import time 3 import ctypes 4 import os 5 import cv2 6 ll = ctypes.cdll.LoadLibrary 7 lib = ll("./build/libopencv_example.so") 8 lib.dump_.restype = ctypes.c_int 9 lib.ReadFlagFromShare_.argtype = (ctypes.c_char) 10 lib.WriteFlag2Share_.argtype = (ctypes.c_char) 11 12 path = "images1/" 13 # paths = os.listdir(path) 14 # paths.sort() 15 16 cv2.namedWindow("py2cgg", cv2.WINDOW_NORMAL) 17 i=0 18 while True: 19 index = 0 20 while(i<=200): 21 # for img in paths: 22 time.sleep(0.08) 23 image = cv2.imread(path+str(i).zfill(4)+‘.png‘) 24 print(path+str(i).zfill(4)+‘.png‘) 25 cv2.waitKey(1) 26 image_data = np.asarray(image, dtype=np.uint8) 27 image_data = image_data.ctypes.data_as(ctypes.c_void_p) 28 flag = ctypes.c_char() 29 lib.ReadFlagFromShare_(ctypes.byref(flag)) 30 #lib.WriteFlag2Share_(0) 31 print(flag) 32 if not flag: 33 value = lib.dump_(image.shape[0], image.shape[1], image_data) 34 i+=1 35 cv2.imshow("py2cgg",image) 36 lib.WriteFlag2Share_(1)
5、在接收端接收图片,接收图片之后,将flag置为0
1 //读取图片函数readimage() ,类似test_recieve.cpp 2 //读取内存中的flag 3 int dump() 4 { 5 int shm_id = shmget(key_2+0, sizeof(int)*3, IPC_CREAT); 6 char *buffer_head; 7 buffer_head = (char*)shmat(shm_id, NULL, 0); 8 usleep(10000); 9 int a=atoi(buffer_head); 10 return a; 11 } 12 //将内存中的flag置为0 13 void dumpto0() 14 { 15 int shm_id = shmget(key_2+0, sizeof(int)*3, IPC_CREAT); 16 char *buffer_head; 17 buffer_head = (char*)shmat(shm_id, NULL, 0); 18 char a=0; 19 memcpy(buffer_head, &a, sizeof(a)); 20 }
原文:https://www.cnblogs.com/zxyzy/p/14753087.html