模板匹配+归一化匹配+金字塔加速
模板匹配(ABS)
原理
ABS算法是利用模板图像和待匹配图像上的搜索窗口之间的像素灰度值的差别,来表示二者的相关性。如果差别小于预定的阈值认为相关成功,否则就认为匹配失败。这种方法的思路简单,实现方便,但有明显的局限性。由于不同的模板和图像有不同的背景灰度值和不同大小的搜索窗口,所需的合适的阈值也各不相同,很难事先选定一个合适的阈值;另外模板图像和待匹配图像上由于光照等因素造成的灰度差异也可能导致匹配失败。
以下代码采取MAD判据
//small_i1, small_j1多余,只是当初在主函数里用到了
//计算所得MAD结果保存在事先定义的全局变量total1[][]里
//具体使用时可用阈值判断,也可取最小的点
void moban_pipei(Mat sma_, Mat big_, int small_i1, int small_j1)
{
Mat big = big_,sma=sma_;
int height1, width1;
int height2, width2;
long long compare = 1000000000000000;
height1 = big.cols;
width1 = big.rows;
height2 = sma.cols;
width2 = sma.rows;
for (int i = 0; i < height1 - height2; i++)
{
for (int j = 0; j < width1 - width2; j++)
{
double he = 0;
//int tt = big.at<uchar>(j,i);
for (int i1 = i; i1 < height2 + i-1; i1++)
{
for (int j1 = j; j1 < width2 + j-1; j1++)
{
Scalar tt1 = big.at<uchar>(Point(i1, j1));
Scalar tt2 = sma.at<uchar>(Point(i1-i, j1-j));
int temp;
temp = abs(tt1[0] - tt2[0]);
he = he + temp;
if (he > 100000)
break;
}
}
he = he / (height2 * width2);
total1[i][j] = he;
}
}
}
归一化匹配(NC)
原理
归一化互相关匹配算法 是一种经典的匹配算法 , 经常写为NC(Normalized Correlation)算法。通过计算模板图像和待匹配图像的互相关值来确定匹配的程度。互相关定义一般有如下两种形式:
上式 的值越大说明搜索图上 位置与模板越相似,当值为1时说明该位置即为匹配位置。
实际应用中,常常因为基准图和参考图是不同时间或不同相机拍摄的,因此两者对应像素的灰度值并不是绝对相等的,因而找不到 值为1的位置,此时,只需要在搜索图中找到具有最大 的位置,则认为该位置为最佳匹配位置。
以下代码采取第一种(此算法较慢,如果将Mat 的数据存在二维数组进行数组操作,时间将大大缩短)
void guiyihua(Mat sma_, Mat big_, int small_i1, int small_j1)
{
Mat big = big_, sma = sma_;
int height1, width1;
int height2, width2;
height1 = big.cols;
width1 = big.rows;
height2 = sma.cols;
width2 = sma.rows;
for (int i = 0; i < height1 - height2; i++)
{
for (int j = 0; j < width1 - width2; j++)
{
double he = 0;
int sum_1 = 0, sum_2 = 0, sum_3 = 0;
//int tt = big.at<uchar>(j,i);
for (int i1 = i; i1 < height2 + i - 1; i1++)
{
for (int j1 = j; j1 < width2 + j - 1; j1++)
{
Scalar tt1 = big.at<uchar>(Point(i1, j1));
Scalar tt2 = sma.at<uchar>(Point(i1 - i, j1 - j));
int temp1,temp2,temp3;
temp1 = tt1[0]*tt2[0];
temp2 = tt1[0] * tt1[0];
temp3 = tt2[0] * tt2[0];
sum_1 = sum_1 + temp1;
sum_2 = sum_2 + temp2;
sum_3 = sum_3 + temp3;
}
}
he = sum_1/(sqrt(sum_2 *sum_3));
total2[i][j] = he;
}
}
}
金字塔加速
原理
这是常用的一种快速相关算法,它是将模板图像和目标图像的每个C*C区域逐级进行灰度平均,得到C个图像塔形结构,从塔形结构的最高层开始,将模板图像和目标图像作相关运算,得到候选匹配点,这叫做粗相关;在下一层中,只在候选匹配点中进行匹配搜索,这叫做细相关。由此逐级向下,直至最高分辨率的原始图像,该方法通过对灰度取平均以减小模板图像和目标图像的大小来达到减少计算量的目的。
第一步.预处理图像
对被匹配的图像进行分层预处理,得到一组分辨率由高到低,维数由大到小的图像序列。
方法是将图像的邻域逐个进行平均处理,从而得到一个分辨率较低和维数较小的图像。然后,将此图像再用同样的方法处理,得到一个分辨率更低的和维数更小的图像。加上原图像,可构成一组分辨率由高到低,维数由大到小的图像序列。
用上述方法将实时图和模板图进行分层处理,可以得到两个图像序列。
第二步.先粗后细进行相关搜索
第一次相关搜索是从分辨率最低、维数最少的分层开始的,为了找到可能的粗匹配位置,应在该层所有搜索位置上进行相关,并确定粗匹配的位置。因为此时维数最小,所以搜索速度很快,这时可能产生多个可能的粗匹配位置。
下一次相关只需要在上一次相关产生的粗匹配位置附近进行相关搜索就可以了。依此类推,直到在最高分辨率的模板图和实时图上找到匹配位置为止。
分层搜索算法的搜索位置数为一般算法的 ,从而大大提高了处理速度。
关于缩放的算法如下
缩放几次调用几次,之后再进行上面的匹配就完成金字塔加速
Mat suofang(Mat img)
{
Mat output=img;
int height, width;
height = img.cols;
width = img.rows;
height = (height-1) / 2;
width = (width-1) / 2;
for (int i = 0; i < height - 1; i++)
{
for (int j = 0; j < width - 1; j++)
{
/*Scalar tt = img.at<uchar>(Point(po1, po2));
int tp = tt[0];*/
output.at<uchar>(Point(i, j)) = int(img.at<uchar>(Point(2*i, 2*j)));
}
}
return output;
}