BMP与IplImage相互转换
使用方法
- 简要介绍:在windows编程中,很多图片信息,都是基于windows系统所谓的DIB(设备无关位图)的结构,其定义在结构体 BITMAPINFOHEADER 中。本方法可以讲 windows 定义的DIB 结构和Opencv内部定义的IPLImage结构做相互转化。
- 具体使用方法:将文件 bmp2ipl.h 和 bmp2ipl.cpp 添加到你的代码中。
代码
头文件
bmp2ipl.h
//bmp2ipl.h
#ifndef BMP2IPL_H
#define BMP2IPL_H
class BMP {
public:
BMP():bmpData(NULL) {
memset(&biHeader, 0, sizeof(biHeader));
}
BMP(const BMP & img);
BMP(const IplImage &img);
BMP(int width, int height, int bitCount);
~BMP(){ delete [] bmpData; }
bool CreateImage(const BITMAPINFOHEADER &biHeader);
//Export
IplImage * BMP2Ipl();
//void Show(HWND hWnd, int nID);
//void Show(CDC *pDC, CRect & rect);
//void Show(HWND hWnd);
void ReSize(int newW, int newH);
private:
void CopyData(char *dest, const char *src, int dataByteSize,
bool isConvert, int height);
// isConvert=true 进行顶左和底左之间的转换(顶左到底左或底左到顶左),否则不转换
// biSizeImage may be set to zero for BI_RGB bitmaps, so calculate it.
int ImgSize() {
return ( biHeader.biHeight * ((biHeader.biWidth * biHeader.biBitCount / 8 + 3) & (-4)));
}
public:
void Clear();
BITMAPINFOHEADER biHeader;
unsigned char * bmpData;
};
#endif
实现文件bmp2ipl.cpp
#include "bmp2ipl.h" /**************************************************************************************************
* *
* NOTE: *
* Only use the "8 bit, 1 or 3 channels" image, the BitMap use LowerLeft (底左), *
* the IplImage use TopLeft (顶左) *
* IplImage: *
* nChannels = 1 or 3 number of channels *
* depth = IPL_DEPTH_8U pixel depth (8 bit), IPL_DEPTH_8U=8 *
* dataOrder = 0 交叉存取颜色通道 *
* origin = IPL_ORIGIN_TL 图像数据保存形式,IPL_ORIGIN_BL底左结构, IPL_ORIGIN_TL顶左结构 *
* align = 4 行数据对齐方式,保证下一行数据从整4字节位置开始 *
* width *
* height *
* widthStep 图像数据行大小,单位字节 *
* imageSize 图像数据大小(=height*widthStep),单位字节 *
* imageData 指向图像数据区,char * *
* BITMAPINFOHEADER: *
* biSize Specifies the number of bytes required by the structure *
* biWidth *
* biHeight(>0) biHeight>0底左结构;biHeight<0顶左结构 *
* biPlanes = 1 Specifies the number of planes for the target device. This value *
* must be set to 1. *
* biBitCount =8 or 24 bits-per-pixel,8-(pixelDepth=8,channels=1), *
* 24-(pixelDepth=8,channels=3) *
* biCompression = BI_RGB An uncompressed format *
* biSizeImage Specifies the size, in bytes, of the image.This may be set to zero *
* for BI_RGB bitmaps. *
* biXPelsPerMeter = 0 *
* biYPelsPerMeter = 0 *
* biClrUsed = 0 *
* biClrImportant = 0 *
* *
***************************************************************************************************/
BMP::BMP(const BMP & img) { if(!IsSupport(img)) { BMP(); return; } //biHeader = img.biHeader;
PBITMAPINFOHEADER pBmpH = (PBITMAPINFOHEADER)&img.biHeader; memcpy(&biHeader, pBmpH, sizeof(BITMAPINFOHEADER)); biHeader.biSizeImage = ImgSize(); bool isLowerLeft = biHeader.biHeight>0; //int rowSize=0;
if(!isLowerLeft) biHeader.biHeight=-biHeader.biHeight; if(bmpData!=NULL) delete[] bmpData;
bmpData = new unsigned char [biHeader.biSizeImage]; //memcpy(bmpData, img.bmpData, img.biHeader.biSizeImage); CopyData((char *)bmpData, (char*)img.bmpData, biHeader.biSizeImage,
!isLowerLeft, biHeader.biHeight); }
BMP::BMP(const IplImage &img) { if(!IsSupport(img)) { BMP();
return; } bool isTopLeft = (img.origin == IPL_ORIGIN_TL);
biHeader.biSize = sizeof(BITMAPINFOHEADER); biHeader.biWidth = img.width; biHeader.biHeight = img.height;
biHeader.biPlanes = 1; biHeader.biBitCount = img.depth * img.nChannels; biHeader.biCompression = BI_RGB; biHeader.biSizeImage = img.imageSize; biHeader.biXPelsPerMeter = 0;
biHeader.biYPelsPerMeter = 0; biHeader.biClrUsed = 0;
biHeader.biClrImportant = 0; if(bmpData!=NULL) delete[] bmpData;
bmpData = new unsigned char [img.imageSize]; //memcpy(bmpData, img.ImageData, img.imageSize);
CopyData((char*)bmpData, (char*)img.imageData, img.imageSize,
isTopLeft, img.height); /*int i,j;
CvScalar s;
for(i=0;i<img.width;i++)
for(j=0;j<img.height;j++){
s=cvGet2D(&img,i,j);
}
*/ } BMP::BMP(int width, int height, int bitCount) {
if(bitCount!=8 && bitCount!=24) return;
biHeader.biSize = sizeof(BITMAPINFOHEADER);
biHeader.biWidth = width; biHeader.biHeight = height;
biHeader.biPlanes = 1; biHeader.biBitCount = bitCount;
biHeader.biCompression = BI_RGB; biHeader.biSizeImage = ImgSize();
biHeader.biXPelsPerMeter = 0; biHeader.biYPelsPerMeter = 0;
biHeader.biClrUsed = 0; biHeader.biClrImportant = 0;
if(bmpData!=NULL) delete[] bmpData;
bmpData = new unsigned char [biHeader.biSizeImage]; Clear(); }
// dest: the destination image // dataByteSize: the Source image
// height: source image height
void BMP::CopyData(char *dest, const char *src, int dataByteSize,
bool isConvert, int height) { char * p = dest; if(!isConvert) { memcpy(dest, src, dataByteSize); return; } if(height<=0) return; //int height = dataByteSize/rowByteSize;
int rowByteSize = dataByteSize / height;
src = src + dataByteSize - rowByteSize ; for(int i=0; i<height; i++) { memcpy(dest, src, rowByteSize);
dest += rowByteSize; src -= rowByteSize; } }
IplImage * BMP::BMP2Ipl() { if(!IsSupport(*this)) return NULL;
IplImage *iplImg; int height; bool isLowerLeft = biHeader.biHeight>0; height = (biHeader.biHeight>0) ? biHeader.biHeight : -biHeader.biHeight;
iplImg = cvCreateImage( cvSize(biHeader.biWidth, height), IPL_DEPTH_8U, biHeader.biBitCount / 8);
//iplImg = cvCreateImageHeader( cvSize(biHeader.biWidth, height), IPL_DEPTH_8U, biHeader.biBitCount / 8);
//cvSetData(iplImg,(char*)bmpData,biHeader.biSizeImage/height);
CopyData( iplImg->imageData, (char*)bmpData, biHeader.biSizeImage,
isLowerLeft, height); /*int i,j;
CvScalar s;
int channels=biHeader.biBitCount / 8;
int step=(biHeader.biWidth*channels+3) & -4;
int loc=0;
for(i=0;i<iplImg->height;i++){
for(j=0;j<iplImg->width;j++){
loc=i*step + j*channels;
s.val[0]=bmpData[loc];
if(channels==3){
s.val[1]=bmpData[loc+1];
s.val[2]=bmpData[loc+2];
}
cvSet2D(iplImg,i,j,s);
}
}*/ return iplImg; } void BMP::Clear() {
if(bmpData == NULL) return; memset(bmpData, 0, ImgSize()); }
void BMP::ReSize(int newW, int newH) { biHeader.biWidth = newW;
biHeader.biHeight = newH; biHeader.biSizeImage = ImgSize(); if(bmpData!=NULL) delete[] bmpData;
bmpData = new unsigned char [biHeader.biSizeImage]; Clear(); }
bool BMP::CreateImage(const BITMAPINFOHEADER &bih) { memset(&biHeader,0,sizeof(BITMAPINFOHEADER)); delete[] bmpData;
bmpData = NULL; memcpy(&biHeader, &bih, sizeof(BITMAPINFOHEADER));
biHeader.biSizeImage = ImgSize();
bmpData = new unsigned char [ biHeader.biSizeImage ];
if(bmpData == NULL) return false; else{ Clear(); return true; } }
本文介绍了一种在Windows编程环境下将BMP格式图片与OpenCV中的IplImage结构相互转换的方法。通过自定义BMP类实现了不同图像格式间的转换,并提供了创建、调整尺寸等实用功能。
1056

被折叠的 条评论
为什么被折叠?



