SAD算法: SAD(Sum of absolute differences)是一种图像局部匹配算法。
公式表示为:SAD(u,v) = Sum{|Left(u,v) - Right(u,v)|} 选择最小值。
此种方法就是以左目图像的源匹配点为中心,定义一个窗口D,其大小为(2m+1) (2n+1),统计其窗口的灰度值的和,然后在右目图像对应点,沿极线方向(水平方向)按照不同视差确定窗口,逐步计算其左右窗口的灰度和的差值,最后搜索到的差值最小的区域的中心像素即为匹配点。
基本流程:
1.构造一个小窗口,类似于卷积核。
2.用窗口覆盖左边的图像,选择出窗口覆盖区域内的所有像素点。
3.同样用窗口覆盖右边的图像并选择出覆盖区域的像素点。
4.左边覆盖区域减去右边覆盖区域,并求出所有像素点差的绝对值的和。
5.移动右边图像的窗口,重复3,4的动作。(这里有个搜索范围,超过这个范围跳出)
6.找到这个范围内SAD值最小的窗口,即找到了左边图像的最佳匹配的像素块。
代码实现:
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <ctime>
using namespace std;
using namespace cv;
const int n = 7; //窗口大小:2*n+1
const int range = 150;//视差范围
void SAD(uchar* Limg,
uchar* Rimg,
uchar* Oimg,int w,int h)
{
for (int y = 0; y< h; y++)
{
for (int x = 0; x< w; x++){
unsigned int bestCost = 999999;
unsigned int bestDisparity = 0;
for (int d = 0; d <= range; d++)
{
unsigned int cost = 0;
for (int i = -n; i <= n; i++)
{
for (int j = -n; j <= n; j++)
{
int yy, xx, xxd;
yy = y + i;
if (yy < 0) yy = 0;
if (yy >= h) yy = h-1;
xx = x + j;
if (xx < 0) xx = 0;
if (xx >= w) xx = w-1;
xxd = xx - d;
if (xxd < 0) xxd = 0;
if (xxd >= w) xxd = w-1;
cost += abs((int)(Limg[yy*w + xx] - Rimg[yy*w + xxd]));
}
}
if (cost < bestCost)
{
bestCost = cost;
bestDisparity = d;
}
Oimg[y*w + x] = bestDisparity*4;
}
}
}
}
int main()
{
clock_t starttime = clock();
Mat imL, imR, imO;
imL = imread("im2.png", 0);
if (imL.empty())
{
return -1;
}
imR = imread("im6.png", 0);
if (imR.empty())
{
return -1;
}
imO.create(imL.rows, imL.cols, CV_8UC1);
SAD(imL.data, imR.data, imO.data, imL.cols, imL.rows);
namedWindow("left", WINDOW_AUTOSIZE);
namedWindow("right", WINDOW_AUTOSIZE);
namedWindow("Output", WINDOW_AUTOSIZE);
imwrite("11.png", imO);
imshow("Output", imO);
imshow("left", imL);
imshow("right", imR);
clock_t endtime = clock();
printf("%d\n", (endtime - starttime));
cout << (endtime - starttime) << endl;
waitKey(0);
return 0;
}
左图和右图:
运行结果为:
注意:
(1)事先在工程目录下存放:立体校正后的左图"im2.png"和立体校正后的右图"im6.png"。图片获取网址:http://vision.middlebury.edu/stereo/data/scenes2003/
(2)代码运行时间大约100s