BMP与IplImage相互转换

本文介绍如何在OpenCV中将IplImage结构转换为Windows的Bitmap结构,并提供了一个实用类BMP,用于实现IplImage与Bitmap之间的相互转换。通过具体的代码示例展示了转换过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面的function 可以把 IplImage 轉 Bitmap

////////////////////////////////////////////////////////////////////////////  
// - the IplImage "src" Image must have a IPL_DEPTH_8U depth              //  
//   and 1 or 3 channels                                                  //  
// - the convertion is done in regards to the ROI if it is set            //  
// - if you want to stretch your TBitmap ,specify width and height before //  
//   calling the function                                                 //  
////////////////////////////////////////////////////////////////////////////
  
bool __fastcall TForm1::IplImageToTBitmap(const IplImage *src,Graphics::TBitmap *dest)
{  
    if (!src || !dest)  
        return false;  
    IplImage *temp;  
    CvRect roi;
    if (src->roi)  
        roi=cvGetImageROI(src);  
    else 
        roi=cvRect(0,0,src->width,src->height);  
    temp=cvCreateImage(cvSize(roi.width,roi.height),IPL_DEPTH_8U,3);  
    if (src->nChannels!=3)  
        cvCvtColor(src,temp,CV_GRAY2RGB);  
    else 
        cvCopy(src,temp);  
    if (dest->Width==0 || dest->Height==0)  
    {  
        dest->Width = roi.width;  
        dest->Height = roi.height;  
    }  
    else 
    {  
        IplImage *temp1=cvCloneImage(temp);  
        cvReleaseImageData(temp);  
        cvInitImageHeader(temp,cvSize(dest->Width,dest->Height),IPL_DEPTH_8U,3,src->origin,4);
        cvCreateImageData(temp);  
        roi.width=dest->Width;  
        roi.height=dest->Height;  
        cvResize(temp1,temp);  
        cvReleaseImage(&temp1);  
    }  
    dest->PixelFormat=pf24bit;  
    try {      
        unsigned char *pLine;  
        int x,y;  
        for(y=0 ;y<roi.height;y++)  
        {  
            pLine = (unsigned char *)dest->ScanLine[y];  
            for(x=0 ;x <roi.width*3  ;x++)  
            {  
                pLine[x]= ((unsigned char*)(temp->imageData + temp->widthStep*y))[x];  
            }  
        }  
    }  
    catch(...)  
    {  
        ShowMessage("Error while converting ...");  
    }  
    cvReleaseImage(&temp);  
    return true;  
}
//-------------------------------------------------------------------

下面为示例代码:

Graphics::TBitmap *CapImg1 = new Graphics::TBitmap();
IplImageToTBitmap (img,CapImg1);
 Form1->Image1->Picture->Bitmap->Assign(CapImg1);
 delete CapImg1;

可用第一篇配置里边的例子改着试试,加个image控件,
//cvNamedWindow(filepath.c_str(),1);
    IplImage *src=cvLoadImage(filepath.c_str(),1);
    if(!src) return;
    Graphics::TBitmap *CapImg1 = new Graphics::TBitmap();
    IplImageToTBitmap(src,CapImg1);
    Form1->Image1->Picture->Bitmap->Assign(CapImg1);
    delete CapImg1;
    //cvShowImage(filepath.c_str(),src);
    cvWaitKey(0);
    cvReleaseImage(&src);
    //cvDestroyWindow(filepath.c_str());

---------------下面是一个BMP与IplIamge相互转换的类,来着opencv-------------

使用方法

  • 简要介绍:在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"
    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;
       }
    }
//-----------------------------------------------------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值