ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

直方图(opencv)

2021-12-20 10:33:25  阅读:196  来源: 互联网

标签:distance Mat cvRound src hist opencv 直方图


一、介绍

 图像直方图是用一表示数字图像中亮度分布的直方图,标绘了图像中每个亮度值的像素数。可以借助观察该直方图了解需要如何调整亮度分布的直方图。这种直方图中,横坐标的左侧为纯黑、较暗的区域,而右侧为较亮、纯白的区域。因此,一张较暗图片的图像直方图中的数据多集中于左侧和中间部分,而整体明亮、只有少量阴影的图像则相反。计算机视觉邻域常借助图像直方图来实现图像的二值化。


二、API函数

C++ Void calcHist(
	        const Mat* images,//输入图像指针
	        int images,// 图像数目
	        const int* channels,// 通道数
	        InputArray mask,// 输入mask,可选,不用
	        OutputArray hist,//输出的直方图数据
	        int dims,// 维数
	        const int* histsize,// 直方图级数
	        const float* ranges,// 值域范围
	        bool uniform,// true by default
	        bool accumulate)// false by defaut
函数cvRound,cvFloor,cvCeil 都是用一种舍入的方法将输入浮点数转换成整数:

cvRound():返回跟参数最接近的整数值,即四舍五入;
cvFloor():返回不大于参数的最大整数值,即向下取整;
cvCeil():返回不小于参数的最小整数值,即向上取整;

三、绘制图像直方图

1、使用API函数 calcHist计算图像直方图;

2、进行直方图归一化;

3、绘制各级直方图;

