1传输的数据

1-1数据格式说明

1 两路视频图像Mat

图像 图像数据(Mat)+图像头信息(ImgInf)

//图像的宽、高、类型信息
typedef struct
{
int width; //4个字节
int height;
int type;
}ImgInf;

  

2 单个TrackBox

(假设单个目标检测框)

typedef struct
{
int x;
int y; int width;
int height; int flag; }TrackBox; //20个字节

  

3 每路视频得  vector<TrackBox> VTrackBox; (所有目标检测框集合)

1-2数据分配位置

//--------------------------------共享内存大小确定--------------------------------------
//1-1为BOX分配的空间
#define BOX_SIZE sizeof(TrackBox) // TrackBox结构体大小
//1-2为BOX数组分配
#define MAT_BOXVEC_NUMBER 2 //几路视频就有多少对应的检测数组
#define MAT_BOX_NUMBER 100 // 一个容器里假设最大有100个TrackBox(20个字节) 2000个字节
#define MAT_BOX_VECTOR MAT_BOX_NUMBER*BOX_SIZE //1-3为图片分配的空间
#define FRAME_NUMBER 2 // 图像输入路数
#define FRAME_W_H 1920*1080 // 图像分辨率
#define FRAME_SIZE FRAME_W_H*sizeof(unsigned char)*3+sizeof(ImgInf) // 图像彩色图(三通道)+ 图像信息结构体 //--------------------------------共享内存位置分配-------------------------------------- //各路图像所在共享内存位置
#define MAT_DATA1 FRAME_SIZE*0 //存MAT_DATA1 pBuf+FRAME_SIZE*1 - pBuf+FRAME_SIZE*1+sizeof(Mat)
#define MAT_DATA2 FRAME_SIZE*1 //存MAT_DATA1 pBuf+FRAME_SIZE*2 - pBuf+FRAME_SIZE*1+sizeof(Mat) #define MAT_DATA1_BOX FRAME_SIZE*2
#define MAT_DATA2_BOX FRAME_SIZE*2+MAT_BOX_VECTOR //BOX_DATA所在共享内存位置
#define BOX_DATA FRAME_SIZE*FRAME_NUMBER + MAT_BOX_VECTOR*MAT_BOXVEC_NUMBER //数据存储的起始位置 存BOX_DATA pBuf+FRAME_SIZE*0 - pBuf+FRAME_SIZE*0+sizeof(TrackBox) //总空间大小
#define MEMORY_SIZE FRAME_SIZE*FRAME_NUMBER+MAT_BOX_VECTOR*MAT_BOXVEC_NUMBER+BOX_SIZE

  

缺陷,没有加入标志位,用来同步两个节点的存取

2工程文件

2-1发送端

main.cpp

#pragma once
#ifndef MAIN
#define MAIN /* 1包含文件 */
//1.1 系统 必选
#include<iostream>
#include<Windows.h>
#include "../Include/ShareMemray.h" //1.2 opencv 可选
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std; TrackBox BOX1;
vector<TrackBox> VTrackBox1;
/* 4 测试 鼠标点击输出 x y 存入共享内存 */
//4.1 鼠标事件
void onMouse(int event, int x, int y, int flags, void* param)
{ //cout << "flag =" << flag << endl;
Mat *im = reinterpret_cast<Mat*>(param);
switch (event)
{
case CV_EVENT_LBUTTONDOWN: //鼠标左键按下响应:返回坐标和灰度
BOX1.x = x;
BOX1.y = y;
BOX1.flag = flags; break;
}
}
// 4.2 读取视频
int imge_test(SHAREDMEMORY sharesend) { VideoCapture capture(0);
if (!capture.isOpened())
{
return -1;
}
Mat frame;
capture.set(CV_CAP_PROP_FRAME_WIDTH, 1920);
capture.set(CV_CAP_PROP_FRAME_HEIGHT, 1080); bool stop = false;
while (1)
{
//flag = 0;
capture >> frame;
cvNamedWindow("当前视频", 0); resize(frame, frame, Size(1920, 1080));
//Sleep(10);
cvSetMouseCallback("当前视频", onMouse, &frame); imshow("当前视频", frame);
waitKey(1); if (BOX1.flag == 1)
{
// 1发送单个BOX1 sharesend.SendBox(BOX1);
cout << "at(" << BOX1.x << "," << BOX1.y << ")" << "flag =" << BOX1.flag <<" h "<< BOX1.height<< " w "<< BOX1.width << endl; // 2发送多个BOX(容器)
VTrackBox1.clear();
// 不能加resize 否则不出图
for (int i = 0; i <MAT_BOX_NUMBER; i++)
{
BOX1.width = i;
BOX1.height = i;
VTrackBox1.push_back(BOX1);
}
sharesend.SendVectorBox(VTrackBox1); BOX1.flag = 0; } // 3发送图片
sharesend.SendMat(frame,MAT_DATA1); } } int main()
{
//共享内存初始化
SHAREDMEMORY sharesend;
sharesend.intShareroom(); //共享内存发送信息
imge_test(sharesend); //共享内存释放
sharesend.stop(); return 0;
} #endif

  2-2接收端

