转自:http://blog.csdn.net/chentravelling/article/details/53672578
0.前言
视差与深度的关系戳这里。在opencv里应该有三种求视差的方法和一些问题集锦,可参考:http://blog.csdn.net/chenyusiyuan/article/details/5967291/
1.代码
void saveDisp(const char* filename, Mat mat);
int main()
{
char* filename = "../disparity_value.txt";
Mat left = imread("../image/left_199.png",CV_LOAD_IMAGE_GRAYSCALE);
Mat right = imread("../image/right_199.png",CV_LOAD_IMAGE_GRAYSCALE);
double t = (double)getTickCount();
Mat disp;
StereoBM bm;
CvStereoBMState *BMState = cvCreateStereoBMState();
bm.state->SADWindowSize = 15;
bm.state->minDisparity = 0;
bm.state->numberOfDisparities = 80;
bm.state->textureThreshold = 10;
bm.state->uniquenessRatio = 8;
bm.state->speckleWindowSize = 10;
bm.state->speckleRange = 32;
bm.state->disp12MaxDiff = -1;
copyMakeBorder(left, left, 0, 0, 80, 0, IPL_BORDER_REPLICATE);
copyMakeBorder(right, right, 0, 0, 80, 0, IPL_BORDER_REPLICATE);
bm.operator()(left,right,disp,CV_32F);
disp = disp.colRange(80, left.cols);
t = ((double)getTickCount() - t)/getTickFrequency();
cout<<"time:"<<t<<endl;
imshow("disp",disp);
saveDisp(filename,disp);
cvWaitKey(0);
return 0;
}
/**
将视差保存到txt,用于MATLAB读取
**/
void saveDisp(const char* filename, Mat mat)
{
int ih = mat.type();
FILE* fp = fopen(filename, "wt");
fprintf(fp, "%02d\n", mat.rows);
fprintf(fp, "%02d\n", mat.cols);
for(int y = 0; y < mat.rows; y++)
{
for(int x = 0; x < mat.cols; x++)
{
float disp = mat.at<float>(y, x);
fprintf(fp, "%f\n", disp);
}
}
fclose(fp);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
相应的Matlab代码为:
function img = txt2img(filename)
data = importdata(filename);
r = data(1);
c = data(2);
disp = data(3:end);
vmin = min(disp);
vmax = max(disp);
disp = reshape(disp, [c,r])'; % 将列向量形式的 disp 重构为 矩阵形式
% OpenCV 是行扫描存储图像,Matlab 是列扫描存储图像
% 故对 disp 的重新排列是首先变成 c 行 r 列的矩阵,然后再转置回 r 行 c 列
img = uint8( 255 * ( disp - vmin ) / ( vmax - vmin ) );
mesh(disp);
set(gca,'YDir','reverse');
axis tight;