Emgu的Image(Of Gray,Byte)转OpenCV的IplImage
2015-09-17 11:53
423 查看
最近在做VB.Net和C++进程间用内存映射文件通信的项目。
VB.NET和C++之间的通信就需要传送统一的文件格式,让VB和C++都能解析。
就会遇到这样地问题:VB.NET中Emgu的Image(Of Gray,Byte)怎么才能转为C++中OpenCV的IplImage格式呢?
进程间通信,我用的是内存映射文件的方式,在本文中就不多做讨论了。主要讨论两种格式之间的转换。
首先VB端创建内存映射文件,把Image(Of Gray,Byte).MIplImage.imageDataOrigin指针指向的内存写入内存映射文件中
因为本文的研究对象都是灰度图,所以MIplImage.imageDataOrigin中存放的都是0-255的灰度值。方向是以左上角为起点,横向扫描。
[vb]
view plaincopyprint?
'imgbytes是Byte()类型的图片文件
Dim img As Image(Of Gray, Byte) = New Image(Of Gray, Byte)(Image.FromStream(New MemoryStream(imgbytes)))
'图片的宽度需是4字节的倍数
Dim mmfImgSize As Integer = Int((img.Width + 3) / 4) * 4 * img.Height
Dim mmfPaper As MemoryMappedFile = MemoryMappedFile.CreateNew("test1", mmfImgSize)
Using Stream As MemoryMappedViewStream = mmfPaper.CreateViewStream()
'把需要通信的图片写入内存映射文件中。宽高通过C++可执行文件的参数传递
Dim writer As BinaryWriter = New BinaryWriter(Stream)
Dim byteSize As Integer = Int((img.Width + 3) / 4) * 4 * img.Height
Dim imageDataByte(byteSize - 1) As Byte
'读取指针中的内容
Marshal.Copy(img.MIplImage.imageDataOrigin, imageDataByte, 0, byteSize)
writer.Write(imageDataByte)
End Using
因为是灰度图,所以通道数我们默认设为1.图片的宽和高,我用的是调用C++命令行可执行文件的参数的形式传递的。
以下是C++端的代码:
char *mmfName是内存映射文件的文件名
char *imgWidth是图片的宽度
char *imgHeight是图片的高
[cpp]
view plaincopyprint?
int mmfImgSize = (atoi(imgWidth) + 3)/4 * 4 *atoi(imgHeight);
bmpWidth = atoi(imgWidth);
bmpHeight = atoi(imgHeight);
//需要将char转为LPCWSTR
WCHAR wszClassName[100] = {0};
memset(wszClassName,0,sizeof(wszClassName));
MultiByteToWideChar(CP_ACP,0,mmfName,strlen(mmfName)+1,wszClassName,sizeof(wszClassName)/sizeof(wszClassName[0]));
//打开共享的文件对象。
HANDLE m_hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, wszClassName);
//获得映射视图
char* mmfm_base_address = (char*)MapViewOfFile(m_hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, mmfImgSize);
DWORD error_code;
if(mmfm_base_address == NULL){
/*error_code = GetLastError();
if(error_code != SUCCESS){
cout<<"error code "<<error_code<<endl;
}*/
return false;
}else{
IplImage *srcBitmap = cvCreateImageHeader(cvSize(bmpWidth,bmpHeight),IPL_DEPTH_8U,1);
cvSetData(srcBitmap,mmfm_base_address,(bmpWidth + 3)/4*4); //第3个参数是行字节数
return true;
}
以上就完成了Emgu的Image(Of Gray,Byte)转OpenCV的IplImage。
但是还需注意,如果图片是由cvCreateImage初始化的,那么用cvReleaseImage来释放;
如果图片是由cvCreateImageHeader初始化的文件头,那么用cvReleaseImageheader(&iplImage)来释放。
初始化后的imageDataOrigin和imageData指向的是同一个地址。
openCV论坛上的大神解释的是:“预留数据接口吧!上面有这么一句话:IplImage结构来自于Intel Image Processing Libray(是其本身所具有的)。OpenCV只支持期中的一个子集。”
转载于:/article/1465567.html
最近在做VB.Net和C++进程间用内存映射文件通信的项目。
VB.NET和C++之间的通信就需要传送统一的文件格式,让VB和C++都能解析。
就会遇到这样地问题:VB.NET中Emgu的Image(Of Gray,Byte)怎么才能转为C++中OpenCV的IplImage格式呢?
进程间通信,我用的是内存映射文件的方式,在本文中就不多做讨论了。主要讨论两种格式之间的转换。
首先VB端创建内存映射文件,把Image(Of Gray,Byte).MIplImage.imageDataOrigin指针指向的内存写入内存映射文件中
因为本文的研究对象都是灰度图,所以MIplImage.imageDataOrigin中存放的都是0-255的灰度值。方向是以左上角为起点,横向扫描。
[vb]
view plaincopyprint?
'imgbytes是Byte()类型的图片文件
Dim img As Image(Of Gray, Byte) = New Image(Of Gray, Byte)(Image.FromStream(New MemoryStream(imgbytes)))
'图片的宽度需是4字节的倍数
Dim mmfImgSize As Integer = Int((img.Width + 3) / 4) * 4 * img.Height
Dim mmfPaper As MemoryMappedFile = MemoryMappedFile.CreateNew("test1", mmfImgSize)
Using Stream As MemoryMappedViewStream = mmfPaper.CreateViewStream()
'把需要通信的图片写入内存映射文件中。宽高通过C++可执行文件的参数传递
Dim writer As BinaryWriter = New BinaryWriter(Stream)
Dim byteSize As Integer = Int((img.Width + 3) / 4) * 4 * img.Height
Dim imageDataByte(byteSize - 1) As Byte
'读取指针中的内容
Marshal.Copy(img.MIplImage.imageDataOrigin, imageDataByte, 0, byteSize)
writer.Write(imageDataByte)
End Using
'imgbytes是Byte()类型的图片文件 Dim img As Image(Of Gray, Byte) = New Image(Of Gray, Byte)(Image.FromStream(New MemoryStream(imgbytes))) '图片的宽度需是4字节的倍数 Dim mmfImgSize As Integer = Int((img.Width + 3) / 4) * 4 * img.Height Dim mmfPaper As MemoryMappedFile = MemoryMappedFile.CreateNew("test1", mmfImgSize) Using Stream As MemoryMappedViewStream = mmfPaper.CreateViewStream() '把需要通信的图片写入内存映射文件中。宽高通过C++可执行文件的参数传递 Dim writer As BinaryWriter = New BinaryWriter(Stream) Dim byteSize As Integer = Int((img.Width + 3) / 4) * 4 * img.Height Dim imageDataByte(byteSize - 1) As Byte '读取指针中的内容 Marshal.Copy(img.MIplImage.imageDataOrigin, imageDataByte, 0, byteSize) writer.Write(imageDataByte) End Using这一部分包含了图片中每个像素点的灰度值。但是并不包含图像的头文件。C++端想新建IplImage的话,还需知道图片的宽高以及通道数。
因为是灰度图,所以通道数我们默认设为1.图片的宽和高,我用的是调用C++命令行可执行文件的参数的形式传递的。
以下是C++端的代码:
char *mmfName是内存映射文件的文件名
char *imgWidth是图片的宽度
char *imgHeight是图片的高
[cpp]
view plaincopyprint?
int mmfImgSize = (atoi(imgWidth) + 3)/4 * 4 *atoi(imgHeight);
bmpWidth = atoi(imgWidth);
bmpHeight = atoi(imgHeight);
//需要将char转为LPCWSTR
WCHAR wszClassName[100] = {0};
memset(wszClassName,0,sizeof(wszClassName));
MultiByteToWideChar(CP_ACP,0,mmfName,strlen(mmfName)+1,wszClassName,sizeof(wszClassName)/sizeof(wszClassName[0]));
//打开共享的文件对象。
HANDLE m_hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, wszClassName);
//获得映射视图
char* mmfm_base_address = (char*)MapViewOfFile(m_hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, mmfImgSize);
DWORD error_code;
if(mmfm_base_address == NULL){
/*error_code = GetLastError();
if(error_code != SUCCESS){
cout<<"error code "<<error_code<<endl;
}*/
return false;
}else{
IplImage *srcBitmap = cvCreateImageHeader(cvSize(bmpWidth,bmpHeight),IPL_DEPTH_8U,1);
cvSetData(srcBitmap,mmfm_base_address,(bmpWidth + 3)/4*4); //第3个参数是行字节数
return true;
}
int mmfImgSize = (atoi(imgWidth) + 3)/4 * 4 *atoi(imgHeight); bmpWidth = atoi(imgWidth); bmpHeight = atoi(imgHeight); //需要将char转为LPCWSTR WCHAR wszClassName[100] = {0}; memset(wszClassName,0,sizeof(wszClassName)); MultiByteToWideChar(CP_ACP,0,mmfName,strlen(mmfName)+1,wszClassName,sizeof(wszClassName)/sizeof(wszClassName[0])); //打开共享的文件对象。 HANDLE m_hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, wszClassName); //获得映射视图 char* mmfm_base_address = (char*)MapViewOfFile(m_hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, mmfImgSize); DWORD error_code; if(mmfm_base_address == NULL){ /*error_code = GetLastError(); if(error_code != SUCCESS){ cout<<"error code "<<error_code<<endl; }*/ return false; }else{ IplImage *srcBitmap = cvCreateImageHeader(cvSize(bmpWidth,bmpHeight),IPL_DEPTH_8U,1); cvSetData(srcBitmap,mmfm_base_address,(bmpWidth + 3)/4*4); //第3个参数是行字节数 return true; }
以上就完成了Emgu的Image(Of Gray,Byte)转OpenCV的IplImage。
但是还需注意,如果图片是由cvCreateImage初始化的,那么用cvReleaseImage来释放;
如果图片是由cvCreateImageHeader初始化的文件头,那么用cvReleaseImageheader(&iplImage)来释放。
初始化后的imageDataOrigin和imageData指向的是同一个地址。
openCV论坛上的大神解释的是:“预留数据接口吧!上面有这么一句话:IplImage结构来自于Intel Image Processing Libray(是其本身所具有的)。OpenCV只支持期中的一个子集。”
转载于:/article/1465567.html
相关文章推荐
- Linux修改/etc/hosts
- Linux系统下Git操作命令整理
- 如何使用PHP对网站验证码进行破解
- vs2008+opencv2.4.9 +win7X64位系统 2.
- Linux2.6.32驱动笔记(2)字符设备驱动编程模型
- OpenERP 搜索过滤: 过去三个月
- Nginx源码分析系列2:系统错误提示信息汇总
- linux 批量文件重命名
- Linux 文件查找
- L7.3 linux shell 循环语句总结
- centos下SNMP的安装与使用
- linux(centOS)下安装nodejs
- CFile用Open打开文件后用Read读取进FileStream
- TopoSort
- 阿里云主机 CentOS6.5 安装Mysql php Apache
- Hadoop —— Ubuntu单机环境部署Hadoop1.2.1
- jprofiler监控linux下的tomcat
- [转]在Linux CentOS 6.6上安装Python 2.7.9
- Linux安装rar和unrar命令,及使用说明
- Linux内核OOM机制的详细分析