#include <windows.h>
#include<iostream>
#include "../Include/ShareMemray.h" using namespace std; TrackBox recBOX; void main() { SHAREDMEMORY sharerec;
sharerec.intShareroom(); while (true)
{ //1 接收单个box
sharerec.RecBox(recBOX);
if (recBOX.flag != 0) // 标志位判断数据是否有效
{ //2 接受多个box(容器)
vector<TrackBox> VTrackBoxrec;
// 必须resize 否则没有空间无法储存
VTrackBoxrec.resize(MAT_BOX_NUMBER); sharerec.RecieveVectorBox(VTrackBoxrec);
for (auto &i : VTrackBoxrec)
{
cout << "x " << i.x << " y " << i.y << " h " << i.height << " w " << i.width << endl;
} } Mat frame=sharerec.RecieveMat(MAT_DATA1);
if (!frame.empty())
{
namedWindow("show", 0);
imshow("show", frame);
waitKey(1);
} }
sharerec.stop(); }

2-2接收端  

#include <windows.h>
#include<iostream>
#include "../Include/ShareMemray.h" using namespace std; TrackBox recBOX; void main() { SHAREDMEMORY sharerec;
sharerec.intShareroom(); while (true)
{ //1 接收单个box
sharerec.RecBox(recBOX);
if (recBOX.flag != 0) // 标志位判断数据是否有效
{ //2 接受多个box(容器)
vector<TrackBox> VTrackBoxrec;
// 必须resize 否则没有空间无法储存
VTrackBoxrec.resize(MAT_BOX_NUMBER); sharerec.RecieveVectorBox(VTrackBoxrec);
for (auto &i : VTrackBoxrec)
{
cout << "x " << i.x << " y " << i.y << " h " << i.height << " w " << i.width << endl;
} } Mat frame=sharerec.RecieveMat(MAT_DATA1);
if (!frame.empty())
{
namedWindow("show", 0);
imshow("show", frame);
waitKey(1);
} }
sharerec.stop(); }

  2-3 共享内存文件

使用过程

配置过程

0-0工程包含这个两个文件

0-1给共享内存取个名字

0-2根据发送的数据,开辟总空间大小,分配各个数据在总空间得存储位置

1 共享内存初始化

SHAREDMEMORY sharesend;

sharesend.intShareroom();

2 发送和接收数据,给例程给了三种数据的收发

3 应该加入同步策略,通过一个标志位来决定什么时候收发。

4 最后释放共享内内存

工程文件

ShareMemray.h

