我需要进行两个图像的对比,第一个图像是从摄像头取出来的,另一个图像是保存的一个模板,是从第一个图像上面取出来的一部份。现在要在第一个图像上面查找出第二个图像所在的区域,并标示出来。
我的做法:
1.灰度转换
2.边缘提取(Prewitt算子)
3.二值化
4.获取第二副图的有色点数
5.按模板图像的宽和高在第一副图上查找有色点数
6.画矩形框标出来。我的问题是:程序查到了相等的有色点数,但标出来的位置总是不正确
有色点查找:long GrayTrans::GetColorCountByBinaryImg(int x,int y,int width,int height)
{
long iNum = 0;
int lineByte=(m_imgWidthOut*m_nBitCountOut/8+3)/4*4; for(int iy = y;iy < y+height;iy++)
{
for(int ix = x;ix < x+width;ix++)
{//m_pImgDataOut是二值化后的数据
if(m_pImgDataOut[iy*lineByte+ix] == 255)
iNum++;
}
}
return iNum;
}图像区域查找: for(int ix=0;ix<=img2.m_imgWidth-iWidth;ix++)
{
for(int iy=0;iy<=img2.m_imgHeight-iHeight;iy++)
{
int iNum = img2.GetColorCountByBinaryImg(ix,iy,iWidth,iHeight);
if(abs(iNum-img1_nColor) < 10)
{//img1_nColor为模板有色点数,10为误差值
CPen pen(PS_SOLID,1,RGB(0,255,0));
CPen *pOldbrush = pImg2DC->SelectObject(&pen);
pImg2DC->SelectStockObject(NULL_BRUSH);
pImg2DC->SetTextColor(RGB(255,0,0));
pImg2DC->Rectangle(ix,iy,ix+iWidth,iy+iHeight);
pImg2DC->SelectObject(pOldbrush);
// for(int i=0;i<iHeight;i++)
// {//这里直接画像素,输出只是几个白点
// for(int j=0;j<iWidth;j++)
// {
// if(img2.m_pImgDataOut[i*((iWidth+3)/4*4)+j] == 255)
// pImg2DC->SetPixel(j,i,RGB(255,255,255));
// else
// pImg2DC->SetPixel(j,i,RGB(0,0,0));
// }
// }
// CString strMsg;
// //strMsg.Format("x:%d y:%d W:%d H:%d",ix,iy,ix+iWidth,iy+iHeight);
// //AfxMessageBox(TEXT(strMsg));
return;
}
}
我的做法:
1.灰度转换
2.边缘提取(Prewitt算子)
3.二值化
4.获取第二副图的有色点数
5.按模板图像的宽和高在第一副图上查找有色点数
6.画矩形框标出来。我的问题是:程序查到了相等的有色点数,但标出来的位置总是不正确
有色点查找:long GrayTrans::GetColorCountByBinaryImg(int x,int y,int width,int height)
{
long iNum = 0;
int lineByte=(m_imgWidthOut*m_nBitCountOut/8+3)/4*4; for(int iy = y;iy < y+height;iy++)
{
for(int ix = x;ix < x+width;ix++)
{//m_pImgDataOut是二值化后的数据
if(m_pImgDataOut[iy*lineByte+ix] == 255)
iNum++;
}
}
return iNum;
}图像区域查找: for(int ix=0;ix<=img2.m_imgWidth-iWidth;ix++)
{
for(int iy=0;iy<=img2.m_imgHeight-iHeight;iy++)
{
int iNum = img2.GetColorCountByBinaryImg(ix,iy,iWidth,iHeight);
if(abs(iNum-img1_nColor) < 10)
{//img1_nColor为模板有色点数,10为误差值
CPen pen(PS_SOLID,1,RGB(0,255,0));
CPen *pOldbrush = pImg2DC->SelectObject(&pen);
pImg2DC->SelectStockObject(NULL_BRUSH);
pImg2DC->SetTextColor(RGB(255,0,0));
pImg2DC->Rectangle(ix,iy,ix+iWidth,iy+iHeight);
pImg2DC->SelectObject(pOldbrush);
// for(int i=0;i<iHeight;i++)
// {//这里直接画像素,输出只是几个白点
// for(int j=0;j<iWidth;j++)
// {
// if(img2.m_pImgDataOut[i*((iWidth+3)/4*4)+j] == 255)
// pImg2DC->SetPixel(j,i,RGB(255,255,255));
// else
// pImg2DC->SetPixel(j,i,RGB(0,0,0));
// }
// }
// CString strMsg;
// //strMsg.Format("x:%d y:%d W:%d H:%d",ix,iy,ix+iWidth,iy+iHeight);
// //AfxMessageBox(TEXT(strMsg));
return;
}
}
------------------就这个需求,最简单的办法是灰度化,然后将模板作为滑动窗口,在第一个图像上滑动,不停作差,并对差值图像求和,如果和小于一个事先设定的tolerance,就认为找到了,标记位置并跳出循环.