#include<opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
    Mat src, dst;
    src = imread("1.jpg");
    cvtColor(src, src, COLOR_BGR2GRAY);
    int histSize = 16;
    float range[] = { 0, 256 };
    const float* histRange = { range };
    if (src.data && src.channels()==1)
    {
        cout << "您输入的是灰度图像" << endl;
        Mat hist;
        calcHist(&src, 1, 0, Mat(), hist, 1, &histSize, &histRange, true, false);

        //绘制直方图
        int hist_w = 512, hist_h = 400;
        //直方图中各点x轴距离
        int distance = cvRound((double)hist_w / histSize);
        //创建一个图像以显示直方图
        Mat histImage1(hist_h, hist_w, src.type(), Scalar(255, 255, 255));
        //归一化直方图
        normalize(hist, hist, 0, hist_h, NORM_MINMAX, -1,Mat());
        for (int i = 1; i < histSize; i++)
        {
            // hist_h - cvRound(hist.at<float>(i)):hist.at<float>(i)存储的值是从图像
            //左上角为0开始计算的,所以需要使用hist_h减以后才是坐标轴的纵轴值
            line(histImage1, Point(distance * (i-1), hist_h - cvRound(hist.at<float>(i-1))),
                 Point(distance * (i), hist_h - cvRound(hist.at<float>(i))),
                 Scalar(0,0,255),2,8,0);
        }
        namedWindow("calcHist1", WINDOW_AUTOSIZE);
        imshow("calcHist1", histImage1);
    }

    else if (src.data && src.channels() == 3)
    {
        cout << "您输入的是彩色图像" << endl;
        vector<Mat> mv;
        split(src, mv);
        Mat b_hist, g_hist, r_hist;
        calcHist(&mv[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, true, false);
        calcHist(&mv[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, true, false);
        calcHist(&mv[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, true, false);


        // 绘制直方图
        int hist_w = 512,hist_h = 400;
        int distance = cvRound((double)hist_w / histSize);
        Mat histImage(hist_h, hist_w, CV_8UC3, Scalar(255, 255, 255));
        normalize(b_hist, b_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
        normalize(g_hist, g_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
        normalize(r_hist, r_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
        for (int i = 1; i < histSize; i++)
        {
            //
            line(histImage, Point(distance * (i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),
                Point(distance * (i), hist_h - cvRound(b_hist.at<float>(i))),
                Scalar(255, 0, 0), 2, 8, 0);
            line(histImage, Point(distance * (i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),
                Point(distance * (i), hist_h - cvRound(g_hist.at<float>(i))),
                Scalar(0, 255, 0), 2, 8, 0);
            line(histImage, Point(distance * (i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),
                Point(distance * (i), hist_h - cvRound(r_hist.at<float>(i))),
                Scalar(0, 0, 255), 2, 8, 0);
        }
        namedWindow("calcHist", WINDOW_AUTOSIZE);
        imshow("calcHist", histImage);
    }

    else
    {
        cout << "您未输入图像" << endl;
        return -1;
    }
    
    waitKey(0);
    return 0;
}

四、直方图比较

  1. 为了比较两个直方图( H1 和 H2 ),首先我们必须选择度量( d(H1,H2)来表示两个直方图的匹配度。
  2. OpenCV实现函数cv :: compareHist进行比较。它还提供4种不同的指标来计算匹配:
  • 相关性(CV_COMP_CORREL)(1为最相似)

OpenCV直方图比较

其中:

OpenCV直方图比较

N是直方图库的总数。

  • Chi-Square(CV_COMP_CHISQR)(0为最相似)

OpenCV直方图比较

  • 交点(method= CV_COMP_INTERSECT)(越大越相似)

OpenCV直方图比较

  • Bhattacharyya distance ( CV_COMP_BHATTACHARYYA )(0为最相似)

OpenCV直方图比较

 

*Method*Base - Base
*Correlation*1.000000
*Chi-square*0.000000
*Intersection*24.391548
*Bhattacharyya*0.000000
#include<opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
    Mat src, dst;
    src = imread("12.bmp");
    namedWindow("原图", WINDOW_AUTOSIZE);
    imshow("原图", src);
    int histSize = 16;
    float range[] = { 0, 256 };
    const float* histRange = { range };
    if (src.data && src.channels()==1)
    {
        cout << "您输入的是灰度图像" << endl;
        Mat hist;
        calcHist(&src, 1, 0, Mat(), hist, 1, &histSize, &histRange, true, false);

        //绘制直方图
        int hist_w = 512, hist_h = 400;
        //直方图中各点x轴距离
        int distance = cvRound((double)hist_w / histSize);
        //创建一个图像以显示直方图
        Mat histImage1(hist_h, hist_w, src.type(), Scalar(255, 255, 255));
        //归一化直方图
        normalize(hist, hist, 0, hist_h, NORM_MINMAX, -1,Mat());
        for (int i = 1; i < histSize; i++)
        {
            // hist_h - cvRound(hist.at<float>(i)):hist.at<float>(i)存储的值是从图像
            //左上角为0开始计算的,所以需要使用hist_h减以后才是坐标轴的纵轴值
            line(histImage1, Point(distance * (i-1), hist_h - cvRound(hist.at<float>(i-1))),
                 Point(distance * (i), hist_h - cvRound(hist.at<float>(i))),
                 Scalar(0,0,255),2,8,0);
        }
        namedWindow("calcHist1", WINDOW_AUTOSIZE);
        imshow("calcHist1", histImage1);
    }

    else if (src.data && src.channels() == 3)
    {
        cout << "您输入的是彩色图像" << endl;
        vector<Mat> mv;
        split(src, mv);
        Mat b_hist, g_hist, r_hist;
        calcHist(&mv[0], 1, 0, Mat(), b_hist, 1, &histSize, &histRange, true, false);
        calcHist(&mv[1], 1, 0, Mat(), g_hist, 1, &histSize, &histRange, true, false);
        calcHist(&mv[2], 1, 0, Mat(), r_hist, 1, &histSize, &histRange, true, false);


        // 绘制直方图
        int hist_w = 512,hist_h = 400;
        int distance = cvRound((double)hist_w / histSize);
        Mat histImage(hist_h, hist_w, CV_8UC3, Scalar(255, 255, 255));
        normalize(b_hist, b_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
        normalize(g_hist, g_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
        normalize(r_hist, r_hist, 0, hist_h, NORM_MINMAX, -1, Mat());
        for (int i = 1; i < histSize; i++)
        {
            //
            line(histImage, Point(distance * (i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),
                Point(distance * (i), hist_h - cvRound(b_hist.at<float>(i))),
                Scalar(255, 0, 0), 2, 8, 0);
            line(histImage, Point(distance * (i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),
                Point(distance * (i), hist_h - cvRound(g_hist.at<float>(i))),
                Scalar(0, 255, 0), 2, 8, 0);
            line(histImage, Point(distance * (i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),
                Point(distance * (i), hist_h - cvRound(r_hist.at<float>(i))),
                Scalar(0, 0, 255), 2, 8, 0);
        }

        //比较直方图相似度
        double similar = compareHist(b_hist, b_hist, CV_COMP_CORREL);
        cout << similar << endl;

        namedWindow("calcHist", WINDOW_AUTOSIZE);
        imshow("calcHist", histImage);
    }

    else
    {
        cout << "您未输入图像" << endl;
        return -1;
    }
    
    waitKey(0);
    return 0;
}

 

 

 

 

标签:distance,Mat,cvRound,src,hist,opencv,直方图
来源: https://blog.csdn.net/qq_44771627/article/details/122033971

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有