C++实现双目立体匹配Census算法的示例代码_C 语言

来源:脚本之家  责任编辑:小易  

上一篇介绍了双目立体匹配SAD算法,这一篇介绍Census算法。

Census原理:

在视图中选取任一点,以该点为中心划出一个例如3 × 3 的矩形,矩形中除中心点之外的每一点都与中心点进行比较,灰度值小于中心点记为1,灰度大于中心点的则记为0,以所得长度为 8 的只有 0 和 1 的序列作为该中心点的 census 序列,即中心像素的灰度值被census 序列替换。经过census变换后的图像使用汉明距离计算相似度,所谓图像匹配就是在匹配图像中找出与参考像素点相似度最高的点,而汉明距正是匹配图像像素与参考像素相似度的度量。具体而言,对于欲求取视差的左右视图,要比较两个视图中两点的相似度,可将此两点的census值逐位进行异或运算,然后计算结果为1 的个数,记为此两点之间的汉明值,汉明值是两点间相似度的一种体现,汉明值愈小,两点相似度愈大实现算法时先异或再统计1的个数即可,汉明距越小即相似度越高。

下面的代码是自己根据原理写的,实现的结果并没有很好,以后继续优化代码。

具体代码如下:

//*************************Census*********************
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>

using namespace std;
using namespace cv;

//-------------------定义汉明距离----------------------------
int disparity;
int GetHammingWeight(uchar value);//求1的个数

//-------------------定义Census处理图像函数---------------------
int hWind = 1;//定义窗口大小为(2*hWind+1)
Mat ProcessImg(Mat &Img);//将矩形内的像素与中心像素相比较,将结果存于中心像素中
Mat Img_census, Left_census, Right_census;

//--------------------得到Disparity图像------------------------
Mat getDisparity(Mat &left, Mat &right);

//--------------------处理Disparity图像-----------------------
Mat ProcessDisparity(Mat &disImg);

int ImgHeight, ImgWidth;

//int num = 0;//异或得到的海明距离
Mat LeftImg, RightImg;
Mat DisparityImg(ImgHeight, ImgWidth, CV_8UC1, Scalar::all(0));
Mat DisparityImg_Processed(ImgHeight, ImgWidth, CV_8UC1, Scalar::all(0));
Mat DisparityImg_Processed_2(ImgHeight, ImgWidth, CV_8UC1);
//定义读取图片的路径
string file_dir="C:\\Program Files\\FLIR Integrated Imaging Solutions\\Triclops Stereo Vision SDK\\stereomatching\\Grab_Stereo\\pictures\\";
//定义存储图片的路径
string save_dir= "C:\\Program Files\\FLIR Integrated Imaging Solutions\\Triclops Stereo Vision SDK\\stereomatching\\Grab_Stereo\\Census\\";

int main()
{
    LeftImg = imread(file_dir + "renwu_left.png", 0);
    RightImg = imread(file_dir + "renwu_right.png", 0);
    namedWindow("renwu_left", 1);
    namedWindow("renwu_right", 1);
    imshow("renwu_left", LeftImg);
    waitKey(5);
    imshow("renwu_right", RightImg);
    waitKey(5);
    ImgHeight = LeftImg.rows;
    ImgWidth = LeftImg.cols;

    Left_census= ProcessImg(LeftImg);//处理左图,得到左图的CENSUS图像 Left_census
    namedWindow("Left_census", 1);
    imshow("Left_census", Left_census);
    waitKey(5);
//  imwrite(save_dir + "renwu_left.jpg", Left_census);

    Right_census= ProcessImg(RightImg);
    namedWindow("Right_census", 1);
    imshow("Right_census", Right_census);
    waitKey(5);
//  imwrite(save_dir  + "renwu_right.jpg", Right_census);

    DisparityImg= getDisparity(Left_census, Right_census);
    namedWindow("Disparity", 1);
    imshow("Disparity", DisparityImg);
//  imwrite(save_dir  + "disparity.jpg", DisparityImg);
    waitKey(5);

    DisparityImg_Processed = ProcessDisparity(DisparityImg);
    namedWindow("DisparityImg_Processed", 1);
    imshow("DisparityImg_Processed", DisparityImg_Processed);
//  imwrite(save_dir + "disparity_processed.jpg", DisparityImg_Processed);
    waitKey(0);
    return 0;
}


//-----------------------对图像进行census编码---------------
Mat ProcessImg(Mat &Img)
{
    int64 start, end;
    start = getTickCount();

    Mat Img_census = Mat(Img.rows, Img.cols, CV_8UC1, Scalar::all(0));
    uchar center = 0;

    for (int i = 0; i < ImgHeight - hWind; i++)
    {
        for (int j = 0; j < ImgWidth - hWind; j++)
        {
            center = Img.at<uchar>(i + hWind, j + hWind);
            uchar census = 0;
            uchar neighbor = 0;
            for (int p = i; p <= i + 2 * hWind; p++)//行
            {
                for (int q = j; q <= j + 2 * hWind; q++)//列
                {
                    if (p >= 0 && p <ImgHeight  && q >= 0 && q < ImgWidth)
                    {

                        if (!(p == i + hWind && q == j + hWind))
                        {
                            //--------- 将二进制数存在变量中-----
                            neighbor = Img.at<uchar>(p, q);

                            if (neighbor > center)
                            {
                                census = census * 2;//向左移一位,相当于在二进制后面增添0
                            }
                            else
                            {
                                census = census * 2 + 1;//向左移一位并加一,相当于在二进制后面增添1
                            }
                            //cout << "census = " << static_cast<int>(census) << endl;
                        }
                    }
                }

            }
            Img_census.at<uchar>(i + hWind, j + hWind) = census;
        }
    }
    /*end = getTickCount();
    cout << "time is = " << end - start << " ms" << endl;*/
    return Img_census;
}

