视频图象匹配有关问题,高手看过来
视频图象匹配问题,高手看过来
我已经把视频图象截取到内存中,但截获的是24位位图 ,得到是位图的句柄,请问我要把此位图转化为8位的应该怎么操作,主要问题是我对 bmp数据格式不是很熟,而不是不知道转化算法,请高手给些思路,尽量细致~
还有可以给我解释下hbitmap,hdib,位图句柄和位图指针的转化,CBITMAP与BITMAP的区别和联系~
尽量细致,最好讲解位图的最低层结构,有示例代码最好,谢谢,50分作为回报,1周内结贴~~
------解决方案--------------------
HANDLE rgb2gray(HANDLE hDIB)
{
//把RGB的DIB图像 转换为灰度图象 返回新的指向DIB图像的句柄
//暂时只考虑> 24位的真彩色道8位灰度图象转化 其他颜色级的灰度变换没有加入
intn BitsCount = 8;
LPSTR lpDIB;
if (hDIB == NULL)
return false;//return NULL;
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
WORD wNumColors = GetColorNum (lpDIB);
if (wNumColors != 0) //不是真彩色 暂时不处理
{
::GlobalFree((HGLOBAL) hDIB);
return false; // return NULL;
}
LPBITMAPINFO lpbmi = NULL;
LPBYTE lpDIBBits, lpTargetBits, lpNewDIB;
DWORD dwSize, dwBitsSize, dwHeaderSize, dwColorNum,dwLineWidth;
HANDLE hNewDIB;
dwColorNum = 1 < < nBitsCount; //256色
dwHeaderSize = sizeof( BITMAPINFO ) + ( dwColorNum * sizeof( RGBQUAD ) );
lpbmi = (LPBITMAPINFO)malloc( dwHeaderSize );
lpbmi-> bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
lpbmi-> bmiHeader.biWidth = m_nWidth;
lpbmi-> bmiHeader.biHeight = m_nHeight;
lpbmi-> bmiHeader.biPlanes = 1;
lpbmi-> bmiHeader.biBitCount = nBitsCount;
lpbmi-> bmiHeader.biCompression = BI_RGB;
lpbmi-> bmiHeader.biSizeImage = 0;
lpbmi-> bmiHeader.biXPelsPerMeter = 0;
lpbmi-> bmiHeader.biYPelsPerMeter = 0;
lpbmi-> bmiHeader.biClrUsed = 0;
lpbmi-> bmiHeader.biClrImportant = 0;
for (int i=0; i < (int)dwColorNum; i++) //调色板赋值0-255灰度值
{
lpbmi-> bmiColors[i].rgbRed =
lpbmi-> bmiColors[i].rgbGreen =
lpbmi-> bmiColors[i].rgbBlue = (BYTE)i;
lpbmi-> bmiColors[i].rgbReserved = (BYTE)0;
}
dwLineWidth = SCANWIDTHBYTES(m_nWidth * nBitsCount);
dwBitsSize = (m_nHeight * dwLineWidth);
lpTargetBits = (LPBYTE) malloc( dwBitsSize ); //数据区重新赋值
memset(lpTargetBits,0,dwBitsSize);
lpDIBBits = (LPBYTE) GetBits(lpDIB);
LPBYTE lpTCurr = lpTargetBits;
LPBYTE lpSCurr = lpDIBBits;
if (m_nBitsPerPixel == 32)
{ //32位图
for (i =0; i < m_nHeight ; i++)
{
lpSCurr = lpDIBBits + (m_dwDIBSize - m_nScanWidth - i * m_nScanWidth);
lpTCurr = lpTargetBits + (dwBitsSize - dwLineWidth - i * dwLineWidth);
for(int j = 0; j < m_nWidth; j++) //数据区的内容是BGR顺序放的
{
//按YUV的系数 灰度化
*lpTCurr = (*(lpSCurr++))*0.114 + (*(lpSCurr++))*0.587 + (*(lpSCurr++))*0.299;
lpSCurr++ ;
lpTCurr++;
}
}
}
else
{ //24位图
for (i =0; i < m_nHeight ; i++)
{
lpSCurr = lpDIBBits + (m_dwDIBSize - m_nScanWidth - i * m_nScanWidth);
lpTCurr = lpTargetBits + (dwBitsSize - dwLineWidth - i * dwLineWidth);
for(int j = 0; j < m_nWidth; j++) //数据区的内容是BGR顺序放的
{
//按YUV的系数 灰度化
*lpTCurr = (*(lpSCurr++))*0.114 + (*(lpSCurr++))*0.587 + (*(lpSCurr++))*0.299;
lpTCurr++;
}
}
}
// Allocate enough memory for the new CF_DIB, and copy bits
dwSize = dwHeaderSize + dwBitsSize;
hNewDIB = GlobalAlloc(GHND, dwSize); //malloc( dwTargetHeaderSize + dwTargetBitsSize );
lpNewDIB = (LPBYTE)GlobalLock(hNewDIB);
//分别把DIB文件头和图像数据拷贝到DIB整块内存
memcpy( lpNewDIB, lpbmi, dwHeaderSize );
memcpy((LPBYTE)(lpNewDIB +dwHeaderSize), lpTargetBits, dwBitsSize );
free(lpbmi); //释放临时空间
我已经把视频图象截取到内存中,但截获的是24位位图 ,得到是位图的句柄,请问我要把此位图转化为8位的应该怎么操作,主要问题是我对 bmp数据格式不是很熟,而不是不知道转化算法,请高手给些思路,尽量细致~
还有可以给我解释下hbitmap,hdib,位图句柄和位图指针的转化,CBITMAP与BITMAP的区别和联系~
尽量细致,最好讲解位图的最低层结构,有示例代码最好,谢谢,50分作为回报,1周内结贴~~
------解决方案--------------------
HANDLE rgb2gray(HANDLE hDIB)
{
//把RGB的DIB图像 转换为灰度图象 返回新的指向DIB图像的句柄
//暂时只考虑> 24位的真彩色道8位灰度图象转化 其他颜色级的灰度变换没有加入
intn BitsCount = 8;
LPSTR lpDIB;
if (hDIB == NULL)
return false;//return NULL;
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
WORD wNumColors = GetColorNum (lpDIB);
if (wNumColors != 0) //不是真彩色 暂时不处理
{
::GlobalFree((HGLOBAL) hDIB);
return false; // return NULL;
}
LPBITMAPINFO lpbmi = NULL;
LPBYTE lpDIBBits, lpTargetBits, lpNewDIB;
DWORD dwSize, dwBitsSize, dwHeaderSize, dwColorNum,dwLineWidth;
HANDLE hNewDIB;
dwColorNum = 1 < < nBitsCount; //256色
dwHeaderSize = sizeof( BITMAPINFO ) + ( dwColorNum * sizeof( RGBQUAD ) );
lpbmi = (LPBITMAPINFO)malloc( dwHeaderSize );
lpbmi-> bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
lpbmi-> bmiHeader.biWidth = m_nWidth;
lpbmi-> bmiHeader.biHeight = m_nHeight;
lpbmi-> bmiHeader.biPlanes = 1;
lpbmi-> bmiHeader.biBitCount = nBitsCount;
lpbmi-> bmiHeader.biCompression = BI_RGB;
lpbmi-> bmiHeader.biSizeImage = 0;
lpbmi-> bmiHeader.biXPelsPerMeter = 0;
lpbmi-> bmiHeader.biYPelsPerMeter = 0;
lpbmi-> bmiHeader.biClrUsed = 0;
lpbmi-> bmiHeader.biClrImportant = 0;
for (int i=0; i < (int)dwColorNum; i++) //调色板赋值0-255灰度值
{
lpbmi-> bmiColors[i].rgbRed =
lpbmi-> bmiColors[i].rgbGreen =
lpbmi-> bmiColors[i].rgbBlue = (BYTE)i;
lpbmi-> bmiColors[i].rgbReserved = (BYTE)0;
}
dwLineWidth = SCANWIDTHBYTES(m_nWidth * nBitsCount);
dwBitsSize = (m_nHeight * dwLineWidth);
lpTargetBits = (LPBYTE) malloc( dwBitsSize ); //数据区重新赋值
memset(lpTargetBits,0,dwBitsSize);
lpDIBBits = (LPBYTE) GetBits(lpDIB);
LPBYTE lpTCurr = lpTargetBits;
LPBYTE lpSCurr = lpDIBBits;
if (m_nBitsPerPixel == 32)
{ //32位图
for (i =0; i < m_nHeight ; i++)
{
lpSCurr = lpDIBBits + (m_dwDIBSize - m_nScanWidth - i * m_nScanWidth);
lpTCurr = lpTargetBits + (dwBitsSize - dwLineWidth - i * dwLineWidth);
for(int j = 0; j < m_nWidth; j++) //数据区的内容是BGR顺序放的
{
//按YUV的系数 灰度化
*lpTCurr = (*(lpSCurr++))*0.114 + (*(lpSCurr++))*0.587 + (*(lpSCurr++))*0.299;
lpSCurr++ ;
lpTCurr++;
}
}
}
else
{ //24位图
for (i =0; i < m_nHeight ; i++)
{
lpSCurr = lpDIBBits + (m_dwDIBSize - m_nScanWidth - i * m_nScanWidth);
lpTCurr = lpTargetBits + (dwBitsSize - dwLineWidth - i * dwLineWidth);
for(int j = 0; j < m_nWidth; j++) //数据区的内容是BGR顺序放的
{
//按YUV的系数 灰度化
*lpTCurr = (*(lpSCurr++))*0.114 + (*(lpSCurr++))*0.587 + (*(lpSCurr++))*0.299;
lpTCurr++;
}
}
}
// Allocate enough memory for the new CF_DIB, and copy bits
dwSize = dwHeaderSize + dwBitsSize;
hNewDIB = GlobalAlloc(GHND, dwSize); //malloc( dwTargetHeaderSize + dwTargetBitsSize );
lpNewDIB = (LPBYTE)GlobalLock(hNewDIB);
//分别把DIB文件头和图像数据拷贝到DIB整块内存
memcpy( lpNewDIB, lpbmi, dwHeaderSize );
memcpy((LPBYTE)(lpNewDIB +dwHeaderSize), lpTargetBits, dwBitsSize );
free(lpbmi); //释放临时空间