OpenCV的IplImage转bmp
2015-09-17 11:56
337 查看
最近做项目,需要VB.NET调用,C++处理的图片。
如果c++处理的结果保存在磁盘上,然后Vb再读取的话,感觉过于占用磁盘IO,不绿色不环保。
因此想用内存映射文件的方式,进程之间传输图片。VB端先创建内存映射文件,然后调用C++程序,C++程序把处理的结果写入内存映射文件,VB端再对内存映射文件进行读取。
/article/1465573.html
进程之间传输图片,就会遇到一个问题,就是需要把图片以一种VB和C++都能认识的方式进行传递。
我就想把OpenCV的IplImage转成bmp,再以byte的形式传递给VB.NET端,vb再解析读取图片。
那么如何才能把IplImage转为bmp呢~
bmp文件由四部分组成:位图文件头,位图信息段,调色板,位图数据。
把这四个部分拼接到一起,就是一个完整的bmp文件了。
我想处理的图像是灰度图,也就是256色的bmp。灰度图的调色板大小为1024字节,内容是R=G=B分别从0到255,而rgbReserved一直为0.
testBitmap是要转为bmp的iplImage图片。为全局变量。
[cpp]
view plaincopyprint?
FILE *fpw;
//变量定义
BITMAPFILEHEADER strHead;
BITMAPINFOHEADER strInfo;
//初始化头文件。用0来填充内存区域
SecureZeroMemory(&strHead, sizeof(strHead));
SecureZeroMemory(&strInfo, sizeof(strInfo));
//初始化灰度图调色板
RGBQUAD *strPla = (RGBQUAD *)malloc(256*sizeof(RGBQUAD));//调色板的大小为1024字节
for (int i1 = 0; i1 < 256; i1++ ){
strPla[i1].rgbRed = strPla[i1].rgbGreen = strPla[i1].rgbBlue = i1;
strPla[i1].rgbReserved = 0;
}
//写bitmapFileHeader
strHead.bfType = 0x4d42;//写入字符"BM"
strHead.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 1024 + (testBitmap->width + 3)/4*4 * testBitmap->height;
strHead.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 1024;
//写bitmapInfoHeader
strInfo.biSize = sizeof(strInfo);
strInfo.biHeight = testBitmap->height;
strInfo.biWidth = testBitmap->width;
strInfo.biPlanes = 1;
strInfo.biBitCount = 8;
strInfo.biCompression = BI_RGB;
//保存bmp图片
if((fpw=fopen("M://abc.bmp","wb"))==NULL){
cout<<"create the bmp file error!"<<endl;
return NULL;
}
fwrite(&strHead,1,sizeof(strHead),fpw);
fwrite(&strInfo,1,sizeof(strInfo),fpw);
fwrite(strPla,1,1024,fpw);
写完了文件头、信息段及调色板,我们接下来要写数据啦。
OpenCV IplImage->imageData中的信息是正着写入的,而bmp中的数据是从下到上,从左到右写入的。
而且IplImage->imageData的大小为(IplImage->width + 3)/4*4 * IplImage->height * IplImage->nChannels.
IplImage->nChannels = 3时,每一个像素点由3个字节来表示。因为是灰度图,所以我猜想其中所写的内容是R=G=B各占一个像素,所以有了如下的写法
[cpp]
view plaincopyprint?
char *imgData = testBitmap->imageData;
char *data = NULL;
data = (char*)malloc((testBitmap->width + 3)/4*4 * testBitmap->height);
for(int i=0;i<testBitmap->height;i++) for(int j=0;j<(testBitmap->width + 3)/4*4;j++)
data[i * ((testBitmap->width + 3)/4*4) + j] = testBitmap->imageData[3*((testBitmap->height - i - 1) * ((testBitmap->width + 3)/4*4) + j)];
fwrite(data,1,(testBitmap->width + 3)/4*4 * testBitmap->height,fpw);
fclose(fpw);
IplImage->nChannels = 1时,每一个像素点由1个字节表示。
由于图像处理中,一般用的都是灰度图,所以创建图片的时候,最好就创建nChannels=1的iplImage
[cpp]
view plaincopyprint?
fullColorBitmap = cvLoadImage(fileNameFull, 1);
bmpWidth = fullColorBitmap->width;
bmpHeight = fullColorBitmap->height;
srcBitmap = cvCreateImage( cvSize(bmpWidth,bmpHeight), 8, 1);
cvCvtColor(fullColorBitmap, srcBitmap, CV_RGB2GRAY);
biHeight除了用于描述图像的高度之外,它还有另外一个用处,就是指明该图像是倒向的位图,还是正向的位图。如果该值是一个正数,说明图像是倒向的,即数据的第一行其实是图像的最后一行,如果该值是一个负数,则说明图像是正向的。大多数的BMP文件都是倒向的位图,也就是高度值是一个正数。
由于我们的位图数据是正着的,所以可以把biheight设置为负。
[cpp]
view plaincopyprint?
char *imgData = temp->imageData;
strInfo.biHeight = -strInfo.biHeight;
fwrite(imgData ,1,(testBitmap->width + 3)/4*4 * testBitmap->height,fpw);
fclose(fpw);
到此就可以把iplImage转为bmp格式的了~
转载于:/article/1465575.html
最近做项目,需要VB.NET调用,C++处理的图片。
如果c++处理的结果保存在磁盘上,然后Vb再读取的话,感觉过于占用磁盘IO,不绿色不环保。
因此想用内存映射文件的方式,进程之间传输图片。VB端先创建内存映射文件,然后调用C++程序,C++程序把处理的结果写入内存映射文件,VB端再对内存映射文件进行读取。
/article/1465573.html
进程之间传输图片,就会遇到一个问题,就是需要把图片以一种VB和C++都能认识的方式进行传递。
我就想把OpenCV的IplImage转成bmp,再以byte的形式传递给VB.NET端,vb再解析读取图片。
那么如何才能把IplImage转为bmp呢~
bmp文件由四部分组成:位图文件头,位图信息段,调色板,位图数据。
把这四个部分拼接到一起,就是一个完整的bmp文件了。
我想处理的图像是灰度图,也就是256色的bmp。灰度图的调色板大小为1024字节,内容是R=G=B分别从0到255,而rgbReserved一直为0.
testBitmap是要转为bmp的iplImage图片。为全局变量。
[cpp]
view plaincopyprint?
FILE *fpw;
//变量定义
BITMAPFILEHEADER strHead;
BITMAPINFOHEADER strInfo;
//初始化头文件。用0来填充内存区域
SecureZeroMemory(&strHead, sizeof(strHead));
SecureZeroMemory(&strInfo, sizeof(strInfo));
//初始化灰度图调色板
RGBQUAD *strPla = (RGBQUAD *)malloc(256*sizeof(RGBQUAD));//调色板的大小为1024字节
for (int i1 = 0; i1 < 256; i1++ ){
strPla[i1].rgbRed = strPla[i1].rgbGreen = strPla[i1].rgbBlue = i1;
strPla[i1].rgbReserved = 0;
}
//写bitmapFileHeader
strHead.bfType = 0x4d42;//写入字符"BM"
strHead.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 1024 + (testBitmap->width + 3)/4*4 * testBitmap->height;
strHead.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 1024;
//写bitmapInfoHeader
strInfo.biSize = sizeof(strInfo);
strInfo.biHeight = testBitmap->height;
strInfo.biWidth = testBitmap->width;
strInfo.biPlanes = 1;
strInfo.biBitCount = 8;
strInfo.biCompression = BI_RGB;
//保存bmp图片
if((fpw=fopen("M://abc.bmp","wb"))==NULL){
cout<<"create the bmp file error!"<<endl;
return NULL;
}
fwrite(&strHead,1,sizeof(strHead),fpw);
fwrite(&strInfo,1,sizeof(strInfo),fpw);
fwrite(strPla,1,1024,fpw);
FILE *fpw; //变量定义 BITMAPFILEHEADER strHead; BITMAPINFOHEADER strInfo; //初始化头文件。用0来填充内存区域 SecureZeroMemory(&strHead, sizeof(strHead)); SecureZeroMemory(&strInfo, sizeof(strInfo)); //初始化灰度图调色板 RGBQUAD *strPla = (RGBQUAD *)malloc(256*sizeof(RGBQUAD));//调色板的大小为1024字节 for (int i1 = 0; i1 < 256; i1++ ){ strPla[i1].rgbRed = strPla[i1].rgbGreen = strPla[i1].rgbBlue = i1; strPla[i1].rgbReserved = 0; } //写bitmapFileHeader strHead.bfType = 0x4d42;//写入字符"BM" strHead.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 1024 + (testBitmap->width + 3)/4*4 * testBitmap->height; strHead.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 1024; //写bitmapInfoHeader strInfo.biSize = sizeof(strInfo); strInfo.biHeight = testBitmap->height; strInfo.biWidth = testBitmap->width; strInfo.biPlanes = 1; strInfo.biBitCount = 8; strInfo.biCompression = BI_RGB; //保存bmp图片 if((fpw=fopen("M://abc.bmp","wb"))==NULL){ cout<<"create the bmp file error!"<<endl; return NULL; } fwrite(&strHead,1,sizeof(strHead),fpw); fwrite(&strInfo,1,sizeof(strInfo),fpw); fwrite(strPla,1,1024,fpw);
写完了文件头、信息段及调色板,我们接下来要写数据啦。
OpenCV IplImage->imageData中的信息是正着写入的,而bmp中的数据是从下到上,从左到右写入的。
而且IplImage->imageData的大小为(IplImage->width + 3)/4*4 * IplImage->height * IplImage->nChannels.
IplImage->nChannels = 3时,每一个像素点由3个字节来表示。因为是灰度图,所以我猜想其中所写的内容是R=G=B各占一个像素,所以有了如下的写法
[cpp]
view plaincopyprint?
char *imgData = testBitmap->imageData;
char *data = NULL;
data = (char*)malloc((testBitmap->width + 3)/4*4 * testBitmap->height);
for(int i=0;i<testBitmap->height;i++) for(int j=0;j<(testBitmap->width + 3)/4*4;j++)
data[i * ((testBitmap->width + 3)/4*4) + j] = testBitmap->imageData[3*((testBitmap->height - i - 1) * ((testBitmap->width + 3)/4*4) + j)];
fwrite(data,1,(testBitmap->width + 3)/4*4 * testBitmap->height,fpw);
fclose(fpw);
char *imgData = testBitmap->imageData; char *data = NULL; data = (char*)malloc((testBitmap->width + 3)/4*4 * testBitmap->height); for(int i=0;i<testBitmap->height;i++) for(int j=0;j<(testBitmap->width + 3)/4*4;j++) data[i * ((testBitmap->width + 3)/4*4) + j] = testBitmap->imageData[3*((testBitmap->height - i - 1) * ((testBitmap->width + 3)/4*4) + j)]; fwrite(data,1,(testBitmap->width + 3)/4*4 * testBitmap->height,fpw); fclose(fpw);
IplImage->nChannels = 1时,每一个像素点由1个字节表示。
由于图像处理中,一般用的都是灰度图,所以创建图片的时候,最好就创建nChannels=1的iplImage
[cpp]
view plaincopyprint?
fullColorBitmap = cvLoadImage(fileNameFull, 1);
bmpWidth = fullColorBitmap->width;
bmpHeight = fullColorBitmap->height;
srcBitmap = cvCreateImage( cvSize(bmpWidth,bmpHeight), 8, 1);
cvCvtColor(fullColorBitmap, srcBitmap, CV_RGB2GRAY);
fullColorBitmap = cvLoadImage(fileNameFull, 1); bmpWidth = fullColorBitmap->width; bmpHeight = fullColorBitmap->height; srcBitmap = cvCreateImage( cvSize(bmpWidth,bmpHeight), 8, 1); cvCvtColor(fullColorBitmap, srcBitmap, CV_RGB2GRAY);nChannels=1时,imageData和bmp的位图数据格式基本相同,仅仅是bmp的位图数据一般都是从下到上的。
biHeight除了用于描述图像的高度之外,它还有另外一个用处,就是指明该图像是倒向的位图,还是正向的位图。如果该值是一个正数,说明图像是倒向的,即数据的第一行其实是图像的最后一行,如果该值是一个负数,则说明图像是正向的。大多数的BMP文件都是倒向的位图,也就是高度值是一个正数。
由于我们的位图数据是正着的,所以可以把biheight设置为负。
[cpp]
view plaincopyprint?
char *imgData = temp->imageData;
strInfo.biHeight = -strInfo.biHeight;
fwrite(imgData ,1,(testBitmap->width + 3)/4*4 * testBitmap->height,fpw);
fclose(fpw);
char *imgData = temp->imageData; strInfo.biHeight = -strInfo.biHeight; fwrite(imgData ,1,(testBitmap->width + 3)/4*4 * testBitmap->height,fpw); fclose(fpw);
到此就可以把iplImage转为bmp格式的了~
转载于:/article/1465575.html
相关文章推荐
- Linux进程间同步与通信
- 记录assign weak copy的使用
- suse linux enterprise 单用户模式
- Emgu的Image(Of Gray,Byte)转OpenCV的IplImage
- 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