• opencvcompareHist直方图比较


    对输入的两张图像进行直方图均衡化及直方图计算步骤后,可以对两个图像的直方图进行对比 

    步骤

    a.先用cvtColor()把图像从RGB色彩空间转换到HSV色彩空间;

    b.计算图像的直方图,然后归一化到[0~1]之间,用到函数 calcHist() 和 normalize() ;

    c.使用四种方法之一进行比较,用到函数compareHist()

    实例

    lm.jpg

     lm1.jpg

     lm2.jpg

    #include<opencv2/opencv.hpp>
    #include<iostream>
    
    
    int main(int argc, char** argv) {
    
        cv::Mat src1 = cv::imread("D:/bb/tu/lm.jpg");
        cv::Mat src2 = cv::imread("D:/bb/tu/lm1.jpg");
        cv::Mat src3 = cv::imread("D:/bb/tu/lm2.jpg");
        if (!src1.data || !src2.data || !src3.data)
        {
            std::cout << "图片导入错误";
            return -1;
        }
        imshow("【src1原图】", src1);
        imshow("【src2原图】", src2);
        imshow("【src3原图】", src3);
    
        //从RGB色彩空间转化为HSV色彩空间,对 HS 两通道进行直方图统计
        cvtColor(src1, src1, cv::COLOR_BGR2HSV);
        cvtColor(src3, src3, cv::COLOR_BGR2HSV);
        cvtColor(src2, src2, cv::COLOR_BGR2HSV);
    
        //定义直方图计算所需要的各种参数
        int h_bins = 50;  //H通道分成50份
        int s_bins = 60;  //S通道分成60份
        int histSize[] = { h_bins,s_bins };
        float h_ranges[] = { 0,180 };  //H通道x轴取值范围0-180
        float s_ranges[] = { 0,256 };  //S通道x轴取值范围0-256
        const float* ranges[] = { h_ranges, s_ranges };
    
        int channels[] = { 0,1 };//对H和S两个通道进行直方图计算
    
        //MatND 是 Mat的别名,方便区分经过直方图计算处理后和输入图像
        cv::MatND hist_src1;
        cv::MatND hist_src2;
        cv::MatND hist_src3;
    
        //计算直方图并归一化处理
        calcHist(&src1, 3, channels, cv::Mat(), hist_src1, 2, histSize, ranges, true, false);
        /*
        参数2:由于图像是3通道的彩色图像,每个通道看做一个图像,所以是3
        参数5: 【 h_bins行,s_bins = 60列  】
        参数7:H通道的x轴被分成180分,S通道的x轴被分成255分
        参数8:H通道的x轴取值范围是r1,S通道的x轴取值范围是r2
        */
        normalize(hist_src1, hist_src1, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
    
        calcHist(&src2, 3, channels, cv::Mat(), hist_src2, 2, histSize, ranges, true, false);
        normalize(hist_src2, hist_src2, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
    
        calcHist(&src3, 3, channels, cv::Mat(), hist_src3, 2, histSize, ranges, true, false);
        normalize(hist_src3, hist_src3, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
    
        
        double src1_src1 = cv::compareHist(hist_src1, hist_src1, cv::HISTCMP_CORREL);//直方图比较
        /*
        参数1:比较图像1
        参数2:比较图像2
        参数3:比较方法
                cv::HISTCMP_CORREL-->相关性比较(Correlation),取值为[0,1],越接近1,直方图相似度越高
                cv::HISTCMP_CHISQR-->卡方Chi-square,取值为[0,1],越接近0,直方图相似度越高
                cv::HISTCMP_INTERSECT-->相交Intersection,
                cv::HISTCMP_BHATTACHARYYA-->巴氏距离Bhattacharyya,在直方图相似度计算时,巴氏距离获得的
                        效果最好,但计算是最为复杂的。巴氏距离的计算结果,其值完全匹配为1,完全不匹配则为0
    
        */
        std::cout << "src1与src1相关性比较结果:" << src1_src1 << std::endl;  // 1
    
        double src1_src2 = cv::compareHist(hist_src1, hist_src2, cv::HISTCMP_CORREL);
        std::cout << "src1与src2相关性比较结果:" << src1_src2 << std::endl; //0.0287919
    
        double src1_src3 = cv::compareHist(hist_src1, hist_src3, cv::HISTCMP_CORREL);
        std::cout << "src1与src3相关性比较结果:" << src1_src3 << std::endl; //0.0287075
    
        
    
        cv::waitKey(0);
        return 0;
    }

    比较方法:

    相关性比较(Correlation)

    相关性比较公式如下:

     其中

     如果H1 = H2,即两个图的直方图一样,分子等于分母,值为1,所以在不严格的情况下,当值为1时,可以认为两个图是一样的。但是也有可能会出现两个图不一样,但是两个图的直方图是一样的情况。因为直方图计算的是像素点个数的分布情况,但是不会显示像素点的位置,所以有可能会出现两幅图片不一样,但是相同像素的个数完全一样,那他们的直方图也是一样的,不过这种情况不常有

     

  • 相关阅读:
    清除浮动的方法
    网页滚动到顶部或底部加载
    任意两个数之间的随机数
    每五个一行
    js放大镜
    HTML5本地存储
    jquery checkbox radio 标签 选中的3种方法
    jquery mouseout mouseover 多次执行
    CentOS6.5安装MySQL5.7(也适合其他版本安装)
    ubuntu下ganglia3.7.2编译安装
  • 原文地址:https://www.cnblogs.com/liming19680104/p/15808731.html
Copyright © 2020-2023  润新知