内存中读取bmp图片转换为IplImage格式
来源:互联网 发布:微软sql server官网 编辑:程序博客网 时间:2024/05/16 09:46
前些天做一个项目,其中要对读入内存的bmp图片转格式,转换为IplImage格式提供给OpenCV处理。内存中的图片是通过Socket从远程传输过来的。仅提供图片的首地址和长度,编写转换的接口。
由于bmp图像大多未经压缩,不同于jpeg的复杂压缩算法,直接从内存中读取bmp图片即可完成转换。首先了解bmp文件格式。
bmp文件由以下部分组成,1、文件信息头,2、bmp信息头,3、调色板(可选),4、图像数据。对于调色板,仅在深度为8时存在(每个像素有256种表示),当今的bmp图像色深普遍为24或32bit,3通道或4通道,因此大多无调色板。存在调色板的图片,其图像数据中每个像素为调色板的索引,因此处理调色板图片时,需要把索引值转换为标准像素值。由于bmp图像大多无调色板,因此该程序没有处理调色板特殊情况,同时也没有处理存在压缩的情况。
在网上找到一个IplImage和bmp相互转换的例子,是基于类对象封装的,但不够简洁,就编写了如下代码。
在工程中首先定义bmp文件头和信息头,注意内存对齐。
//文件头结构体#pragma pack(push)#pragma pack(2) //两字节对齐,否则bmp_fileheader会占16Byte//bmp文件头struct bmp_fileheader{unsigned short bfType; //文件标识 unsigned long bfSize; //文件大小 unsigned long bfReverved1; //保留 unsigned long bfOffBits;//数据偏移};//bmp信息头struct bmp_infoheader{unsigned long biSize;//信息头长度 unsigned long biWidth;//宽度unsigned long biHeight;//高度unsigned short biPlanes;//柱面数=1 unsigned short biBitCount;//像素位数unsigned long biCompression;//压缩说明unsigned long biSizeImage;//位图数据的大小unsigned long biXPelsPerMeter;//水平分辨率unsigned long biYpelsPerMeter;//垂直分辨率unsigned long biClrUsed;//使用的颜色数unsigned long biClrImportant;//重要的颜色数};#pragma pack(pop)其中部分参照了bmp文件格式说明。
定义基本格式后,就要对内存中的图像进行读取转换,定义如下函数:
IplImage *BMP2Ipl(unsigned char *src, int FileSize){ bmp_fileheader *Fileheader = (bmp_fileheader *)src;//检查错误assert(FileSize == Fileheader->bfSize);//判断是否是位图if(Fileheader->bfType!= 0x4d42)return NULL;//开始处理信息头bmp_infoheader *bmpheader = (bmp_infoheader *)(src + sizeof(bmp_fileheader));unsigned int width = bmpheader->biWidth;//宽度unsigned int height = bmpheader->biHeight;//高度unsigned int hSize = bmpheader->biSize;//信息头长度if(bmpheader->biBitCount < 24)return NULL;//支持真色彩32位if(bmpheader->biCompression != 0)return NULL;//不支持压缩算法//数据大小unsigned int dataByteSize = bmpheader->biSizeImage;//实际位图数据大小unsigned int rowByteSize = dataByteSize/height;//对齐的每行数据IplImage *img = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, bmpheader->biBitCount/8);//拷贝实际数据无颜色表unsigned char *gc = src + FileSize - rowByteSize;char *p = img->imageData;for(int i=0; i<height; ++i){ memcpy(p, gc, rowByteSize); p += rowByteSize; gc -= rowByteSize; }/**/////通道数处理//for(int i=0;i<height;++i)//{//for(int j=0;j<width;++j)//{//*(p+3*j+0) = *(gc+3*j+0);//通道0//*(p+3*j+1) = *(gc+3*j+1);//通道1//*(p+3*j+2) = *(gc+3*j+2);//通道2//}//p += rowByteSize; //gc -= rowByteSize;//}return img;}该函数不支持压缩的图片,由于bmp图像数据是倒置从文件尾部逐行存储,因此转换过程中需要倒置数据。
转换后的IplImage直接拿来用就可以了。
0 0
- 内存中读取bmp图片转换为IplImage格式
- 如何将读取到内存中的BMP图片转换为IplImage
- bmp图片转换为YUV422格式
- 读取BMP格式图片
- WINCE下将BMP格式图片转换为JPG格式
- 打开DICOM图片(图像内容转换为BMP格式)
- 将iPhone中tga格式的图片转换为其他格式(png、bmp等)的工具(Windows版本)
- 读取bmp图片为rgb
- opencv中使用cvSaveImage转换成bmp还是IplImage格式吗?还是可以直接成DIB格式?
- Opencv:IplImage转换为bmp的过程及相关问题
- Raw格式转换为Bmp格式
- PHP读取BMP格式图片的函数
- C语言读取BMP格式图片
- 读取bmp格式图片(二)
- 【原创】C语言读取BMP格式图片
- Flex 读取 bmp 格式的图片
- C语言读取BMP格式的图片
- PHP读取BMP格式图片的函数
- 消息中间件
- c# - Lazy<T> 延迟初始化对象
- Android出现CursorWindow: Window is full: requested allocation 1354087 bytes, free space 141032 bytes,
- Java编码的那些事儿
- Swift中的问号?和感叹号!
- 内存中读取bmp图片转换为IplImage格式
- 那些年遇到的那些css bug
- wifi功能 Android
- CocoaPods解决办法
- 查看Activity栈信息
- Xcode插件: MMNavigatorFont
- Git本地仓库操作
- 零散知识点
- 分享你最喜欢的技巧和提示(Xcode,Objective-C,Swift,C...等等)