正常工程学习结构
发送端
#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;
}
浙公网安备 33010602011771号