vc++数字图像运动检测处理系统 第8页
下面先看第一个过程:特征区域的匹配。在执行这一操作之前,系统已经得到了第一幅图片的特征区域的信息。现在要做的事情就是查看第二幅图片里面有没有相同的(或者说是非常相近)的一块区域。具体算法如下:把已经得到的存放彩色特征区域信息的数组当作一个模板在第二幅图片上移动,计算两个正方形内像素点的差值,找到第二幅图片中差值最小的正方形区域。考察在这个区域里面两个正方形的像素颜色差值,如果大于设定的上限,则说明第二幅图片里面没有第一幅图片的特征区域,如果小于设定的上限,则把这块区域当作第二幅图片的特征区域。
1) 特征区域匹配的函数MatchImportantPoint。
//下面的函数实现对特征区域的匹配MatchImportantPoint
BOOLDIB::MatchImportantPoint(HANDLEhDIB,int CharaterInfo[RADIUS*2+1][RADIUS*2+1][3],CPoint *ImPoint)
{
LPBITMAPINFOHEADER lpbi;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
int width = lpbi->biWidth;
int height = lpbi->biHeight;
LPBYTE lpData = this->FindDIBBits(hDIB);
WORD wBytesPerLine = this->BytePerLine(hDIB);
long lOffset;
long sum =100000,tempsum;
//扫描整个图片(边缘点)除外
for(int i=RADIUS ;i<height-RADIUS;i++)
for(int j=RADIUS;j<width-RADIUS;j++)
{
tempsum =0;
//扫描以RADIUS*2+1为边长的正方形区域
for(int k=-RADIUS;k<=RADIUS;k++)
for(int kk=-RADIUS;kk<=RADIUS;kk++)
{
//计算当前正方形和已知特征区域的颜色差值
lOffset = this->PixelOffset(i+k,j+kk,wBytesPerLine);
int colorblue = abs(*(lpData+lOffset++)-CharaterInfo[k+RADIUS][kk+RADIUS][0]);
int colorgreen = abs(*(lpData+lOffset++)-CharaterInfo[k+RADIUS][kk+RADIUS][1]);
int colorred = abs(*(lpData+lOffset++)-CharaterInfo[k+RADIUS][kk+RADIUS][2]);
tempsum +=colorgreen+colorblue+colorred;
}
if(tempsum<sum)
{ //更新差值
sum = tempsum;
//更改特征坐标点
ImPoint->x = j
ImPoint->y = i;
}
}
if(sum <THRESHOLD){//找到满足条件的区域
//下面的代码把找到的区域的边框设置成为白色
for(i =-RADIUS;i<=RADIUS;i++)
{
lOffset = this->PixelOffset(ImPoint->y-RADIUS,ImPoint->x+i,wBytesPerLine);
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
}
for(i =-RADIUS;i<=RADIUS;i++)
{
lOffset = this->PixelOffset(ImPoint->y+RADIUS,ImPoint->x+i,wBytesPerLine);
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
}
for(i =-RADIUS;i<=RADIUS;i++)
{
lOffset = this->PixelOffset(ImPoint->y+i,ImPoint->x+RADIUS,wBytesPerLine);
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
}
for(i =-RADIUS;i<=RADIUS;i++)
{
lOffset = this->PixelOffset(ImPoint->y+i,ImPoint->x-RADIUS,wBytesPerLine);
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255;
*(lpData+lOffset++) = 255; }
GlobalUnlock(hDIB);
return true;
}
else AfxMessageBox("Can't find the corresponding point!");
GlobalUnlock(hDIB);
return false;
匹配得到的特征区域如图15所示。
图15 匹配得到的特征区域图
完成了特征区域的匹配之后要进行的是相似度判定。相似度判定就是考察两幅图片像素颜色差别的大小。其中包括图片对齐的过程,对齐是按照特征区域对齐的方法来进行的,即把两个特征区域的中心点重叠,然后考察两幅图片中对应像素的差值。最后根据得到的差值,综合确定两幅图片是否相似。
2) 相似度判定的函数ComPareImg
//下面的函数比较两幅图片的相似度
BOOL DIB::ComPareImg(HANDLE hDIB1, HANDLE hDIB2 ,CPoint pt1,CPoint pt2)
{
if(abs(pt1.x-pt2.x)>3 || abs(pt1.y -pt2.y)>3)//图像偏差过大
{
AfxMessageBox("Imgs Offset are too big");
return false;
}
LPBITMAPINFOHEADER lpbi1,lpbi2;
lpbi1 = (LPBITMAPINFOHEADER)GlobalLock(hDIB1);
int width1 = lpbi1->biWidth;
int height1 = lpbi1->biHeight;
lpbi2 = (LPBITMAPINFOHEADER)GlobalLock(hDIB2);
int width2 = lpbi2->biWidth;
int height2 = lpbi2->biHeight;
if(width1 != width2 || height1 != height2)//图像长宽尺寸不同
{
GlobalUnlock(hDIB1);
GlobalUnlock(hDIB2);
AfxMessageBox("Img is not same size");
return false;
}
LPBYTE lpData1,lpData2;
lpData1 = this->FindDIBBits(hDIB1);
lpData2 = this->FindDIBBits(hDIB2);
WORD wBytesPerLine = this->BytePerLine(hDIB1);
int xleft,xright,ytop,ybottom;
//下面的一段代码实现图像对齐
if(pt1.x>=pt2.x)//第一幅图得特征中心点比第二幅图偏右
{
xleft = pt2.x;//要处理得左边得象素点个数
xright =width-pt1.x-1;//要处理得右边得象素点个数
}
else//第一幅图得特征中心点比第二幅图偏左
{
xleft = pt1.x;
xright = width1-pt2.x-1;
}
if(pt1.y >=pt2.y)//第一幅图得特征中心点得位置偏上
{
ytop = pt2.y;//要处理得中心点上面得象素个数
ybottom = height1-pt1.y-1;//要处理得中心点下面得象素个数
}
else//第一幅图得特征中心点得位置偏下
{
ytop = pt1.y;
ybottom = height1-pt2.y-1;
}
long sum=0;
long lOffset;
//计算两幅图片交叉区域得象素差值
for(int i=-ytop;i<=ybottom;i++)
for(int j=-xleft;j<=xright;j++)