StereoBM:opencv计算视差

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:"<"disp",disp);
    saveDisp(filename,disp);
    cvWaitKey(0);
    return 0;
}

/**
将视差保存到txt,用于MATLAB读取
**/
void saveDisp(const char* filename,  Mat mat)       
{
    int ih = mat.type();
    //float disp = mat.at(0,0); 
    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); // 这里视差矩阵是CV_16S 格式的,故用 short 类型读取
            fprintf(fp, "%f\n", disp); // 若视差矩阵是 CV_32F 格式,则用 float 类型读取
        }
    }
    fclose(fp);
}
相应的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');  % 通过 mesh 方式绘图时,需倒置 Y 轴方向
axis tight; % 使坐标轴显示范围与数据范围相贴合,去除空白显示区

StereoBM:opencv计算视差_第1张图片

你可能感兴趣的:(【图像处理】,图像处理)