• OpenCv 019---图像直方图比较


    1 前备知识

     图像直方图比较,就是比较两幅图像的直方图数据,比较两组数据的相似性,从而得到两幅图像之间的相似程度,直方图比较在早期的CBIR(基于内容的图像检索Content-based image retrieval)是较常应用的技术手段,通常结合边缘处理、词袋模型等技术一起使用。

    词袋模型英语:Bag-of-words model)是个在自然语言处理和信息检索(IR)下被简化的表达模型。此模型下,一段文本(比如一个句子或是一个文档)可以用一个装着这些词的袋子来表示,这种表示方式不考虑文法以及词的顺序。最近词袋模型也被应用在计算机视觉领域。

    词袋模型被广泛应用在文件分类,词出现的频率可以用来当作训练分类器的特征。

    2 所用到的主要OpenCv API

    CV_EXPORTS void calcHist( const Mat* images, int nimages,
                              const int* channels, InputArray mask,
                              OutputArray hist, int dims, const int* histSize,
                              const float** ranges, bool uniform = true, bool accumulate = false );

    /** @brief Calculates a histogram of a set of arrays.//计算一组数组的直方图

    @param images Source arrays. They all should have the same depth, CV_8U, CV_16U or CV_32F , and the same
    size. Each of them can have an arbitrary number of channels(任意的通道数).
    @param nimages Number of source images. //原图数量
    @param channels List of the dims channels used to compute the histogram. The first array channels
    are numerated from 0 to images[0].channels()-1 , the second array channels are counted from
    images[0].channels() to images[0].channels() + images[1].channels()-1, and so on.
    @param mask Optional mask. If the matrix is not empty, it must be an 8-bit array of the same size
    as images[i] . The non-zero mask elements mark the array elements counted in the histogram.
    @param hist Output histogram, which is a dense or sparse dims -dimensional array.
    @param dims Histogram dimensionality that must be positive and not greater than CV_MAX_DIMS
    (equal to 32 in the current OpenCV version).
    @param histSize Array of histogram sizes in each dimension.
    @param ranges Array of the dims arrays of the histogram bin boundaries in each dimension. When the
    histogram is uniform ( uniform =true), then for each dimension i it is enough to specify the lower
    (inclusive) boundary f$L_0f$ of the 0-th histogram bin and the upper (exclusive) boundary
    f$U_{ exttt{histSize}[i]-1}f$ for the last histogram bin histSize[i]-1 . That is, in case of a
    uniform histogram each of ranges[i] is an array of 2 elements. When the histogram is not uniform (
    uniform=false ), then each of ranges[i] contains histSize[i]+1 elements:
    f$L_0, U_0=L_1, U_1=L_2, ..., U_{ exttt{histSize[i]}-2}=L_{ exttt{histSize[i]}-1}, U_{ exttt{histSize[i]}-1}f$
    . The array elements, that are not between f$L_0f$ and f$U_{ exttt{histSize[i]}-1}f$ , are not
    counted in the histogram.
    @param uniform Flag indicating whether the histogram is uniform or not (see above).
    @param accumulate Accumulation flag. If it is set, the histogram is not cleared in the beginning
    when it is allocated. This feature enables you to compute a single histogram from several sets of
    arrays, or to update the histogram in time.
    */

    3 程序代码

    #include<opencv2opencv.hpp>
    #include <iostream>
    
    using namespace std;
    using namespace cv;
    
    int main(int argc, char** argv)
    {
        //load the image
        Mat src1 = imread("G:\CVworkstudy\program_wwx\Research society140\ZhaiZhigang140\m1.png");
        Mat src2 = imread("G:\CVworkstudy\program_wwx\Research society140\ZhaiZhigang140\m2.png");
        Mat src3 = imread("G:\CVworkstudy\program_wwx\Research society140\ZhaiZhigang140\flower.png");
        Mat src4 = imread("G:\CVworkstudy\program_wwx\Research society140\ZhaiZhigang140\wm.jpg");
        //show the image
        imshow("input1", src1);
        imshow("input2", src2);
        imshow("input3", src3);
        imshow("input4", src4);
        //convert hte HSV to BGR
        Mat hsv1, hsv2, hsv3, hsv4;
        cvtColor(src1, hsv1, COLOR_BGR2HSV);
        cvtColor(src2, hsv2, COLOR_BGR2HSV);
        cvtColor(src3, hsv3, COLOR_BGR2HSV);
        cvtColor(src4, hsv4, COLOR_BGR2HSV);
        //calculate the hist
        int h_bins = 60;
        int s_bins = 64;
        int histSize[] = { h_bins,s_bins };
        float h_ranges[] = { 0,180 };
        float s_ranges[] = { 0,255 };
        const float* ranges[] = { h_ranges,s_ranges };
        int channels[] = { 0,1 };
        Mat hist1, hist2, hist3, hist4;
        calcHist(&hsv1, 1, channels, Mat(), hist1, 2, histSize, ranges, true, false);
        calcHist(&hsv2, 1, channels, Mat(), hist2, 2, histSize, ranges, true, false);
        calcHist(&hsv3, 1, channels, Mat(), hist3, 2, histSize, ranges, true, false);
        calcHist(&hsv4, 1, channels, Mat(), hist4, 2, histSize, ranges, true, false);
    
        normalize(hist1, hist1, 0, 1, NORM_MINMAX, -1, Mat());
        normalize(hist2, hist2, 0, 1, NORM_MINMAX, -1, Mat());
        normalize(hist3, hist3, 0, 1, NORM_MINMAX, -1, Mat());
        normalize(hist4, hist4, 0, 1, NORM_MINMAX, -1, Mat());
    
        for (int i = 0; i < 4; i++)
        {
            int compare_method = i;
            double src1_src2 = compareHist(hist1, hist2, compare_method);
            double src3_src4 = compareHist(hist3, hist4, compare_method);
            printf(" Method [%d]: src1_src2: %f,src3_src4: %f,
    ", i, src1_src2, src3_src4);
        }
    
        waitKey(0);
        return 0;
    }

    4 运行结果

     

    5 扩展及注意事项

    null

    One day,I will say "I did it"
  • 相关阅读:
    Java--学生类(成员变量,成员方法输出学生信息和平均成绩)
    Java--水仙花数
    Java--学生类(成员变量,成员方法直接输出学生信息)
    Java--二分法查找
    矩阵转换
    建立一个框架,设置文字的颜色,字体,大小和位置
    使用字符串函数(作业)
    java 实现监听事件(使用按钮连续改变标签的颜色和字号)(上机倒数第二次作业)
    786.第k个数
    蓝桥杯
  • 原文地址:https://www.cnblogs.com/Vince-Wu/p/11409295.html
Copyright © 2020-2023  润新知