正常工程学习结构
发送端
#include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/shm.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> #include <vector> #include <string> #define Shm_addrees 1201 #define IMAGE_W 1202 //图像宽 #define IMAGE_H 676 //图像高 #define IMAGE_SIZE IMAGE_W*IMAGE_H*3 //图片像素总大小 3通道彩色 using namespace std; typedef struct _ShareData { int flag; int rows; int cols; char imgdata[IMAGE_SIZE];//之前用了cv::Mat不行,因为无法在结构体里初始化大小 }ShareData; int Send_data2_share(ShareData *pShareData){ int i = 0; while(1) { while(pShareData->flag == 0) { getchar(); cv::Mat Img=cv::imread("../data_img/1.jpg",cv::IMREAD_COLOR); if(Img.data== nullptr)//nullptr是c++11新出现的空指针常量 { printf("图片文件不存在\n"); return 0; } else{ printf("图片文件存在\n"); } //3-1共享内存保存图像宽和高 pShareData->rows =Img.rows; pShareData->cols = Img.cols; //3-2共享内存保存图像数据 int size = Img.cols * Img.rows * Img.channels(); char *cvoutImg = (char*)Img.data; memcpy(pShareData->imgdata, cvoutImg, size); //3-3共享内存保存标志位 pShareData->flag = 1; } } } int main() { //1创建共享内存 int shmid = shmget((key_t)Shm_addrees, sizeof(ShareData), 0666|IPC_CREAT); //2映射共享内存地址 shm指针记录了起始地址 void *shm = shmat(shmid, (void*)0, 0);//如果创建一个函数每次调用都执行,需要执行完释放一下shmdt printf("共享内存地址 : %p\n", (int *)(shm)); //2-1映射共性内存类型-访问共享内存数据 ShareData *pShareData= (ShareData*)shm; pShareData->flag = 0; //使用共享内存数据 Send_data2_share(pShareData); //4断开映射 ,保证下次访问不被占用 shmdt(shm); //5释放共享内存地址 shmctl(shmid, IPC_RMID, 0); return 0; }
接收端
#include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/shm.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> #define Shm_addrees 1201 #define IMAGE_W 1202 //图像宽 #define IMAGE_H 676 //图像高 #define IMAGE_SIZE IMAGE_W*IMAGE_H*3 //图片像素总大小 3通道彩色 最大大小 using namespace std; typedef struct _ShareData { int flag; int rows; int cols; char imgdata[IMAGE_SIZE]; }ShareData; int Rec_share2_data(ShareData *pShareData){ while(1) { //3-1共享内存读取标志位 if(pShareData->flag == 1) { //3-2从共享内存获取图像高和宽 int IMAGE_h=pShareData->rows;//从共享内存获取图像高 int IMAGE_w=pShareData->cols;//从共享内存获取图像宽 //3-3共享内存读取图像数据 cv::Mat cvoutImg = cv::Mat(IMAGE_h,IMAGE_w,CV_8UC3,cv::Scalar(255, 255, 255));//bufHight,bufWidth int size = cvoutImg.cols * cvoutImg.rows * cvoutImg.channels(); memcpy((char*)cvoutImg.data, pShareData->imgdata,size); cv::imshow("RecData_Show",cvoutImg); cv::waitKey(1000); printf("数据跟新一次"); //3-4共享内存修改标志位 pShareData->flag = 0; } } } int main() { //1创建共享内存 int shmid = shmget((key_t)Shm_addrees, sizeof(ShareData), 0666|IPC_CREAT); //2映射共享内存地址 void *shm = shmat(shmid, (void*)0, 0);//如果创建一个函数每次调用都执行,需要执行完释放一下shmdt //2-1映射共性内存类型 ShareData *pShareData = (ShareData*)shm; //3数据访问 Rec_share2_data( pShareData); //4断开映射 ,保证下次访问不被占用 shmdt(shm); //5释放共享内存地址 shmctl(shmid, IPC_RMID, 0); return 0; }
---------------------------------------------------------------
类封装工程
编译测试
cd build cmake .. make
执行
使用讲解
正常调用
具体代码
CMakeLists.txt
# cmake needs this line cmake_minimum_required(VERSION 3.1) # Define project name project(opencv_example_project) find_package(OpenCV REQUIRED) message(STATUS "OpenCV library status:") message(STATUS " version: ${OpenCV_VERSION}") message(STATUS " libraries: ${OpenCV_LIBS}") message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}") # Declare the executable target built from your sources add_executable(send ApiShare.cpp send_example.cpp) add_executable(client ApiShare.cpp recive_example.cpp) # Link your application with OpenCV libraries target_link_libraries(send ${OpenCV_LIBS}) target_link_libraries(client ${OpenCV_LIBS})
调用类
修改内容
1修改图像分辨率
2修改数据结构,自定义扩展
#define IMAGE_W 1202 //图像宽
#define IMAGE_H 676 //图像高
3修改共享内存标识
#define Shm_addrees 1201 //共享内存地址标识
ApiShare.cpp
#include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/shm.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> #include <vector> #include <string> using namespace std; namespace MyShare{ class Share_class { //变量定义 public: #define Shm_addrees 1201 //共享内存地址标识 #define IMAGE_W 1202 //图像宽 #define IMAGE_H 676 //图像高 #define IMAGE_SIZE IMAGE_W*IMAGE_H*3 //图片像素总大小 3通道彩色 //共享内存结构 typedef struct _ShareData { int flag; int rows; int cols; char imgdata[IMAGE_SIZE];//之前用了cv::Mat不行,因为无法在结构体里初始化大小 }ShareData; //1创建共享内存 int shmid = shmget((key_t)Shm_addrees, sizeof(ShareData), 0666|IPC_CREAT); //2映射共享内存地址 shm指针记录了起始地址 void *shm = shmat(shmid, (void*)0, 0);//如果创建一个函数每次调用都执行,需要执行完释放一下shmdt //printf("共享内存地址 : %p\n", (int *)(shm)); //2-1映射共性内存类型-访问共享内存数据 ShareData *pShareData= (ShareData*)shm; //pShareData->flag = 0; cv::Mat cvoutImg = cv::Mat(IMAGE_H,IMAGE_W,CV_8UC3,cv::Scalar(255, 255, 255));//bufHight,bufWidth //函数定义 public: //1初始化执行 Share_class(){ printf("共享内存地址 : %p\n", (int *)(shm)); pShareData->flag = 0; }//1构造函数 //0销毁执行 ~Share_class() { cout<<"析构函数执行"<<endl; } //0结束销毁函数 //3销毁共享内存 int DestroyShare(){ //4断开映射 ,保证下次访问不被占用 shmdt(shm); //5释放共享内存地址 shmctl(shmid, IPC_RMID, 0); cout<<"共享内存已经销毁"<<endl; } //2发送图像一张 ,并修改发送标志位1 int Send_pic2_share_once(cv::Mat Img){ int i = 0; if(pShareData->flag == 0) { //cv::Mat Img=cv::imread("../data_img/1.jpg",cv::IMREAD_COLOR); if(Img.data== nullptr)//nullptr是c++11新出现的空指针常量 { printf("图片文件不存在\n"); return 0; } else{ printf("图片文件存在\n"); } //3-1共享内存保存图像宽和高 pShareData->rows =Img.rows; pShareData->cols = Img.cols; //3-2共享内存保存图像数据 int size = Img.cols * Img.rows * Img.channels(); char *cvoutImg = (char*)Img.data; memcpy(pShareData->imgdata, cvoutImg, size); //3-3共享内存保存标志位 pShareData->flag = 1; } //getchar(); } //从共享内存读取一张图片 int Rec_pic2_data_once(){ //cv::Mat &cvoutImg_in //3-1共享内存读取标志位 if(pShareData->flag == 1) { //3-2从共享内存获取图像高和宽 int IMAGE_h=pShareData->rows;//从共享内存获取图像高 int IMAGE_w=pShareData->cols;//从共享内存获取图像宽 //3-3共享内存读取图像数据 //cv::Mat cvoutImg = cv::Mat(IMAGE_h,IMAGE_w,CV_8UC3,cv::Scalar(255, 255, 255));//bufHight,bufWidth int size = cvoutImg.cols * cvoutImg.rows * cvoutImg.channels(); memcpy((char*)cvoutImg.data, pShareData->imgdata,size); //cvoutImg.copyTo(cvoutImg_in); //cvoutImg_in=cvoutImg; //cv::imshow("RecData_Show",cvoutImg); //cv::waitKey(1); printf("数据跟新一次\n"); //3-4共享内存修改标志位 pShareData->flag = 0; } } };//类定义结束 }//namespace 定义
发送类
send_example.cpp
#include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/shm.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> #include <vector> #include <string> #include "ApiShare.cpp" using namespace std; int main() { //1创建对象 MyShare::Share_class useShare; //2-1发送数据-读取数据 cv::Mat Img=cv::imread("../data_img/1.jpg",cv::IMREAD_COLOR); //2-2修改标志位--用来控制读取同步 //useShare.pShareData->flag = 0; //提醒。第一次初始化强制给0,清除上次程序残留结果,类初始化已经给0了 //3发送图像 while (1){ useShare.Send_pic2_share_once(Img);//发送一张图像 if(useShare.pShareData->flag ==3){ //接收端读取成功并且将标志位修改成3 关闭 break; } } //销毁 useShare.DestroyShare(); //销毁共享内存 }
接受测试
recive_example.cpp
#include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/shm.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <iostream> #include <vector> #include <string> #include "ApiShare.cpp" using namespace std; int main() { //1创建对象 MyShare::Share_class useShare; //2创建接受图像 // cv::Mat cvoutImg = cv::Mat(676,1201,CV_8UC3,cv::Scalar(255, 255, 255));//bufHight,bufWidth //3接受图像 while (1){ useShare.Rec_pic2_data_once();//接受一张图像 cv::Mat cvoutImg=useShare.cvoutImg; cv::imshow("RecData_Show",cvoutImg); char key=cv::waitKey(1); if(key=='q'){ useShare.pShareData->flag=3; printf("按键退出"); break;} } //销毁 useShare.DestroyShare(); //销毁共享内存 return 0; }