OpenCV24---直方图比较

二十四、直方图比较
利用两张图片的直方图判断两张图片的相似性,也可以判断两个图片是否为同一图片。
1、直方图比较方法
对输入的两张图象计算得到直方图H1与H2,归一化到相同的尺度空间然后可以通过计算H1和H2之间的距离得到两个直方图的相似程度进而比较图像本身的相似程度。opencv提供的比较方法有4种:

  • Correlation相关性比较 HISTCMP_CORREL
    如果两个数组H1、H2一样的情况下,相关性最大,得到的值为1。
    在这里插入图片描述
  • Chi-Square卡方比较HISTCMP_CHISQR
    如果H1、H2完全相同,相关性最大,得到的值为0。
    在这里插入图片描述
  • Intersection十字交叉性HISTCMP_INTERSECT(不准确,慎用)
    在这里插入图片描述
  • Bhattacharyya distance巴氏距离HISTCMP_BHATTACHARYYA
    如果H1、H2完全相同,相关性最大,得到的值为0。
    在这里插入图片描述

2、相关API

  • 首先把图像从RGB色彩空间转换到HSV色彩空间cvtColor
  • 计算图像的直方图,然后归一化到0-1之间calcHistnormalize
  • 使用上述四种方法之一进行比较compareHist
compareHist(
InputArray h1,//直方图数据,下同
InputArray h2,
int method//比较方法,上述四种方法之一
)

示例代码:(直方图比较)

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

using namespace cv;
using namespace std;

string convertToString(double d);//将double型数据转为字符型

int main(int argc, char* argv) {
    Mat src, test1, test2;
    src = imread("添加图片路径");
    if (!src.data) {
        cout << "could not load image..." << endl;
  	return -1;
    }
    test1 = imread("添加图片路径");

    cvtColor(src, src, COLOR_BGR2HSV);//将测试图片转至HSV色彩空间,后面只取HS两个色彩空间计算直方图,因为色彩和饱和度是直方图中最敏感的表征量
    cvtColor(test1, test1, COLOR_BGR2HSV);
    
    int h_bins = 50; int s_bins = 60;//划分一张图片两个通道直方图的bin
    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 hist_src;//ND表示多维
    MatND hist_test1;
    
    calcHist(&src, 1, channels, Mat(), hist_src, 2, histSize, ranges, true, false);//直方图计算
    normalize(hist_src, hist_src, 0, 1, NORM_MINMAX, -1, Mat());//归一化
    
    calcHist(&test1, 1, channels, Mat(), hist_test1, 2, histSize, ranges, true, false);
    normalize(hist_test1, hist_test1, 0, 1, NORM_MINMAX, -1, Mat());
    
    double srcsrc = compareHist(hist_src, hist_src, HISTCMP_CORREL);//src与src做直方图相关性比较
    //double srctest1 = compareHist(hist_src, hist_test1, HISTCMP_CORREL);//src与test1做直方图相关性比较
    double srctest1 = compareHist(hist_src, hist_test1, HISTCMP_BHATTACHARYYA);//src与test1做直方图巴氏比较
    printf("src compare with test1 correlation value : %f", srctest1);
    
    putText(src, convertToString(srcsrc), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 0), 2, LINE_AA);//在图像上打印比较结果
    putText(test1, convertToString(srctest1), Point(50, 50), FONT_HERSHEY_COMPLEX, 1, Scalar(0, 0, 0), 2, LINE_AA);
    
    namedWindow("src", WINDOW_AUTOSIZE);
    namedWindow("test1", WINDOW_AUTOSIZE);
    
    imshow("src", src);
    imshow("test1", test1);
    
    waitKey(0);
    return 0;
}

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

输出结果显示:

  • 相关性比较方法
    在这里插入图片描述
    分析:用的图片分别是一张图片和其提升对比度后的图片,可以看出经过相关性比较,两张图片直方图比较的结果接近1,说明相似度很高。而左侧图片和自身对比的结果为1,说明两张图片相同。

  • 巴氏距离比较方法

在这里插入图片描述

分析:两张一样的图片做对比,结果为0,验证了两张图片为同一张图。
一张图片和提升对比度后的图片做直方图巴氏比较,得到的值较小,说明两张图片相似性较高。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值