OpenCV之直方图的计算与绘制

69 篇文章 14 订阅
53 篇文章 15 订阅

图像直方图

直方图广泛的应用于很多计算机视觉应用中,通过标记帧与帧之间显著的边缘和颜色的通解变化,来检测视频场景中的变化。在每个兴趣点设置一个有相近特征的直方图所构成“标签”,用以确定图像中的兴趣点。边缘、色彩、角度等直方图构成了可以被传递给目标识别分类器的通用特征类型。色彩和边缘的直方图序列还可以用来识别网络视频是否被复制。

简单来说,直方图就是对数据进行统计的一种方法,并且将统计直组织到一系列事先定义好的bin中。bin为直方图中经常到的概念,可以理解为“直条”或“组距”,其数值是从数据中计算出的特征统计量,这些数据可以是梯度、方向、色彩或者其它数据特征

直方图获得的是数据分布的统计图,且直方图的维数要低于原始数据

在统计学中,直方图是一种对数据分布情况的图形表示,是一种二维统计图表,它的两个坐标分别是统计样本和该样本对应的某个属性的度量。

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

直方图的意义如下:

  • 直方图是图像中像素强度分布的图像表达式。
  • 它统计了每一个强度值所具有的像素个数。
  • 直方图是对数据的统计集合,并将结果分布于一系列预定义的bins中,这里的数据不仅可以是灰度图,也可以是任何能有效描述图像的特征。

假设有一张灰度图,像素饿范围是0-255,可以将这个范围分割成子区域(也就是前面提到的bins),如:

然后再统计每一个bins中的像素数目,用这种方法便可以得到图像直方图,其中:

  • dims:需要统计的特征的数目。
  • bins:所分的区段的数目,比如16, 64, 255等。
  • range:特征空间的取值范围,RGB的则是[0, 255]。

calcHist()函数

calcHist()函数用于计算一个或多个阵列的直方图,函数原型:

void(const Mat* images, int nimages, const int* channels, InputArray mask,outputArray hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accimulate=false)
  • 第一个参数:输入放入数组或数组集,他们需要有相同的深度。
  • 第二个参数:输入数组的个数,也就是第一个参数重存放了多少张图像。
  • 第三个参数:需要统计的通道索引。第一个数组通道从0到images[0].channels()-1,而第二个数组通道从images[0].channels()计算到image[0].channels()+imahes[1].channels()+1
  • 第四个参数:可选的操作掩码,如果此掩码不为空,那么它必须是8位,并且与images[i]有相同的大小,这里的非零掩码元素用于标记出统计直方图的数组元素数据。
  • 第五个参数:输出的目标直方图,一个二维数组。
  • 第六个参数:需要计算的直方图的维度,必须是正数。
  • 第七个参数:存放每个维度的直方图尺寸的数组。
  • 第八个参数:表示每一个维度数组的每一维的边界阵列,可以理解为每一维数值的取值范围。
  • 第九个参数:bool类型的uniform,指示直方图是否均匀的标识符,默认值是true。
  • 第十个参数:累积标识符,默认false,若为true,直方图在配置阶段不会被清零。此功能主要是允许从多个阵列中计算单个直方图,或用于在特定的时间更新直方图。

找寻最值:minMaxLoc()函数

minMaxLoc()函数的作用是找到全局最小值和最大值,函数原型:

void minMaxLoc(InputArray src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, inputArray mask=noArray())javascript:void(0)
  • 第一个参数:输入的单通道阵列
  • 第二个参数:doubel*类型的minVal,返回最小值的指针,若无需返回,则为NULL。
  • 第三个参数:doubel*类型的maxVal,返回最大值的指针,若无需返回,则为NULL。
  • 第四个参数:Point*类型的minLoc,返回最小位置的指针,若无需返回,则为NULL。
  • 第五个参数:Point*类型的maxLoc,返回最大位置的指针,若无需返回,则为NULL。
  • 第六个参数:InputArray类型的马赛克,用于选择子阵列的可选掩膜。

代码示例:

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

int main() {
//    读入图像
    Mat srcImage = imread("/Users/dwz/Desktop/cpp/1.jpg", 0);

//    定义变量
    MatND  dstHist;
    int dims = 1;
    float hranges[] = {0, 255};
    const float *ranges[] = {hranges};
    int size = 256;
    int channels = 0;

//    计算直方图
    calcHist(&srcImage, 1, &channels, Mat(), dstHist, dims, &size, ranges);
    int scale = 1;
    Mat dstImage(size * scale, size, CV_8U, Scalar(0));
    double minValue = 0, maxValue = 0;
    minMaxLoc(dstHist, &minValue, &maxValue,0, 0);

//    画图
    int hpt = saturate_cast<int>(0.9 * size);
    for (int i=0; i<256; i++)
    {
        float binValue = dstHist.at<float>(i);
        int realValue = saturate_cast<int>(binValue * hpt / maxValue);
        rectangle(dstImage, Point(i*scale, size-1), Point((i+1)*scale-1, size-realValue), Scalar(255));

    }
    imwrite("hist.jpg", dstImage);

    return 0;
}

输入:

输出:

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值