OpenCV学习笔记(十二)之直方图比较

一. 直方图比较方法

       对输入的两张图像计算得到直方图H1和H2,归一化到相同的尺度空间,然后通过计算H1和H2之间的距离得到两个直方图的相似程度。

二. OpenCV提供的比较方法:

  1. Correlation - 相关性比较
  2. Chi-Square - 卡方比较
  3. Intersection - 十字交叉性
  4. Bhattacharyya - 巴氏距离

(一).相关性比较(HISTCOM_CORREL)

相关性比较

(二).卡方比较(HISTCOM_CHISQE)

卡方比较

(三). 十字交叉性(HISTCOM_INTERSECT)

十字交叉性

(四). 巴氏距离(HISTCOM_BHATTACHARYYA)

巴氏距离

三. API分析

cv::compareHist(
    InputArray h1,      //直方图数据
    InputArray h2,
    int method,         //比较方法
)

四. 代码实现:

/*****直方图比较*****/

#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>

using namespace std;

string DoubleToString(double b);

int main(int argc, char** argv) {
    cv::Mat src1, src2, src3;           //测试三张图片的相似度
    src1 = cv::imread("1.jpg");
    src2 = cv::imread("10.jpg");
    src3 = cv::imread("10.png");

    //将RGB空间转为HSV空间
    cv::cvtColor(src1, src1, cv::COLOR_BGR2HSV);
    cv::cvtColor(src2, src2, cv::COLOR_BGR2HSV);
    cv::cvtColor(src3, src3, cv::COLOR_BGR2HSV);
    
    //准备直方图的参数
    //两维的直方图
    int h_bins = 50;        //H的直方图的尺寸
    int s_bins = 60;        //S的直方图的尺寸
    int histSize[] = { h_bins, s_bins };

    //直方图的变化范围
    float h_ranges[] = { 0, 180 };  //H的变化范围
    float s_ranges[] = { 0, 256 };  //S的变化范围
    const float* ranges[] = { h_ranges, s_ranges };

    //二维的直方图使用两个通道0, 1
    int channels[] = { 0, 1 };
    //直方图数据
    cv::MatND hist_src1;
    cv::MatND hist_src2;
    cv::MatND hist_src3;

    //生成直方图,并将数据归一化到0-1之间
    cv::calcHist(&src1, 1, channels, cv::Mat(), hist_src1, 2, histSize,
        ranges, true, false);
    cv::calcHist(&src2, 1, channels, cv::Mat(), hist_src2, 2, histSize,
        ranges, true, false);
    cv::calcHist(&src3, 1, channels, cv::Mat(), hist_src3, 2, histSize,
        ranges, true, false);
    //归一化
    cv::normalize(hist_src1, hist_src1, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
    cv::normalize(hist_src2, hist_src2, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
    cv::normalize(hist_src3, hist_src3, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());

    //求出直方图的数据后,就可以进行比较了
    double src1_2 = cv::compareHist(hist_src1, hist_src2, cv::HISTCMP_CORREL);
    double src1_3 = cv::compareHist(hist_src1, hist_src3, cv::HISTCMP_CORREL);
    double src2_3 = cv::compareHist(hist_src2, hist_src3, cv::HISTCMP_CORREL);

    cout << "src1 compares with src2 correlation value: " << src1_2 << endl;
    cout << "src1 compares with src3 correlation value: " << src1_3 << endl;
    cout << "src2 compares with src3 correlation value: " << src2_3 << endl;

    //将比较数值显示到图像上
    cv::putText(src1, DoubleToString(src1_2), cv::Point(50, 50),
        cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(0, 0, 255), 2, cv::LINE_AA);
    cv::putText(src2, DoubleToString(src2_3), cv::Point(50, 50),
        cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(0, 0, 255), 2, cv::LINE_AA);
    
    cv::namedWindow("src1_1", cv::WINDOW_NORMAL);
    cv::namedWindow("src1_2", cv::WINDOW_NORMAL);

    cv::imshow("src1_2", src1);
    cv::imshow("src2_3", src2);

    cv::waitKey(0);
    return 0;

}

//Doublle 转 String
string DoubleToString(double b) {
    ostringstream os;
    if (os << b)
        return os.str();
    return "invalid value";  
}


       关注公号【开发小鸽】,获取海量计算机视觉与深度学习资源,实战项目源码,最新论文下载,大厂面试经验!!!​

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容