#pragma once
#ifndef ShareMemray_H
#define ShareMemray_H #include<iostream>
#include<Windows.h>
#include <stdio.h>
#include <cstdio>
#include <opencv2/opencv.hpp> using namespace cv;
using namespace std; //--------------------------------共享内存数据类型--------------------------------------
//目标检测的上下顶点;
typedef struct
{
int x;
int y; int width;
int height; int flag; }TrackBox; //20个字节 //图像的宽、高、类型信息
typedef struct
{
int width; //4个字节
int height;
int type;
}ImgInf; //图像的数据信息 单通道和三通道
//Mat //--------------------------------共享内存大小确定--------------------------------------
//1-1为BOX分配的空间
#define BOX_SIZE sizeof(TrackBox) // TrackBox结构体大小
//1-2为BOX数组分配
#define MAT_BOXVEC_NUMBER 2 //几路视频就有多少对应的检测数组
#define MAT_BOX_NUMBER 100 // 一个容器里假设最大有100个TrackBox(20个字节) 2000个字节
#define MAT_BOX_VECTOR MAT_BOX_NUMBER*BOX_SIZE //1-3为图片分配的空间
#define FRAME_NUMBER 2 // 图像输入路数
#define FRAME_W_H 1920*1080 // 图像分辨率
#define FRAME_SIZE FRAME_W_H*sizeof(unsigned char)*3+sizeof(ImgInf) // 图像彩色图(三通道)+ 图像信息结构体 //--------------------------------共享内存位置分配-------------------------------------- //各路图像所在共享内存位置
#define MAT_DATA1 FRAME_SIZE*0 //存MAT_DATA1 pBuf+FRAME_SIZE*1 - pBuf+FRAME_SIZE*1+sizeof(Mat)
#define MAT_DATA2 FRAME_SIZE*1 //存MAT_DATA1 pBuf+FRAME_SIZE*2 - pBuf+FRAME_SIZE*1+sizeof(Mat) #define MAT_DATA1_BOX FRAME_SIZE*2
#define MAT_DATA2_BOX FRAME_SIZE*2+MAT_BOX_VECTOR //BOX_DATA所在共享内存位置
#define BOX_DATA FRAME_SIZE*FRAME_NUMBER + MAT_BOX_VECTOR*MAT_BOXVEC_NUMBER //数据存储的起始位置 存BOX_DATA pBuf+FRAME_SIZE*0 - pBuf+FRAME_SIZE*0+sizeof(TrackBox) //总空间大小
#define MEMORY_SIZE FRAME_SIZE*FRAME_NUMBER+MAT_BOX_VECTOR*MAT_BOXVEC_NUMBER+BOX_SIZE class SHAREDMEMORY { public: HANDLE hMapFile;
LPCTSTR pBuf;
TCHAR szName[30] = TEXT("Local\\FHY_SYSTEM_0"); //指向同一块共享内存的名字
//TrackBox BOX;
//vector<TrackBox> VTrackBox; //为了共享内存传输,必须开始初始化最大 public: //1 初始化
int intShareroom();
void SendBox(TrackBox &BOX);
void RecBox(TrackBox &BOX);
void SendVectorBox(vector<TrackBox> &VTrackBox);
void RecieveVectorBox(vector<TrackBox> &VTrackBox);
void SendMat(cv::Mat img, char indexAddress);
Mat RecieveMat(char indexAddress); void stop(); }; #endif //SHAREDMEMORY_HPP

  ShareMemray.cpp

