美文网首页图像处理OpenCv
【图像处理】OpenCV系列三十四--- compareHist

【图像处理】OpenCV系列三十四--- compareHist

作者: 307656af5a04 | 来源:发表于2019-05-17 17:30 被阅读24次

    1、函数原型

    // 原型一
    double compareHist(InputArray H1,
        InputArray H2,
        int method)     
    
    // 原型二
    double compareHist(const SparseMat &H1,
        const SparseMat &H2,
        int method) 
    

    2、函数功能

    用指定的方法比较两个密集或两个稀疏直方图;
    该函数适用于1-、2-、3维密集直方图,但不适用于高维稀疏直方图;在这种柱状图中,由于存在混叠和采样问题,非零柱状图的坐标会发生轻微的偏移;为了比较这些柱状图或更一般的加权点稀疏配置,考虑使用EMD函数;

    3、参数详解

    • 第一个参数,InputArray H1,待比较的第一个直方图;

    • 第二个参数,InputArray H2,待比较的第二个直方图,与第一个直方图具有相同的大小;

    • 第三个参数,int method,直方图比较的方法;

    具体有如下方法:

    (1) HISTCMP_CORREL,相关性;

    相关性

    其中,

    image.png

    N是总的柱状图bins个数;

    (2) HISTCMP_CHISQR ,卡方;

    卡方

    (3) HISTCMP_INTERSECT,交叉;

    交叉

    (4) HISTCMP_BHATTACHARYYA,Bhattacharyya距离(事实上,opencv计算了与Bhattacharyya系数相关的Hellinger距离);

    Bhattacharyya距离

    (5) HISTCMP_HELLINGER,与HISTCMP_BHATTACHARYYA相同;
    (6) HISTCMP_CHISQR_ALT,变种卡方,这种替代公式经常用于纹理比较;

    变种卡方

    (7) HISTCMP_KL_DIV,交叉熵的K-L散度;

    交叉熵的K-L散度
    • 返回值,返回两个直方图比较的结果;

    4、实验实例

    #define INPUT_TITLE0 "input image srctest1-srctest2"
    #define INPUT_TITLE1 "input image srctest1"
    #define INPUT_TITLE2 "input image srctest2"
     
    #include <iostream>
    #include <math.h>
    #include <opencv2/opencv.hpp>
     
    using namespace std;
    using namespace cv;
     
     
    string convertToString(double d);
     
    int main() 
    {
        // 加载图像 
        Mat src, srctest1, srctest2;
        src = imread("lena.png");
        srctest1 = imread("1.png");
        srctest2 = imread("2.png");
        
        // 判断图像是否为空
        if (!src.data|| !srctest1.data|| !srctest2.data)
        {
            cout << "ERROR : could not load image.";
            return -1;
        }
        
        // 显示原始图像
        imshow("【src 原图】", src);
        imshow("【srctest1 原图】", srctest1);
        imshow("【srctest2 原图】", srctest2);
     
        //从RGB色彩空间转化为HSV色彩空间
        cvtColor(src, src, COLOR_BGR2HSV);
        cvtColor(srctest1, srctest1, COLOR_BGR2HSV);
        cvtColor(srctest2, srctest2, COLOR_BGR2HSV);
     
        //定义直方图计算所需要的各种参数
        int h_bins = 50;
        int s_bins = 60;
        int histSize[] = { h_bins,s_bins };
     
        float h_ranges[] = { 0,180 };
        float s_ranges[] = { 0,256 };
        const float* ranges[] = { h_ranges, s_ranges };
     
        int channels[] = { 0,1 };
     
        // MatND 是 Mat的别名,方便区分经过
        // 直方图计算处理后和输入图像
        MatND hist_src;
        MatND hist_srctest1;
        MatND hist_srctest2;
     
        //计算直方图并归一化处理
        calcHist(&src, 1, channels, Mat(), 
            hist_src, 2, histSize, ranges, true, false);
            
        normalize(hist_src, hist_src, 0, 1, 
            NORM_MINMAX, -1, Mat());
     
        calcHist(&srctest1, 1, channels, Mat(), 
            hist_srctest1, 2, histSize, ranges, true, false);
            
        normalize(hist_srctest1, hist_srctest1, 0, 1, 
            NORM_MINMAX, -1, Mat());
        
        calcHist(&srctest2, 1, channels, Mat(), 
            hist_srctest2, 2, histSize, ranges, true, false);
            
        normalize(hist_srctest2, hist_srctest2, 0, 1, 
            NORM_MINMAX, -1, Mat());
        
        //直方图比较
        double src_srctest1 = compareHist(hist_src, 
            hist_srctest1, HISTCMP_CORREL);
            
        double src_srctest2 = compareHist(hist_src, 
        hist_srctest2, HISTCMP_CORREL);
        
        double srctest1_srctest2 = compareHist(hist_srctest1, 
            hist_srctest2, HISTCMP_CORREL);
     
        cout << "src compare with \
            srctest1_srctest2 correlation value : " 
            << srctest1_srctest2 << endl;
            
        cout << "src compare with \
            srctest1 correlation value : " 
            << src_srctest1 << endl;
            
        cout << "src compare with \
            srctest2 correlation value : " 
            << src_srctest2 << endl;
     
        // 给每个图像上添加文字,内容为
        // 该图片和原始图片的比较结果
        putText(srctest1, convertToString(src_srctest1), 
            Point(50, 50), FONT_HERSHEY_COMPLEX, 1, 
            Scalar(0, 0, 255), 2, LINE_AA);
            
        putText(srctest2, convertToString(src_srctest2), 
            Point(50, 50), FONT_HERSHEY_COMPLEX, 1, 
            Scalar(255, 0, 255), 2, LINE_AA);
            
        putText(src, convertToString(srctest1_srctest2), 
            Point(50, 50), FONT_HERSHEY_COMPLEX, 1, 
            Scalar(0, 255, 255), 2, LINE_AA);
     
        //图像的显示
        namedWindow(INPUT_TITLE0, WINDOW_AUTOSIZE);
        namedWindow(INPUT_TITLE1, WINDOW_AUTOSIZE);
        namedWindow(INPUT_TITLE2, WINDOW_AUTOSIZE);
     
        imshow(INPUT_TITLE0, src);
        imshow(INPUT_TITLE1, srctest1);
        imshow(INPUT_TITLE2, srctest2);
        
     
        waitKey(0);
        return 0;
    }
     
    string convertToString(double d) {
        ostringstream os;
        if (os<<d)
        {
            return os.str();
        }
        return "invalid conversion";
    }
    

    5、实验结果

    三幅原图 原图与中间图像直方图的比较结果 原图与第三张图像直方图的比较结果 中间图像与第三张图像直方图的比较结果

    我是奕双,现在已经毕业将近两年了,从大学开始学编程,期间学习了C语言编程,C++语言编程,Win32编程,MFC编程,毕业之后进入一家图像处理相关领域的公司,掌握了用OpenCV对图像进行处理,如果大家对相关领域感兴趣的话,可以关注我,我这边会为大家进行解答哦!如果大家需要相关学习资料的话,可以私聊我哦!

    相关文章

      网友评论

        本文标题:【图像处理】OpenCV系列三十四--- compareHist

        本文链接:https://www.haomeiwen.com/subject/nyxvaqtx.html