机器学习实践系列之10 - OpenCV实战立体视觉
·
立体视觉 是通过图像间的对应关系,根据三角测量原理,得到视差图,主要过程包括:摄像机标定、立体标定、立体校正、计算视差图。
在得到视差信息后,很容易根据投影模型 计算原始图像的深度,立体匹配技术被 认为是立体视觉中最困难也是最关键的问题,容易受 光照、噪声、非显著纹理(特征)等问题影响,无法得到较好的匹配效果。
本节主要讲解 OpenCV 自带立体视觉模块 StereoSGBM 。
StereoSGBM 是一种 半全局匹配算法,对比 BM算法 StereoBM (块匹配,Block Matching)视差图轮廓更清晰,但是计算量稍大。
详细说明可以参考OpenCV的在线文档:http://opencv.willowgarage.com/documentation/cpp/camera_calibration_and_3d_reconstruction.html
来看实现效果:
参考代码:
/* linolzhang 2013.9
Stereo Match
*/
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#pragma comment(lib,"opencv_core2410.lib")
#pragma comment(lib,"opencv_highgui2410.lib")
#pragma comment(lib,"opencv_calib3d2410.lib")
using namespace std;
using namespace cv;
int main()
{
// Load示例图像
IplImage* img1 = cvLoadImage("scene_l.bmp",0);
IplImage* img2 = cvLoadImage("scene_r.bmp",0);
// 定义结果显示图像
Mat disp, disp_gray;
// OpenCV自带的SGBM
cv::StereoSGBM sgbm;
// 预处理参数
sgbm.preFilterCap = 63;
// SAD参数
sgbm.SADWindowSize = 9; // SAD窗口大小,奇数,取值[5,255]
sgbm.minDisparity = 0; // 最小视差,默认0,可以为负
sgbm.numberOfDisparities = 64; // 视差窗口,16的整数倍,=最大视差值-最小视差值
int nChannel = img1->nChannels;
// 平滑参数,值越大越平滑,P2必须大于P1
// P1是相邻像素点视差增/减 1 时的惩罚系数,P2是相邻像素点视差变化值大于1时的惩罚系数
sgbm.P1 = 8 * nChannel * sgbm.SADWindowSize * sgbm.SADWindowSize;
sgbm.P2 = 32 * nChannel * sgbm.SADWindowSize * sgbm.SADWindowSize;
sgbm.uniquenessRatio = 10; // 视差唯一性百分比,一般取值 5-15
sgbm.speckleWindowSize = 100; // 检查视差连通区域变化度的窗口大小, 值为0时取消 speckle 检查
sgbm.speckleRange = 32; // 视差变化阈值,当窗口内视差变化大于阈值时,该窗口内的视差清零
// 左视差图(直接计算得出)和右视差图(通过cvValidateDisparity计算得出)之间的最大容许差异,
// 超过该阈值的视差值将被清零,默认值为-1,不执行左右视差检查
sgbm.disp12MaxDiff = 1;
sgbm((Mat)img1, (Mat)img2, disp);
disp.convertTo( disp_gray, CV_8U, 255/(sgbm.numberOfDisparities*16.) );
cvShowImage("left", img1);
cvShowImage("right", img2);
imshow("disparity", disp_gray);
waitKey();
cvDestroyAllWindows();
return 0;
}更多推荐
所有评论(0)