一个读取raw格式图像数据并显示的函数,但是显示不正确,哪位高手给看看问题出在哪,或者是哪里可能有问题。谢谢
/*************************************************************************
*
*  Function:  ReadRAWFile (CFile&)
*  
*  Purpose:  Reads in the specified RAW file into a global chunk of
*      memory.
*          
*            Returns:  A handle to a dib (hDIB) if successful.
*            NULL if an error occurs.
*            
*            Comments:  BITMAPFILEHEADER is stripped off of the DIB.
*            Everything from the end of the BITMAPFILEHEADER structure 
*            on is returned in the global memory handle.
*              
**************************************************************************/
HDIB ReadRAWFile(CFile& file)
{
  double min,max;
  int width,height;  CRawdlg dlg;
  if (dlg.DoModal() != IDOK) return FALSE;
  width=dlg.m_width;
  height=dlg.m_height;
  //Allocate memory for the image
  DWORD dwImageSize = width*height*12;// 12=DIBChannels
  BYTE* pImageData = new BYTE[dwImageSize];  file.Read(pImageData,dwImageSize);
  // Setup the DIB with the correct details
  BITMAPINFO bmi;
  BITMAPINFOHEADER& bih = bmi.bmiHeader;
  ZeroMemory(&bih, sizeof(BITMAPINFOHEADER));
  bih.biSize = sizeof(BITMAPINFOHEADER);
  bih.biWidth = width;
  bih.biHeight= height;
  bih.biCompression = BI_RGB;
  bih.biPlanes = 1;
  bih.biBitCount = 24;   // Allocate memory for DIB
  DWORD dwBmpBitsSize = WIDTHBYTES(width*24)*height;
  HDIB hDIB = (HDIB) ::GlobalAlloc(GHND, bih.biSize + dwBmpBitsSize);
  if (hDIB == 0)
  {
  TRACE(_T("Could not allocate memory for the DIB while loading from file!\n"));
  delete [] pImageData;
    return NULL;
  }   LPSTR pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
  if (pDIB == 0)
  {
  TRACE(_T("Could not lock memory for the DIB while loading from file!\n"));
  delete [] pImageData;
    return NULL;
  } //Copy over the header to the DIB
  CopyMemory(pDIB, &bmi.bmiHeader, bih.biSize);   //Copy the DIB bits from the user buffer into the DIB
  BYTE* pBmp = (BYTE*) (pDIB + bih.biSize);
  for (int j=0; j<height; j++)
  {
    int nDepthInOffset = j*width*3;
    int nDepthOutOffset = (height-j-1)*WIDTHBYTES(width*24); 
    for (int i=0; i<width; i++)
    {
      int nInOffset = nDepthInOffset + i*3;
      int nOutOffset = nDepthOutOffset + i*3;  
      pBmp[nOutOffset]   = pImageData[nInOffset];
      pBmp[nOutOffset+1] = pImageData[nInOffset+1];
      pBmp[nOutOffset+2] = pImageData[nInOffset+2];
    }
  }  //Delete the memory used to load the jpeg prior to transfering to the DIB
delete [] pImageData;  ::GlobalUnlock((HGLOBAL) hDIB);
  return hDIB;}

