读取raw图像数据

michochina 2009-01-06 09:37:11
一个读取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;

}
...全文
981 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
michochina 2009-01-08
  • 打赏
  • 举报
回复
正如tan34035所说,需要一个归一化过程,很简单,已经解决,谢谢大家。
fxlcoy 2009-01-08
  • 打赏
  • 举报
回复
楼主所说的“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类型就真不知道该怎么处理,看来还得学习啊!
百事烟 2009-01-07
  • 打赏
  • 举报
回复
如果是用别人家的工业摄像头,用他们自带的SDK啊,为啥自己写?

还是你们公司就是做摄像头的?
michochina 2009-01-07
  • 打赏
  • 举报
回复
这里假设打开一幅图像。
raw图像的大小通过对话框用户输入(width=dlg.m_width; height=dlg.m_height;)得到,如果是float数据类型,那么这个DWORD dwImageSize = width*height*x中的x应该取多少呢,也就是读入的数据内存应该分配多大呢?
Show_Mike 2009-01-07
  • 打赏
  • 举报
回复
12bit的色彩位平面?
tan34035 2009-01-07
  • 打赏
  • 举报
回复
就是一个归一化的问题,将32为转化为24为简单来说就是除以255,都是简单的数学知识。当然归一化的方法有很多,看你的数据和需要取舍
michochina 2009-01-07
  • 打赏
  • 举报
回复
fxlcoy说的是彩色位数,24bit,32bit,... 关于这个在我的代码中可以看出已经定位24bit(bih.biBitCount = 24)。
打开raw数据时除了长和宽之外还需要另一个重要的参数就是数据类型,我所指的就是这个。这个数据类型可以是8bit int型,也可以是float(32bit)和double(64bit)型。
对于8bit型,一个像素只占用一个字节;32bit,一个像素占用4个字节。现在的问题是我可以打开8bit的数据,但是32bit的数据如何打开,应该是需要一个转换。
tan34035 2009-01-07
  • 打赏
  • 举报
回复
楼主的问题在与对计算机的显示理解不是很透彻,数据格式是一回事,显示是另外一个回事,目前计算机最高的显示是真彩色图像,即BGR(255,255,255).数据精度不会给显示带来效果,当然会为数据处理带来效果。

明白这点之后,显示问题就是黑白二值问题,灰度图像问题,和正彩色问题

我推荐LZ使用数据预处理的方式显示图像(我以前处理雷达图象数据的时候就是double数据),将数据归一化为0-255区间再用你的方式显示,至于归一化的方式有很多,简单的线性算法实现容易,如果需要进一步的讨论可以联系我。
fxlcoy 2009-01-07
  • 打赏
  • 举报
回复
看来我学习的范围有限,对你说的“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吧。

不晓得我理解的这些类型跟你说的类型有没有共通的地方。
菜牛 2009-01-07
  • 打赏
  • 举报
回复
说来说去如果你有数据格式的说明,就参照来做,看不懂就贴出来大家分析,靠猜是不行的,明显你说的和大家理解的不是一回事儿,说不定你的数据都是些权重值呢?
michochina 2009-01-07
  • 打赏
  • 举报
回复
你说的这些我都明白,谢谢你的解释。
但是”一般就是类似“inch”、“cm”这样的选项,这些单位下的width和height数据是可以为float型的,但通常应该搭配有分辨率的信息,如DPI(dot per inch)。”,这个和我强调的数据类型不一样,你所讨论的是8bit int型raw数据, 这种数据我已经可以打开并显示。我现在要打开的是float(32bit)和double(64bit)型raw数据,换句话说他们是按照这两种数据类型保存的,不是整数int型。
fxlcoy 2009-01-07
  • 打赏
  • 举报
回复
在数字图像的概念里面,图像是由一个一个的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。
michochina 2009-01-07
  • 打赏
  • 举报
回复
谢谢fxlcoy的回答,问题是现在数据类型不是整型而是float型也有double型的, 对于这两种情况下gray图像,ImageSize也是width*height?
fxlcoy 2009-01-07
  • 打赏
  • 举报
回复
“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图像的大小通过对话框用户输入,那么就应该限定用户输入的数据类型是整型。
菜牛 2009-01-06
  • 打赏
  • 举报
回复
DIBChannels是什么意思?RAW格式没有标准,也不知道你的代码对不对,应该先说明一下到底是怎样的格式。

19,469

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