图像处理OpenCv

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

2019-05-17  本文已影响24人  307656af5a04

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、参数详解

具体有如下方法:

(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对图像进行处理,如果大家对相关领域感兴趣的话,可以关注我,我这边会为大家进行解答哦!如果大家需要相关学习资料的话,可以私聊我哦!

上一篇下一篇

猜你喜欢

热点阅读