#ifndef SAD_H
#define SAD_H
#include"opencv2/opencv.hpp"
using namespace cv;
class SAD
{
public:
SAD():winSize(7),DSR(30){}
SAD(int _winSize, int _DSR): winSize(_winSize), DSR(_DSR){}
Mat computeSAD (Mat& imgL, Mat& imgR); //返回视差图
private:
int winSize;
int DSR;
};
#endif//SAD_H
#include"opencv2/opencv.hpp"
#include"../include/Sad.h"
using namespace cv;
Mat SAD::computeSAD (Mat& imgL, Mat& imgR)
{
int Height = imgL.rows;
int Width = imgR.cols;
Mat Kernel_L = Mat(Size(winSize, winSize), CV_8U);
Mat Kernel_R = Mat(Size(winSize, winSize), CV_8U);
Mat Kernel_Diff = Mat(Size(winSize, winSize), CV_8U);
Mat Disparity = Mat(Size(Width, Height), CV_8U); //Size_(_Tp _width, _Tp _height);! ! !先说width,再说HEIGHT
Mat uRight = Mat(Size(Width, Height), CV_8U);
//对每个像素点运用SAD匹配
for (int i = 0; i < Width - winSize; i++)
{
for (int j = 0; j < Height - winSize; j++)
{
Kernel_L = imgL(Rect(i, j , winSize, winSize));
Mat Diff_sum = Mat(1, DSR, CV_32F);
float Diff_min = 1000000;
//取得右图的窗口
for (int k = 0; k < DSR; k++)
{
int new_x = i + k;
if (new_x < Width - winSize)
{
Kernel_R = imgR(Rect(new_x, j, winSize, winSize));
//计算差值
cv::absdiff(Kernel_L, Kernel_R, Kernel_Diff);
Scalar ADD = sum(Kernel_Diff);
Diff_sum.at<char>(k) = ADD[0];
if (Diff_sum.at<char>(k) < Diff_min)
{
Diff_min = Diff_sum.at<char>(k) ;
uRight.at<char>(j,i) = imgR.at<char>(new_x);
}
}
}
Disparity.at<char>(j,i) = imgL.at<char>(j,i) - uRight.at<char>(j, i);
}
}
return Disparity;
}
#include "../include/Sad.h"
#include "opencv2/opencv.hpp"
#include "iostream"
#include "../src/Sad2.h"
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
if(argc!=3)
{
cerr << endl << "Usage: ./imgL imgR" << endl;
return 1;
}
Mat imgL = imread("imgL.jpg", 0);
Mat imgR = imread("imgR.jpg", 0);
Mat Disparity;
SAD my_SAD(7, 30);
Disparity = my_SAD.computeSAD(imgL, imgR);
imshow("imgL", imgL);
imshow("imgR", imgR);
imshow("Disparity", Disparity);
imwrite("Disparity.jpg", Disparity);
cvWaitKey(0);
return 0;
}
速度很慢,因为采取的是遍历每一个像素,后续尝试写提取特征点再用SAD匹配的方法