IplImage与位图的相互转换,Windows系统中一行像素所占的字节数为4的倍数

来源:互联网 发布:化妆品批号查询软件 编辑:程序博客网 时间:2024/05/22 05:24

1、位图----->IplImage

  BYTE *pt;
 pt=classify->m_pData;
 int m_Width = classify->GetWidth();
 int m_Height = classify->GetHeight();

// 首先由cvCreateImageHeader()创建IplImage图像头,制定图像的尺寸,深度和通道数;
 IplImage * copysrc = cvCreateImageHeader( cvSize( m_Width, m_Height) , IPL_DEPTH_8U, 1 ); 
 
//然后由cvSetData()根据BYTE*图像数据指针设置IplImage图像头的数据,其中LineBytes指定该IplImage图像每行占的字节数,对于1通道的IPL_DEPTH_8U图像,LineBytes可以等于width。
 //将copysrc->imageData的指针指向pt数据区的首地址 
 cvSetData( copysrc, pt, LineBytes); 

 cvSaveImage("c:\\pImg11.bmp",copysrc);

 Threshold(copysrc,copysrc);
 int LineBytes=(copysrc->width*8+31)/32*4; 
 
 for(int i=0;i<copysrc->height;i++)
 {
  for(int j=0;j<copysrc->width;j++)
  {
   copysrc->imageData[LineBytes*i+j]=255-copysrc->imageData[LineBytes*i+j];
   
  }
 }
 Invalidate();
 cvSaveImage("c:\\copysrc.bmp",copysrc);


 2、IpiImage--------->位图

#include <stdio.h>
#include <windows.h>
#include <shlwapi.h>

#include "cv.h"
#include "highgui.h"
#pragma comment(lib,"dllpipei.lib")

_declspec(dllimport)  char * num_Arial_regul(char* path,char* result,int mm);
_declspec(dllimport) void xOtsuSegment_Arial_regul(unsigned char *ImgSrc, const int iHeight, const int iWidth,int mmmm);

int main()
{
 char *result="";
 IplImage * tempimg=NULL;
 char *path=new char[100];
 char *filename=new char[100];
 for (int i=0;i<1;i++)
 {
  sprintf(path,"c:\\%d.bmp",i);
  
  if (!PathFileExists(path))
  {
   break;
  }
       
  tempimg=cvLoadImage(path,-1);
  uchar mmmm=0;
  // UCHAR *data=(uchar*)img->imageData;
  // int m=0;
 //第一次二值化
/// int thershold1=xOtsuSegment22huang(data, height, width,m);

  int LineBytes1=(((tempimg->width*8)+31)/32*4); 
  mmmm=(tempimg->imageData[LineBytes1 * (tempimg->height-1) +0]) + (tempimg->imageData[0]) + (tempimg->imageData[LineBytes1 * (tempimg->height-1) +tempimg->width-1]) + (tempimg->imageData[tempimg->width-1]);
  mmmm/=4;
  
  result=num_Arial_regul(path,result,mmmm);
  
  printf("%s\n",result);
 }
 
 delete []path;
 delete []filename;
 return 0;
 
}

 

说明:

由OpenCV的源代码可以看到imageData的数据类型是char*的。8U和8S是读取形式。

比如说内存里的 1111 1111.如果把它当做一个无符号的字符类型,那么就是255.如果把它看做一个有符号的就是-1了。

3、 int lineByte=(width * biBitCount/8+3)/4*4;

程序中有这么一句 int lineByte=(width * biBitCount/8+3)/4*4; 这是因为Windows系统中一行像素所占的字节数为4的倍数,因此不是4的倍数时要补充为4的倍数,这样在寻址每一个像素的时候,像素的地址为 pImage+i*lineByte+j ;

而循环控制语句for(j=0; j<width; j++)中仍用width,不用lineByte,因为补充的数据不是原图像数据,我们不需要处理。

原创粉丝点击