//------------得到汉明距离---------------
int GetHammingWeight( uchar value)
{
    int num = 0;
    if (value == 0)
        return 0;
    while (value)
    {
        ++num;
        value = (value - 1)&value;
    }
    return num;
}

//--------------------得到视差图像--------------
Mat getDisparity(Mat &left, Mat &right)
{
    int DSR =16;//视差搜索范围
    Mat disparity(ImgHeight,ImgWidth,CV_8UC1);

    cout << "ImgHeight = " << ImgHeight << "   " << "ImgWidth = " << ImgWidth << endl;
    for (int i = 0; i < ImgHeight; i++)
    {
        for (int j = 0; j < ImgWidth; j++)
        {
            uchar L;
            uchar R;
            uchar diff;

            L = left.at<uchar>(i, j);
            Mat Dif(1, DSR, CV_8UC1);
//          Mat Dif(1, DSR, CV_32F);

            for (int k = 0; k < DSR; k++)
            {
                //cout << "k = " << k << endl;
                int y = j - k;
                if (y < 0)
                {
                    Dif.at<uchar>(k) = 0;
                }
                if (y >= 0)
                {
                    R = right.at<uchar>(i,y);
                    //bitwise_xor(L, R, );
                    diff = L^R;
                    diff = GetHammingWeight(diff);
                    Dif.at<uchar>(k) = diff;
//                  Dif.at<float>(k) = diff;
                }
            }
            //---------------寻找最佳匹配点--------------
            Point minLoc;
            minMaxLoc(Dif, NULL, NULL, &minLoc, NULL);
            int loc = minLoc.x;
            //cout << "loc..... = " << loc << endl;
            disparity.at<uchar>(i,j)=loc*16;
        }
    }
    return disparity;
}

//-------------对得到的视差图进行处理-------------------
Mat ProcessDisparity(Mat &disImg)
{
    Mat ProcessDisImg(ImgHeight,ImgWidth,CV_8UC1);//存储处理后视差图
    for (int i = 0; i < ImgHeight; i++)
    {
        for (int j = 0; j < ImgWidth; j++)
        {
            uchar pixel = disImg.at<uchar>(i, j);
            if (pixel < 100)
                pixel = 0;
            ProcessDisImg.at<uchar>(i, j) = pixel;
        }
    }
    return ProcessDisImg;
}

经过处理后的左图census图像

经过处理后的右图census图像

disparity图像

处理后的disparity图像

以上就是C++实现双目立体匹配Census算法的示例代码的详细内容,更多关于C++双目立体匹配Census算法的资料请关注真格学网其它相关文章!

您可能感兴趣的文章:opencv3/C++ FLANN特征匹配方式c++ 实现文件逐行读取与字符匹配opencv?C++模板匹配的简单实现

  • 本文相关:
  • c语言数据类型枚举enum全面详解示例教程
  • c++实现双向链表代码分析
  • vc多线程编程详解
  • vs2019中使用mfc构建简单windows窗口程序
  • c++ 虚函数表图文解析
  • c++ 获取进程cpu占用率
  • c语言简单实现求n阶勒让德多项式的方法
  • c++ ofstream与ifstream详细用法
  • c语言break和continue的语句用法
  • c++实现归并排序(mergesort)
  • 双目视觉的匹配算法是不是有好几种?具体是哪几种?
  • 双目立体视觉可以测障碍物高度吗
  • 双目80万像素的立体视觉感知,实时性到底能做到什么程度?如果...
  • 双眼可以测距和建立立体环境,双摄像头可以吗?
  • 三d立体图怎么看
  • 三d立体图怎么看
  • 一只眼睛正常,另一眼睛近视200度怎么办
  • 形容五官立体的句子?
  • 立体盲日常如何做辅助治疗,眼保健操有用吗?因注意哪些问题?...
  • 什么是主动立体投影
  • SuperD HDB103 3D立体显示器的产品怎样
  • 3D立体液晶电视的3D立体电视TCL分类
  • 什么叫烟台立体雕眉?效果好吗?
  • 谁了解虚拟现实方法中,洞穴式立体显示的原理么
  • 通过双目摄像头,通过对运动物体进行拍照的方式,能否精确计算...
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全c#教程vbvb.netc 语言java编程delphijavaandroidiosswiftscala易语言汇编语言r语言其它相关首页opencv3/c++ flann特征匹配方式c++ 实现文件逐行读取与字符匹配opencv?c++模板匹配的简单实现c语言数据类型枚举enum全面详解示例教程c++实现双向链表代码分析vc多线程编程详解vs2019中使用mfc构建简单windows窗口程序c++ 虚函数表图文解析c++ 获取进程cpu占用率c语言简单实现求n阶勒让德多项式的方法c++ ofstream与ifstream详细用法c语言break和continue的语句用法c++实现归并排序(mergesort)c语言程序设计50例(经典收藏)c语言10个经典小程序c语言字符串操作总结大全(超详细)c语言文件操作函数大全(超详细)c语言运算符优先级列表(超详细)c语言字符数组与字符串的使用详解c语言/c++中如何产生随机数c++中的string常用函数用法总结深入理解c++中public、protected及privac++常用字符串分割方法实例汇总c++ sort排序函数用法详解c++中的while循环和for循环语句学习教程c语言中函数返回字符串的方法汇总clion搭建配置c++开发环境的图文教程 (mingw-w64 gcc-8c语言实现猜数游戏c语言程序中递归算法的使用实例教程c++单例模式应用实例vc++ 控件list control用法总结解析c语言基于udp协议进行socket编程的要点c语言中return与exit的区别浅析
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved