三维重建之视图差的计算--SGBM和GC算法
2016-04-15 17:20
351 查看
最近一直在做三维重建的毕业设计,看了好多的算法、论文和代码。在查找资料的过程中发现很多人上传的东西真的是没法用,而且全都要积分。我虽说是一个水货,也不致力于从事着方面的研究和工作,但是为了毕设也没办法,目前调通了很多算法,虽然说不清原理,但是还是把代码创传上来,供大家使用。
后来一点点的改进,在这个过程中有很多的收获。
在网上搜了很多资料,针对两种算法,sgbm和gc算法,输入的图片要求不同,sgbm可以处理彩色图片,但是gc算法不允许,而且在转换为灰色图像的过程中,运行时会出现异常,在下面的代码里也都给出了解决的办法。但是因为本人学艺不精,就不给什么其他的注释了,大家尽量凭借自己的智慧去看吧。
一、win32项目工程,stereo vision1
1、头文件:
#include "stdafx.h" #include <cstdio> #include<cstring> #include <cmath> #include <highgui.h> #include <cv.h> #include <cxcore.h> #include <iostream> #include <iostream> #include <stdlib.h> #include <cvaux.h> #include "opencv2/calib3d/calib3d.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/contrib/contrib.hpp" #pragma comment(lib,"opencv_highgui249d.lib") #pragma comment(lib,"opencv_core249d.lib") #pragma comment(lib,"opencv_imgproc249d.lib") #include <math.h> #include <GL/glut.h> #include <iostream>
2、SGBM算法
int StereoSBGM(IplImage *img1, IplImage *img2) { cv::StereoSGBM sgbm; int SADWindowSize = 9; sgbm.preFilterCap = 63; sgbm.SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 3; int cn = img1->nChannels; int numberOfDisparities=64; sgbm.P1 = 8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize; sgbm.P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize; sgbm.minDisparity = 0; sgbm.numberOfDisparities = numberOfDisparities; sgbm.uniquenessRatio = 10; sgbm.speckleWindowSize = 100; sgbm.speckleRange = 32; sgbm.disp12MaxDiff = 1; Mat disp, disp8; int64 t = getTickCount(); sgbm((Mat)img1, (Mat)img2, disp); t = getTickCount() - t; cout<<"Time elapsed:"<<t*1000/getTickFrequency()<<endl; disp.convertTo(disp8, CV_8U, 255/(numberOfDisparities*16.)); // getF_Gray2Color(disp8); cv::Mat di; getDisparityImage(disp8,di,true); waitKey(); return 1; }
3、GC算法
int StereoGC(IplImage *img1, IplImage *img2) { CvStereoGCState* GCState=cvCreateStereoGCState(64,3); assert(GCState); cout<<"start matching using GC"<<endl; CvMat* gcdispleft=cvCreateMat(img1->height,img1->width,CV_16S); CvMat* gcdispright=cvCreateMat(img2->height,img2->width,CV_16S); CvMat* gcvdisp=cvCreateMat(img1->height,img1->width,CV_8U); int64 t=getTickCount(); cvFindStereoCorrespondenceGC(img1,img2,gcdispleft,gcdispright,GCState); t=getTickCount()-t; cout<<"Time elapsed:"<<t*1/getTickFrequency()<<endl; cvNormalize(gcdispright,gcvdisp,0,255,CV_MINMAX); // cvSaveImage("GC_right_disparity.png",gcvdisp); // cvNamedWindow("GC_disparity",0); // cvShowImage("GC_disparity",gcvdisp); cv::Mat di; CvMat *a = gcvdisp; Mat b = Mat(a, true); getDisparityImage(b,di,true); //转换为彩色视图差 cvWaitKey(0); cvReleaseMat(&gcdispleft); cvReleaseMat(&gcdispright); cvReleaseMat(&gcvdisp); return 1; }
4、伪彩色视图差
<span style="font-size:10px;">/*-----------</span>----------------- * 功能 : 获取伪彩色视差图 *---------------------------- * 函数 : StereoMatch::getDisparityImage * 访问 : public * 返回 : 0 - 失败,1 - 成功 * * 参数 : disparity [in] 原始视差数据 * 参数 : disparityImage [out] 伪彩色视差图 * 参数 : isColor [in] 是否采用伪彩色,默认为 true,设为 false 时返回灰度视差图 */ int getDisparityImage(cv::Mat& disparity, cv::Mat& disparityImage, bool isColor) { // 将原始视差数据的位深转换为 8 位 cv::Mat disp8u; if (disparity.depth() != CV_8U) { disparity.convertTo(disp8u, CV_8U, 255/(64*16.)); } else { disp8u = disparity; } // 转换为伪彩色图像 或 灰度图像 if (isColor) { if (disparityImage.empty() || disparityImage.type() != CV_8UC3 ) { disparityImage = cv::Mat::zeros(disparity.rows, disparity.cols, CV_8UC3); } for (int y=0;y<disparity.rows;y++) { for (int x=0;x<disparity.cols;x++) { uchar val = disp8u.at<uchar>(y,x); uchar r,g,b; if (val==0) r = g = b = 0; else { r = 255-val; g = val < 128 ? val*2 : (uchar)((255 - val)*2); b = val; } disparityImage.at<cv::Vec3b>(y,x) = cv::Vec3b(r,g,b); } } } else { disp8u.copyTo(disparityImage); } IplImage * Image; Image = &IplImage (disparityImage); cvSaveImage("colordisparityImage.png",Image); namedWindow("3、disparityImage",1); cvShowImage("3、disparityImage",Image); waitKey(0); return 1; }
二、基于对话框的mfc, stereovision
当转换到mfc上的时候,发现好多代码是无法直接移植的,愁死我了。/(ㄒoㄒ)/~~后来一点点的改进,在这个过程中有很多的收获。
在网上搜了很多资料,针对两种算法,sgbm和gc算法,输入的图片要求不同,sgbm可以处理彩色图片,但是gc算法不允许,而且在转换为灰色图像的过程中,运行时会出现异常,在下面的代码里也都给出了解决的办法。但是因为本人学艺不精,就不给什么其他的注释了,大家尽量凭借自己的智慧去看吧。
1、头文件
#include "stdafx.h" #include "stereovision.h" #include "stereovisionDlg.h" #include "afxdialogex.h" #include <cstdio> #include<cstring> #include <cmath> #include <highgui.h> #include <cv.h> #include <cxcore.h> #include <iostream> #include <iostream> #include <stdlib.h> #include <cvaux.h> #include "opencv2/calib3d/calib3d.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/contrib/contrib.hpp" #pragma comment(lib,"opencv_highgui249d.lib") #pragma comment(lib,"opencv_core249d.lib") #pragma comment(lib,"opencv_imgproc249d.lib") #include <math.h> #include <GL/glut.h> #include <iostream>
2、sgbm算法
int CstereovisionDlg::StereoSGBM(IplImage* img1, IplImage* img2) { cv::StereoSGBM sgbm; int SADWindowSize = 9; sgbm.preFilterCap = 63; sgbm.SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 3; int cn = img1->nChannels; int numberOfDisparities=64; sgbm.P1 = 8*cn*sgbm.SADWindowSize*sgbm.SADWindowSize; sgbm.P2 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize; sgbm.minDisparity = 0; sgbm.numberOfDisparities = numberOfDisparities; sgbm.uniquenessRatio = 10; sgbm.speckleWindowSize = 100; sgbm.speckleRange = 32; sgbm.disp12MaxDiff = 1; Mat disp, disp8; int64 t = getTickCount(); sgbm((Mat)img1, (Mat)img2, disp); disp.convertTo(disp8, CV_8U, 255/(numberOfDisparities*16.)); cv::Mat di; getDisparityImage(disp8,di,true); waitKey(); return 1; }
3、gc算法
int CstereovisionDlg::StereoGC(IplImage* img1, IplImage* img2) { IplImage* imgl=cvCreateImage(cvGetSize(img1),img1->depth,1);//不可以仅仅设置为IplImage* imgl = NULL IplImage* imgr=cvCreateImage(cvGetSize(img2),img2->depth,1); cvCvtColor(img1,imgl,CV_BGR2GRAY); cvCvtColor(img2,imgr,CV_BGR2GRAY); CvStereoGCState* state = cvCreateStereoGCState( 64, 3 ); assert(state); CvMat* left_disp_ = cvCreateMat( imgl->height,imgl->width, CV_16S ); CvMat* right_disp_ = cvCreateMat( imgr->height,imgr->width,CV_16S ); CvMat* gcvdisp = cvCreateMat(imgl->height,imgl->width,CV_8U); cvFindStereoCorrespondenceGC( imgl, imgr, left_disp_, right_disp_, state, 0 ); cvNormalize(right_disp_,gcvdisp,0,255,CV_MINMAX); cv::Mat di; CvMat *a = gcvdisp; Mat b = Mat(a, true); getDisparityImage(b,di,true); //转换为彩色视图差 cvWaitKey(0); cvReleaseMat(&left_disp_); cvReleaseMat(&right_disp_); cvReleaseMat(&gcvdisp); cvReleaseStereoGCState(&state); return 1; }暂时先写到这里,其他的代码段我会抽空上传。希望对大家有所帮助。
相关文章推荐
- order by 列加索引
- MySQL中文全文检索demoSQL
- linux上jdk管理
- echarts 地图的背景色和各省颜色配置以及地图饼图联动
- 英语交流之路
- 浅析html input 等值改变添加监听事件
- hdu4513(manacher)
- win7系统修改系统安装时间
- 一个关于gravity和layout_gravity的例子
- WIFI无线调试android真机开发
- cordova app强制横屏
- nginx配置文件【转载】
- android SDK 代理
- Oracle DMP文件异常解决
- ASM磁盘组状态和使用率的监控
- php加密解密
- 实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(返回最小值的操作)的时间复杂度为O(1)
- [Swift 开发] UICollectionView的用法
- Android知识梳理之Service整理
- 【剑指 offer】(二十四)—— 二叉搜索树的后序遍历序列