怎样从一幅彩色BMP图片(有几个颜色棋)里面分辨出其中一个红色棋子,比较急!高分赠英雄!
怎样从一幅彩色BMP图片(有几个彩色棋子,图片不是很清晰)里面分辨出其中一个红色棋子,思路是怎样的,最好谁有源代码给我看看。
我不懂数字图像处理的,急用,大家多多帮忙!
问题点数:100、回复次数:6Top
1 楼I_Love_CPP(Never stop!)回复于 2005-04-01 10:01:23 得分 0
用象素点的颜色值去判断。Top
2 楼vcleaner(我没当大哥很久了.......)回复于 2005-04-01 10:14:46 得分 50
使用图像点的RGB值判断。参考:
void CCreateRandomBMPDlg::OnBtnCreateBMP()
{
CDC dc;
dc.CreateDC("DISPLAY", NULL, NULL, NULL);
CBitmap bm;
int Width = 800;//指定图片宽度
int Height = 600;//指定图片高度
bm.CreateCompatibleBitmap(&dc, Width, Height);
CDC tdc;
tdc.CreateCompatibleDC(&dc);
CBitmap* pOld = tdc.SelectObject(&bm);
tdc.BitBlt(0, 0, Width, Height, &dc, 0, 0, SRCCOPY);
tdc.SelectObject(pOld);
BITMAP btm;
bm.GetBitmap(&btm);
DWORD size = btm.bmWidthBytes* btm.bmHeight;
LPSTR lpData = (LPSTR) GlobalAllocPtr(GPTR, size);
/////////////////////////////////////////////
/////////////////////////////////////////////
BITMAPINFOHEADER bih;
bih.biBitCount = btm.bmBitsPixel;
bih.biClrImportant = 0;
bih.biClrUsed = 0;
bih.biCompression = 0;
bih.biHeight = btm.bmHeight;
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = size;
bih.biWidth = btm.bmWidth;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
///////////////////////////////////
GetDIBits(dc, bm, 0, bih.biHeight, lpData, (BITMAPINFO *) &bih,
DIB_RGB_COLORS);
// bm.GetBitmapBits(size,lpData); //此函数在处理5-5-5模式的16位色下会出现颜色混乱
//////////////////////////////
//修改RGB值
int nWidth = btm.bmWidth * 4;
for (int i = 0; i < btm.bmHeight; i++)
{
for (int j = 0; j < btm.bmWidth; j++)
{
lpData[i * nWidth + j * 4 + 2] = GetRandomRGBValue(); //R
lpData[i * nWidth + j * 4 + 1] = GetRandomRGBValue(); //G
lpData[i * nWidth + j * 4] = GetRandomRGBValue(); //B
TRACE("\nR = %d; G = %d; B = %d\n",
lpData[i * nWidth + j * 4 + 2],
lpData[i * nWidth + j * 4 + 1], lpData[i * nWidth + j * 4]);
}
}
static int filecount = 0;
CString name;
name = "D:\\Test.bmp";//m_Path+name;
BITMAPFILEHEADER bfh;
bfh.bfReserved1 = bfh.bfReserved2 = 0;
bfh.bfType = ((WORD) ('M' << 8) | 'B');
bfh.bfSize = 54 + size;
bfh.bfOffBits = 54;
CFile bf;
if (bf.Open(name, CFile::modeCreate | CFile::modeWrite))
{
bf.WriteHuge(&bfh, sizeof(BITMAPFILEHEADER));
bf.WriteHuge(&bih, sizeof(BITMAPINFOHEADER));
bf.WriteHuge(lpData, size);
bf.Close();
}
GlobalFreePtr(lpData);
AfxMessageBox("Create BMP File Over!");
}
============================
这是一个生成随机RGB值的BMP图像的程序。GetRandomRGBValue是一个返回值在0-255之间的一个计算随机数的函数!Top
3 楼vcleaner(我没当大哥很久了.......)回复于 2005-04-01 10:16:50 得分 0
或者可以参考下面的例子,它使用打开文件对话框打开一个文件,显示在屏幕上,其中有读取RGB值的部分。你可以参考一下。不过红色的RGB值应该是一个范围值,而不是一个确定的值。
void CCreateRandomBMPDlg::OnBtnTest()
{
// TODO: Add your control notification handler code here
HBITMAP hBmp;
CFileDialog dlg(TRUE, "bmp", NULL, 0, "位图文件 (*.bmp)|*.bmp||", this);
if (dlg.DoModal() != IDOK)
{
return;
}
hBmp = (HBITMAP) LoadImage(NULL, dlg.GetPathName(), IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if (hBmp == NULL)
{
return;
}
BITMAP bm;
PBITMAPINFO bmpInf;
if (GetObject(hBmp, sizeof(bm), &bm) == 0)
return ;
int nPaletteSize = 0;
if (bm.bmBitsPixel < 16)
nPaletteSize = (int) pow(2, bm.bmBitsPixel);
bmpInf = (PBITMAPINFO) LocalAlloc(LPTR,
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * nPaletteSize);
//-----------------------------------------------
bmpInf->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInf->bmiHeader.biWidth = bm.bmWidth;
bmpInf->bmiHeader.biHeight = bm.bmHeight;
bmpInf->bmiHeader.biPlanes = bm.bmPlanes;
bmpInf->bmiHeader.biBitCount = bm.bmBitsPixel;
bmpInf->bmiHeader.biCompression = BI_RGB;
bmpInf->bmiHeader.biSizeImage = (bm.bmWidth + 7) /
8 * bm.bmHeight * bm.bmBitsPixel;
bmpInf->bmiHeader.biXPelsPerMeter = 0;
bmpInf->bmiHeader.biYPelsPerMeter = 0;
bmpInf->bmiHeader.biClrUsed = 0;
bmpInf->bmiHeader.biClrImportant = 0;
//-----------------------------------------------
HDC hDC = ::GetWindowDC(NULL);
if (!::GetDIBits(hDC, hBmp, 0, (WORD) bm.bmHeight, NULL, bmpInf,
DIB_RGB_COLORS))
{
LocalFree(bmpInf);
::ReleaseDC(NULL, hDC);
return ;
}
void* buf = (void*) new char[bmpInf->bmiHeader.biSizeImage];
if (buf == NULL)
{
::ReleaseDC(NULL, hDC);
LocalFree(bmpInf);
return ;
}
if (!::GetDIBits(hDC, hBmp, 0, (UINT) bm.bmHeight, buf, bmpInf,
DIB_RGB_COLORS))
{
::ReleaseDC(NULL, hDC);
delete[]buf;
LocalFree(bmpInf);
return ;
}
::ReleaseDC(NULL, hDC);
CString sMsg;
sMsg.Format("BitsPixel:%d,width:%d,height:%d", bm.bmBitsPixel, bm.bmWidth,
bm.bmHeight);
AfxMessageBox(sMsg);
CClientDC dc(this);
if (bm.bmBitsPixel == 8)
{
BYTE* pData = (BYTE*) buf;
int nWidth = bm.bmWidth;
while (nWidth % 4 != 0)
{
//Bmp每行数据都是4个字节的整数倍。
nWidth++;
}
for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
RGBQUAD rgbQ;
rgbQ = bmpInf->bmiColors[pData[i * nWidth + j]];
dc.SetPixel(j, bm.bmHeight - i,
RGB(rgbQ.rgbRed, rgbQ.rgbGreen, rgbQ.rgbBlue));
}
}
}
else if (bm.bmBitsPixel == 16)
{
BYTE* pData = (BYTE*) buf;
int nWidth = bm.bmWidth*2;
while (nWidth % 4 != 0)
{
nWidth++;
}
BYTE red, green, blue;
for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
blue = pData[i * nWidth + j * 2] & 0x1F;
green = pData[i * nWidth + j * 2] >> 5;
green |= (pData[i * nWidth + j * 2 + 1] & 0x03) << 3;
red = (pData[i * nWidth + j * 2 + 1] >> 2) & 0x1F;
WORD wRed = red*8;
WORD wBlue = blue*8;
WORD wGreen = green*8;
red = min(255, wRed);
blue = min(255, wBlue);
green = min(255, wGreen);
dc.SetPixel(j, bm.bmHeight - i, RGB(red, green, blue));
}
}
}
else if (bm.bmBitsPixel == 24)
{
BYTE* pData = (BYTE*) buf;
int nWidth = bm.bmWidth*3;
while (nWidth % 4 != 0)
{
nWidth++;
}
for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
dc.SetPixel(j, bm.bmHeight -
i,
RGB(pData[i * nWidth + j * 3 + 2],
pData[i * nWidth + j * 3 + 1],
pData[i * nWidth + j * 3]));
}
}
}
else if (bm.bmBitsPixel == 32)
{
BYTE* pData = (BYTE*) buf;
int nWidth = bm.bmWidth*4;
for (int i = 0; i < bm.bmHeight; i++)
{
for (int j = 0; j < bm.bmWidth; j++)
{
dc.SetPixel(j, bm.bmHeight -
i,
RGB(pData[i * nWidth + j * 4 + 2],
pData[i * nWidth + j * 4 + 1],
pData[i * nWidth + j * 4]));
}
}
}
delete[]buf;
DeleteObject(hBmp);
LocalFree(bmpInf);
}
Top
4 楼mava(性感小奶牛)回复于 2005-04-01 11:23:22 得分 30
Email : mava@163.com
给我图片和你的要求,我看看。Top
5 楼billy145533($_$)回复于 2005-04-01 17:01:07 得分 0
顶。学习Top
6 楼huanyun(无妻徒刑)回复于 2005-04-02 00:45:32 得分 20
直接用V分量判断
//加上127的偏移, 归一化到0-255;
inline BYTE PixelV(PCBYTE pSrc)
{
return static_cast<BYTE>(((pSrc[2]<<7) - 107*pSrc[1] - 21*pSrc[0] + 32512) >> 8);
}
红色的V值 至少大于128;
至于多红 根据你的图像判断 取一个合适的值就可以了Top




