| 在灰度图像处理的过程中,很多情况下都要使用图像采集卡,以把模拟的图像转化为数字图像,供计算机处理。但是,有一些图像采集卡,必须将VGA设置成 256 色的显示方式,才能正确的实时显示活动的灰度图像。另一方面,由于Windows 操作系统中有20个保留色,所以采集到的图像数据有时会进入Windows 的保留色,也就是在显示灰度图像的时候会出现伪彩色,给256级灰度图像的显示带来了不必要的麻烦。这种限制有时会迫使微视在编程时人为的去掉两端的各十个灰度级,也就是以牺牲一定信息量的代价换取避免出现伪彩。
但是这样带来两个不利之处∶一、使图像所包含的信息量受损,这无疑对图像处理是很不利的。二、会给应用程序的使用带来不必要的麻烦。比如,微视可能要在不同的应用程序之间切换,而有的应用程序需要将WGA设置成真彩色的显示模式才能取得好的显示效果或才能运行,而在灰度图像处理中,需要将显示模式设置成256色才能正确的实时显示图像,这就构成了一对矛盾。在程序之间的频繁切换是一件很令人头疼的事。
在采用微视V_V2A卡编程的过程中,由于此卡对VGA不同显示模式的支持能力,微视可以很好地解决以上问题。
首先,V2A卡支持在真彩色模式下实时显示、采集灰度图像,此时,先将显卡设置成真彩色(24 或 32 位)显示模式,再在程序中设置适当的调色板,就可以很好的进行实时显示。由于是真彩色的显示方式,图像的视觉效果比 256 色显示方式下更好(能够真正显示8Bit)。
其次,在显示采集到的灰度图像时,由于已将显示卡设置成真彩色,所以不能再使用 MFC 中 CDC 类的 bitblt 或 stretchchblt等与设备相关的图像显示函数,使用它们将会得到错误的显示结果。微视可以使用功能更强大的 windows API 函数 ::StretchDIBits(...)来达到微视显示的目的。
StretchDIBits() 是功能非常强大的与设备无关的显示函数。通过适当的参数,它能缩放、水平或垂直镜像显示图像。其调用方法如下:
int StretchDIBits( HDC hdc, // 目的设备句柄
int XDest, // 目的矩形左上角的x坐标
int YDest, // 目的矩形左上角的y坐标
int nDestWidth, // 目的矩形的宽度
int nDestHeight,// 目的矩形的高度
int XSrc, // 源矩形左上角的x坐标
int YSrc, // 源矩形左上角的y坐标
int nSrcWidth, // 源矩形的宽度
int nSrcHeight, // 源矩形的高度
CONST vOID *lpBits, // 位图数据位的地址
CONST BITMAPINFO *lpBitsInfo, //位图数据的地址
UINT iUsage, // 颜色表用法
DWORD dwRop // 光栅操作码
);
参数的具体说明请参见该函数说明。
需要说明的参数是 lpBitsInfo,这是一个指向 BITMAPINFO 结构的指针。该结构的填写针对灰度图像请参见以下例程。
void CMyview::DisplayImage()
{
CDC* pDC;
CSize m_sizeBmp = CSize(512, 512);
PDC=GetDC();
Long lImgLen;
LImgLen = (long)m_sizeBmp.cx*m_sizeBmp.cy;
LPBITMAPINFO pbmi = (LPBITMAPINFO)new BYTE[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
Pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
Pbmi->bmiHeader.biWidth = m_sizeBmp.cx;
Pbmi->bmiHeader.biHeight = m_sizeBmp.cy;
Pbmi->bmiHeader.biPlanes = 1;
Pbmi->bmiHeader.biBitCount = 8;
Pbmi->bmiHeader.biCompression = 0;
Pbmi->bmiHeader.biSizeImage = 0;
Pbmi->bmiHeader.biXPelsPerMeter = 0;
Pbmi->bmiHeader.biYPelsPerMeter = 0;
Pbmi->bmiHeader.biClrUsed = 0;
Pbmi->bmiHeader.biClrImportant = 0;
For(int i=0; i<256; i++) {
pbmi->bmiColors[i].rgbBlue = i;
pbmi->bmiColors[i].rgbGreen = i;
pbmi->bmiColors[i].rgbRed = i;
pbmi->bmiColors[i].rgbReserved = 0;
}
//函数中的参数 m_pImgData 为采集的图像数据的指针
::StretchDIBits(pDC->GetSafeHdc(), 0, 0, m_sizeBmp.cx, m_sizeBmp.cy,
0,0, m_sizeBmp.cx, m_sizeBmp.cy, m_pImgData,
pbmi, DIB_RGB_COLORS, SRCCOPY);
delete []pbmi;
ReleaseDC(pDC);
}
|