首页 > 其他 > 详细

C开辟共享内存实现图片的接收和发送

时间:2021-05-11 00:57:16      阅读:31      评论:0      收藏:0      [点我收藏+]

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 }

 

C开辟共享内存实现图片的接收和发送

原文:https://www.cnblogs.com/zxyzy/p/14753087.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!