解决方案 »

  1.   

    DIBChannels是什么意思?RAW格式没有标准,也不知道你的代码对不对,应该先说明一下到底是怎样的格式。
      

  2.   

    如果是用别人家的工业摄像头,用他们自带的SDK啊,为啥自己写?还是你们公司就是做摄像头的?
      

  3.   

    这里假设打开一幅图像。
    raw图像的大小通过对话框用户输入(width=dlg.m_width;   height=dlg.m_height;)得到,如果是float数据类型,那么这个DWORD dwImageSize = width*height*x中的x应该取多少呢,也就是读入的数据内存应该分配多大呢?
      

  4.   

    “DWORD dwImageSize = width*height*12;// 12=DIBChannels”这个我不是很理解,不晓得你所说的raw图像是什么格式的。我所接触的raw图像,RGB图像的文件格式就是R、G、B、R、G、B……R、G、B这样的排列方式,gray图像的文件格式就是每个pixel的level值顺序排列,其中每个R或G或B或level值都是以一个BYTE存储的,所以RGB图像的ImageSize就是width*3*height,而gray图像的ImageSize就是width*height,单位BYTE。如果raw图像的大小通过对话框用户输入,那么就应该限定用户输入的数据类型是整型。
      

  5.   

    谢谢fxlcoy的回答,问题是现在数据类型不是整型而是float型也有double型的, 对于这两种情况下gray图像,ImageSize也是width*height?
      

  6.   

    在数字图像的概念里面,图像是由一个一个的pixel顺序排列而成的,我们所说的width和height如果没有明确指定单位的话通常都是指的pixel的个数,如果是这样定义的话,width和height的值应该都是整数才有意义,因为不会有“0.5个pixel”这样的概念。如果CRawdlg是自己创建的,允许用户输入的只有width和height的话,可以在输入控件内限定只能输入整数,表示图像横向纵向的pixel个数;如果CRawdlg不是自己创建的,只能被动接受数据,那就要看看dlg上还有没有诸如“单位”这样的信息,一般就是类似“inch”、“cm”这样的选项,这些单位下的width和height数据是可以为float型的,但通常应该搭配有分辨率的信息,如DPI(dot per inch)。总之,图像数据放到内存中,图像的width和height信息一定是用整数表示的,指的是图像横向纵向的pixel个数。至于RGB图像的ImageSize是width*3*height,而gray图像的ImageSize是width*height,原因是RGB图像用3个BYTE表示一个pixel,gray图像只需要一个BYTE就可以表示一个pixel。
      

  7.   

    你说的这些我都明白,谢谢你的解释。
    但是”一般就是类似“inch”、“cm”这样的选项,这些单位下的width和height数据是可以为float型的,但通常应该搭配有分辨率的信息,如DPI(dot per inch)。”,这个和我强调的数据类型不一样,你所讨论的是8bit int型raw数据, 这种数据我已经可以打开并显示。我现在要打开的是float(32bit)和double(64bit)型raw数据,换句话说他们是按照这两种数据类型保存的,不是整数int型。
      

  8.   

    看来我学习的范围有限,对你说的“float(32bit)和double(64bit)型raw数据”不是很理解。我理解的图像数据如下:(24bit以下省略)
    24bit彩色 - R(8bit)、G(8bit)、B(8bit)
    32bit彩色 - R(8bit)、G(8bit)、B(8bit)、A(8bit,颜色的alpha 通道,透明信息)
    48bit彩色 - R(16bit)、G(16bit)、B(16bit)至于64bit的数据,我想可能在48bit基础上多一个16bit的A channel吧。不晓得我理解的这些类型跟你说的类型有没有共通的地方。
      

  9.   

    楼主的问题在与对计算机的显示理解不是很透彻,数据格式是一回事,显示是另外一个回事,目前计算机最高的显示是真彩色图像,即BGR(255,255,255).数据精度不会给显示带来效果,当然会为数据处理带来效果。明白这点之后,显示问题就是黑白二值问题,灰度图像问题,和正彩色问题我推荐LZ使用数据预处理的方式显示图像(我以前处理雷达图象数据的时候就是double数据),将数据归一化为0-255区间再用你的方式显示,至于归一化的方式有很多,简单的线性算法实现容易,如果需要进一步的讨论可以联系我。
      

  10.   

      fxlcoy说的是彩色位数,24bit,32bit,... 关于这个在我的代码中可以看出已经定位24bit(bih.biBitCount = 24)。  
      打开raw数据时除了长和宽之外还需要另一个重要的参数就是数据类型,我所指的就是这个。这个数据类型可以是8bit int型,也可以是float(32bit)和double(64bit)型。
      对于8bit型,一个像素只占用一个字节;32bit,一个像素占用4个字节。现在的问题是我可以打开8bit的数据,但是32bit的数据如何打开,应该是需要一个转换。
      

  11.   

    楼主所说的“float(32bit)和double(64bit)型raw数据”是不是表示一个pixel的色彩信息全部组合成一个float数据或者double数据?我倒是见过将R、G、B组合成一个DWORD型(32bit int)数值的,通过下面这种方式
    DWORD color = (DWORD)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16));
    从这个color值分析出R、G、B则通过如下
    R = (BYTE)(color);
    G = (BYTE)(((WORD)(color)) >> 8);
    B = (BYTE)((rgb)>>16);至于float和double类型就真不知道该怎么处理,看来还得学习啊!
      

  12.   

    正如tan34035所说,需要一个归一化过程,很简单,已经解决,谢谢大家。