首页 > 服务与支持 > 知识培训 技术专题


灰度图像处理中伪彩色的防止方法

    在灰度图像处理的过程中,很多情况下都要使用图像采集卡,以把模拟的图像转化为数字图像,供计算机处理。但是,有一些图像采集卡,必须将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);

    }