直方图比较(图片相关性比较)

直方图比较方法

对输入的两张图像计算得到直方图H1和H2,归一化得到相同的尺度空间然后可以通过计算H1和H2之间的距离得到两个直方图相似程度进而比较图像本身的相似程度。opencv提供的比较方法有四种:

  • Correlation相关性比较(CV_COMP_CORREL)越接近1越相似
  • Chi-Square卡方比较(CV_COMP_CHISQR)越接近0越相似
  • Intersection十字交叉性(CV_COMP_INTERSECT)对于相似度比较这个算法不太好
  • Bhattacharyya distance巴氏距离(CV_COMP_BHATTACHARYYA)越接近1越相似

直方图一般比较步骤

  • 加载图像
  • 将图像色彩空间由BGR转换为HSV空间(由于直方图对亮度和灰度比较敏感,色彩空间转换就是突出这两个因素尽量去除其他因素)
  • 计算直方图进行归一化处理,归一化到0到1之间,calcHistnormalize
  • 直方图比较,使用上述四种方法之一,compareHist

参考链接:https://blog.csdn.net/shuiyixin/article/details/80257822


API介绍

API
double compareHist(InputArray h1,InputArray H2,int method)

参数介绍

  • 第一个参数InputArray类型 h1,直方图数据,下同
  • 第二个参数InputArray类型 h2,直方图数据,下同
  • 第三个参数int类型 method比较方法,上述四种方法之一
  • 返回值:采用上述四中方法之一计算后的两个直方图相关系数

代码演示

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

#define Pic_Path "/home/image/Pictures/my_picture/"
#define Pic_Name "model_1.jpeg"
#define Pic_Name1 "model_1_gray.jpeg"
#define Pic_Name2 "model_1_point.jpeg"

string convertToString(double d) {
    ostringstream os;
    if (os<<d)
    {
        return os.str();
    }
    return "invalid conversion";
}

//直方图比较
int main(void)
{
    string pic = string(Pic_Path) + string(Pic_Name);
    cout << pic << endl;

    string pic1 = string(Pic_Path) + string(Pic_Name1);
    cout << pic1 << endl;

    string pic2 = string(Pic_Path) + string(Pic_Name2);
    cout << pic2 << endl;

    cv::Mat src,srctest1,srctest2;
    //读取原始图片
    src      = cv::imread(pic.c_str());
    srctest1 = cv::imread(pic1.c_str());
    srctest2 = cv::imread(pic2.c_str());

    if(src.empty()||srctest1.empty()||srctest2.empty() )
    {
        cout << "其中有图片不存在" << endl;
        return -1;
    }
    cv::namedWindow("src",cv::WINDOW_AUTOSIZE);
    cv::imshow("src",src);

    cv::namedWindow("srctest1",cv::WINDOW_AUTOSIZE);
    cv::imshow("srctest1",srctest1);

    cv::namedWindow("srctest2",cv::WINDOW_AUTOSIZE);
    cv::imshow("srctest2",srctest2);

    //从RGB色彩空间转化为HSV色彩空间  色调、饱和度、亮度
    cvtColor(src, src, CV_BGR2HSV);
    cvtColor(srctest1, srctest1, CV_BGR2HSV);
    cvtColor(srctest2, srctest2, CV_BGR2HSV);

    //定义直方图计算所需要的各种参数
    int h_bins = 50;    //直方图通道1色调级数
    int s_bins = 60;    //直方图通道2饱和度级数
    int histSize[] = { h_bins,s_bins };    //直方图计算函数中的直方图级数参数

    float h_ranges[] = { 0,180 };   //直方图通道0色调通道值域范围
    float s_ranges[] = { 0,256 };   //直方图通道1饱和度通道值域范围
    const float* ranges[] = { h_ranges, s_ranges }; //直方图计算函数中的直方图值域范围参数

    int channels[] = { 0,1 };    //直方图计算函数中的通道参数

    //MatND 是 Mat的别名,方便区分经过直方图计算处理后和输入图像
    MatND hist_src;
    MatND hist_srctest1;
    MatND hist_srctest2;

    //计算直方图并归一化处理
    //原始图像     图像数目 通道数        MAsk        输出直方图数据 维数 直方图级数    值域范围       默认参数1 默认参数2
    //const Mat*  int     const int*   InputArray  OutputArray int  const int*  const float*  bool    bool
    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_src      = compareHist(hist_src, hist_src,      CV_COMP_CORREL);
    double src_srctest1 = compareHist(hist_src, hist_srctest1, CV_COMP_CORREL);
    double src_srctest2 = compareHist(hist_src, hist_srctest2, CV_COMP_CORREL);

    //打印计算后的相关性值
    cout << "src compare with src correlation value : "      << src_src      << endl;
    cout << "src compare with srctest1 correlation value : " << src_srctest1 << endl;
    cout << "src compare with srctest2 correlation value : " << src_srctest2 << endl;

    //给每个图像上添加文字,内容为该图片和原始图片的比较结果
    putText(src,      convertToString(src_src),      Point(50, 50), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(0, 255, 255), 2, LINE_AA);
    putText(srctest1, convertToString(src_srctest1), Point(50, 50), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 255),   2, LINE_AA);
    putText(srctest2, convertToString(src_srctest2), Point(50, 50), CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 0, 255), 2, LINE_AA);

    //图像的显示
    namedWindow("自身比较", CV_WINDOW_AUTOSIZE);
    namedWindow("灰度比较", CV_WINDOW_AUTOSIZE);
    namedWindow("杂质比较", CV_WINDOW_AUTOSIZE);
    //namedWindow(OUTPUT_TITLE, CV_WINDOW_AUTOSIZE);

    imshow("自身比较", src);
    imshow("灰度比较", srctest1);
    imshow("杂质比较", srctest2);


    cv::waitKey(0);
    cv::destroyAllWindows();
}

运行结果

/home/image/Pictures/my_picture/model_1.jpeg
/home/image/Pictures/my_picture/model_1_gray.jpeg
/home/image/Pictures/my_picture/model_1_point.jpeg
src compare with src correlation value : 1
src compare with srctest1 correlation value : -0.00129504
src compare with srctest2 correlation value : 0.999878

原始图片
原始图片
计算结果
计算结果


补充知识

色调 H : 0 ~ 180
用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°, 蓝色为240°。它们的补色是:黄色为60°,青色为180°, 品红为300°;
饱和度 S :0 ~ 255
饱和度S表示颜色接近光谱色的程度。一种颜色,可以看成是某种光谱色与白色混合的结果。其中光谱色所占的比例愈大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高。饱和度高,颜色则深而艳。光谱色的白光成分为0,饱和度达到最高。通常取值范围为0%~100%,值越大,颜色越饱和。
亮度 V : 0 ~ 255
亮度表示颜色明亮的程度,对于光源色,亮度值与发光体的光亮度有关;对于物体色,此值和物体的透射比或反射比有关。通常取值范围为0%(黑)到100%(白)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值