#pragma once
#ifndef ShareMemray_CPP
#define ShareMemray_CPP #include "ShareMemray.h" //3.2 初始化
int SHAREDMEMORY::intShareroom() { hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, MEMORY_SIZE ,szName); if (hMapFile == NULL)
{ cout <<"Could not create file mapping object" << GetLastError() << endl;
return 1;
} pBuf = (LPTSTR)MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
MEMORY_SIZE); if (pBuf == NULL)
{ cout << "Could not map view of file" << GetLastError() << endl;
CloseHandle(hMapFile); return 1;
} // 容器初始化
//VTrackBox.resize(MAT_BOX_NUMBER); } /**************************************************
功能: 发送单个结构体
输入:
TrackBox &BOX 1结构体
(char*)pBuf+ BOX_DATA 2结构体存在的位置
sizeof(TrackBox) 3结构体大小() ***************************************************/
void SHAREDMEMORY::SendBox(TrackBox &BOX) {
memcpy((char*)pBuf+ BOX_DATA, &BOX, sizeof(TrackBox));
} /**************************************************
功能: 接收单个结构体
输入:
TrackBox &BOX 1结构体
(char*)pBuf+ BOX_DATA 2结构体存在的位置
sizeof(TrackBox) 3结构体大小()
***************************************************/
void SHAREDMEMORY::RecBox(TrackBox &BOX) {
memcpy(&BOX, (char*)pBuf+ BOX_DATA, sizeof(TrackBox));
} /**************************************************
*name :void SendVectorBox(vector<TrackBox> VTrackBox)
*function :发送容器,结构体序列序列
输入:
vector<TrackBox> VTrackBox 1要存得容器
(char*)pBuf + MAT_DATA1_BOX 2结构体序列得起始位置
number*sizeof(TrackBox) 3每一个结构体依次往后递增存储位置
sizeof(TrackBox) 4单个结构体大小
输出: 无
说明:
1每次调用前清空容器
2采用auto &i : VTrackBox 访问容器,确保容器提前resize足够固定空间,否则无法存 VTrackBox.resize(MAT_BOX_NUMBER);
即使这样,循环访问索引还是会出错,最好固定数目MAT_BOX_NUMBER 而非用 VTrackBox.size()
正确 for (int i = 0; i <100; i++)
出问题 for (int i = 0; i <VTrackBox.size(); i++)
**************************************************/
void SHAREDMEMORY::SendVectorBox(vector<TrackBox> &VTrackBox) {
int number = 0;
for (auto &i : VTrackBox) {
//cout << number << " "<< i.x <<endl;
memcpy((char*)pBuf + MAT_DATA1_BOX + number*sizeof(TrackBox), &i, sizeof(TrackBox));
number++;
}
//VTrackBox.clear();
//VTrackBox.resize(MAT_BOX_NUMBER);
}
/**************************************************
*name :void RecieveVectorBox(vector<TrackBox> VTrackBox)
*function :接受容器序列
输入:
vector<TrackBox> VTrackBox 要接受的容器
输出: 无
**************************************************/
void SHAREDMEMORY::RecieveVectorBox(vector<TrackBox> &VTrackBox)
{
//VTrackBox.clear();
//VTrackBox.resize(MAT_BOX_NUMBER);
int number = 0;
for (auto &i : VTrackBox) {
memcpy(&i ,(char*)pBuf + MAT_DATA1_BOX + number*sizeof(TrackBox), sizeof(TrackBox));
number++;
} } /**************************************************
*name :int SharedMemory::sendMat(Mat img, int index)
*function :发送Mat图像
输入:
Mat img 要存得图像
char indexAddress 图像要存得位置
输出: 无
**************************************************/
void SHAREDMEMORY::SendMat(cv::Mat img, char indexAddress)
{
ImgInf ImgHead;
ImgHead.width = img.cols;
ImgHead.height = img.rows;
ImgHead.type = img.type();
if (ImgHead.type == CV_64FC1)
{
memcpy((char*)pBuf + indexAddress, &ImgHead, sizeof(ImgInf));
memcpy((char*)pBuf + indexAddress + sizeof(ImgInf), img.data, img.cols * img.rows * img.channels() * sizeof(double));
}
else
{
memcpy((char*)pBuf + indexAddress, &ImgHead, sizeof(ImgInf));
memcpy((char*)pBuf + indexAddress + sizeof(ImgInf), img.data, img.cols * img.rows * img.channels());
}
} /**************************************************
*name :int SharedMemory::recieveMat(int index)
*function :接收Mat图像
*参数:
输入:char indexAddress 要取得图像首地址
输出: Mat 类型图像
**************************************************/
cv::Mat SHAREDMEMORY::RecieveMat(char indexAddress)
{
ImgInf ImgHead;
cv::Mat img;
memcpy(&ImgHead, (char*)pBuf+indexAddress, sizeof(ImgInf));
img.create(ImgHead.height, ImgHead.width, ImgHead.type);
if (ImgHead.type == CV_64FC1)
{
memcpy(img.data, (char*)pBuf+indexAddress + sizeof(ImgInf), img.cols * img.rows * img.channels() * sizeof(double));
}
else
{
memcpy(img.data, (char*)pBuf+indexAddress + sizeof(ImgInf), img.cols * img.rows * img.channels());
}
return img;
} void SHAREDMEMORY::stop() {
UnmapViewOfFile(pBuf); //释放;
CloseHandle(hMapFile);
}
#endif

  

例程使用(1-4)共享内存 存图片+vector容器教程的更多相关文章

  1. vector存入共享内存(了解)

    昨天在上篇blog里描写了如何把STL容器放到共享内存里去,不过由于好久不写blog,发觉词汇组织能力差了很多,不少想写的东西写的很零散,今天刚好翻看自己的书签,看到一篇挺老的文章,不过从共享内存到S ...

  2. Linux共享内存(一)

    inux系统编程我一直看 <GNU/LINUX编程指南>,只是讲的太简单了,通常是书和网络上的资料结合着来掌握才比较全面 .在掌握了书上的内容后,再来都其他资料 . 原文链接 http:/ ...

  3. 进程间通信机制(管道、信号、共享内存/信号量/消息队列)、线程间通信机制(互斥锁、条件变量、posix匿名信号量)

    注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料如<linux内核完全剖析>.<linux c 编程一站式学习>等,只是为了更好 ...

  4. Linux进程间通信—共享内存

    五.共享内存(shared memory) 共享内存映射为一段可以被其他进程访问的内存.该共享内存由一个进程所创建,然后其他进程可以挂载到该共享内存中.共享内存是最快的IPC机制,但由于linux本身 ...

  5. <转>UNIX 共享内存应用中的问题及解决方法

    http://www.ibm.com/developerworks/cn/aix/library/au-cn-sharemem/ 共享内存是一种非常重要且常用的进程间通信方式,相对于其它IPC机制,因 ...

  6. Linux学习笔记(14)-进程通信|共享内存

    在Linux中,共享内存是允许两个不相关的进程访问同一个逻辑内存的进程间通信方法,是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式. 不同进程之间共享的内存通常安排为同一段物理内存.进程可 ...

  7. mmap和shm共享内存的区别和联系

    共享内存的创建 根据理论: 1. 共享内存允许两个或多个进程共享一给定的存储区,因为数据不需要来回复制,所以是最快的一种进程间通信机制.共享内存可以通过mmap()映射普通文件(特殊情况下还可以采用匿 ...

  8. linux进程间通信-共享内存

    转载:http://www.cnblogs.com/fangshenghui/p/4039720.html 一 共享内存介绍 共享内存可以从字面上去理解,就把一片逻辑内存共享出来,让不同的进程去访问它 ...

  9. Linux IPC POSIX 共享内存

    模型 #include <unistd.h> //for fstat() #include <sys/types.h> //for fstat() #include <s ...

随机推荐

  1. Scala Types 1

    在 Scala 中所有值都有一种对应的类型 单例类型 形式:value.type,返回类型 value / null 场景1:链式API调用时的类型指定 class Super { def m1(t: ...

  2. vue日历/日程提醒/html5本地缓存

    先上图 功能: 1.上拉日历折叠,展示周 2.左右滑动切换月 2.“今天”回到今天:“+”添加日程 3.localStorage存储日程 index,html <body> <div ...

  3. CDH5.14.4中的Hue集成HBase

    1.进入CDH中的给HBase添加Thrift Server角色实例, 为了方便, 将Thrift Server添加到Hue同一主机 2.HBase Thrift Server中选择主机cm1: 3. ...

  4. English--动词时态

    English|动词时态 时态是一个很玄乎的东西,要么是完全掌握,要么是不知所云. 在正式开始之前,大家需要明白汉语的谓语动词是不会随着时间与状态而变化.但是,英语的谓语动词会随着时间与状态发生变化. ...

  5. The Vertu of the Dyamaund钻石

    dyamaund and the English words dyamaund The Vertu of the Dyamaund": Gemstones, Knowledge and Va ...

  6. Cheat Engine 字节数组类型

    BIG5 编码:http://www.qqxiuzi.cn/zh/hanzi-big5-bianma.php 打开游戏 准备修改名字 查找BIG5码 藤 吉 开始扫描 使用字节数组类型扫描 新BIG5 ...

  7. 数据结构与算法—Trie树

    Trie,又经常叫前缀树,字典树等等.它有很多变种,如后缀树,Radix Tree/Trie,PATRICIA tree,以及bitwise版本的crit-bit tree.当然很多名字的意义其实有交 ...

  8. Python学习日记(四十二) Mysql数据库篇 十

    前言 当我们自己去写SQL代码的时候有时候会因为不熟练会导致效率低,再之后要进行许多的优化,并且操作也较为繁琐.因此ORM框架就能够解决上面的问题,它能根据自身的一些规则来帮助开发者去生成SQL代码. ...

  9. PHP的垃圾回收机制之引用计数

    1,介绍 php的垃圾回收机制(GC)是在PHP5之后出现的,而在PHP5.3版本之前使用的都是“引用计数”的方式.实现引用计数的实质就是在每个内存对象中都有一个计数器,当内存对象被变量引用时,计数器 ...

  10. Oracle数据表字段小写转大写

    BEGIN FOR c IN ( SELECT COLUMN_NAME cn FROM all_tab_columns WHERE table_name = '表名' ) loop BEGIN exe ...