文章目录

  • 一、 直方图概述 Overview of histogram
  • 二、直方图的建立 Establishment of histogram
  • 三、直方图的作用 The function of histogram
    • 1)图像匹配
    • 2)判断成像质量
    • 3)二值化阈值
  • 四、编程实现 Programming implementation
  • 总结

一、 直方图概述 Overview of histogram

直方图(Histogram),又称质量分布图,是一种统计报告图,由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据类型,纵轴表示分布情况。
直方图是图像处理中的一个有着广泛应用的工具,直方图本质是概率分布的图形化,同时直方图也可以用来表示向量。

二、直方图的建立 Establishment of histogram

下面以一幅分辨率为8*8、8级灰度的图像来介绍如何建立一幅直方图


以Pi(i = 0、1、2、3…7)表示八级灰度每一级的概率,Ni(i = 0、1、2、3…7)表示88共64个像素点中各级灰度出现的次数,则Pi = Ni/(88),即灰度出现的次数对像素点总数的归一化。
由此绘制出的Pi-灰度的关系图就是灰度直方图。横坐标为灰度值,纵坐标为该灰度值出现的概率。
当然一般是以8位表示一个像素点,灰度一般有256级。

从这张直方图上可以很直观地看到,它的灰度值以0、1、2为主,显然是一张偏暗的图片。

对于图像,不光可以建立灰度直方图,也可以自己设计方法建立任意形式的直方图。如可以对RGB图像三个颜色通道分别建立直方图,得到彩色直方图。也可以针对图像的HSV色彩模型,建立HSC直方图。
两个直方图的比较可以使用欧几里德距离,马氏距离等。Opencv中的compareHist函数提供了四种方法:Correlation、Chi-Square,Intersection,Bhattacharyya距离。
可以想象,如果两个直方图的欧几里德距离为零的话,那么就应该是两个完全一样的直方图。

三、直方图的作用 The function of histogram

1)图像匹配

比较两幅图像的直方图,可以得到两幅图像的相似程度。其本质是对比灰度出现的概率是否相似。
在图像匹配的时候,也可以对其他的特征量建立直方图,来进行匹配。
同样的图像直方图显然相同。反之却不一定成立,这是因为直方图只能记录各级灰度出现的概率,却丢失了空间信息。
如下图就是一个明显的反例:

那么为何要对灰度进行归一化呢,假设我们有一张原图和一张对原图进行放大缩小后的图片,两种图片实际上是同一张图片,只是大小不同,它们的直方图理应是相同的。但是如果不仅归一化,仅仅是以各级灰度出现的次数作为纵坐标,由于放大缩小后的图像与原图像素点存在差异,它呈现出来的纵坐标也是不同的,这就导致了两张相同的图片直方图不同,因此要进行归一化。

2)判断成像质量

下面以几张图片作为示例:



3)二值化阈值

在图像二值化的过程中,我们可以通过分析直方图选择一个适当的阈值,把灰度图像转换为二值化图像,通常的目的是分离前景和背景

以一张256级灰度的细胞的图片为例,下面是它的直方图

可以明显地看到,它的直方图呈现双峰性,它的前景分布集中在一个区域,背景分布集中在另一个区域,这时候我们只要选择直方图中的谷值,就能得到较为理想的二值化图像。

四、编程实现 Programming implementation

通过Opencv编程实现读取一张图片计算并显示RGB三通道直方图。
这里用的Opencv版本是4.40。
当然这里可以用Opencv自带的函数calcHist()函数计算直方图,自己写一个算直方图的函数只是为了能够加深对直方图和OpencvMat类的理解。

#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
#define hist_rgb_width  800
#define hist_rgb_height 400void Calc_histogram(cv::Mat src)
{/*定义直方图矩阵*这里以一个256*3的矩阵存放各个通道各个灰度值的个数*以数组下标标记灰度值,数组内容为该灰度值的个数*/float histogram[256][3] = { 0 };//定义vector作为三个通道的容器std::vector<cv::Mat>   channels;//分离三个通道像素值cv::split(src, channels);cv::Mat B = channels.at(0);cv::Mat G = channels.at(1);cv::Mat R = channels.at(2);//*****遍历*****//获取向量长度int height = src.rows;int width  = src.cols;long int size = height * width;for (int j = 0; j < height; ++j){for (int i = 0; i < width; ++i){++histogram[B.at<uchar>(j, i)][0];++histogram[G.at<uchar>(j, i)][1];++histogram[R.at<uchar>(j, i)][2];}}//*****归一化*****/* 由于直方图归一化以后的纵坐标小于1,需要放大以后显示才直观* 而放大多少倍才能使现有的画布容纳所有放大后的线段* 这里用三个变量记录归一化后最大的值,将最大值放大为画布高度400* 最大值能容纳,其他的值也自然能容纳了*/float BMax = 0;float GMax = 0;float RMax = 0;for (int i = 0; i < 256; ++i){histogram[i][0] = histogram[i][0] / size;histogram[i][1] = histogram[i][1] / size;histogram[i][2] = histogram[i][2] / size;if (histogram[i][0] > BMax)BMax = histogram[i][0];if (histogram[i][1] > GMax)GMax = histogram[i][1];if (histogram[i][2] > RMax)RMax = histogram[i][2];}cv::Mat dispMat(hist_rgb_height, hist_rgb_width, CV_8UC3, Scalar(0, 0, 0));cv::Point pt1, pt2;pt1.y = 400;pt1.x = 0;pt2.x = 0;int Coeficient = 0;//绘制R通道直方图Coeficient = (int)(400 / RMax);for (int i = 0; i < 256; ++i){pt2.y = pt1.y - histogram[i][2] * Coeficient;cv::line(dispMat, pt1, pt2, Scalar(0, 0, 255), 1, 8, 0);pt2.x = ++pt1.x;}//绘制G通道直方图Coeficient = (int)(400 / GMax);for (int i = 0; i < 256; ++i){pt2.y = pt1.y - histogram[i][1] * Coeficient;cv::line(dispMat, pt1, pt2, Scalar(0, 255, 0), 1, 8, 0);pt2.x = ++pt1.x;}//绘制B通道直方图Coeficient = (int)(400 / BMax);for (int i = 0; i < 256; ++i){pt2.y = pt1.y - histogram[i][0] * Coeficient;cv::line(dispMat, pt1, pt2, Scalar(255, 0, 0), 1, 8, 0);pt2.x = ++pt1.x;}imshow("Histogram", dispMat);
}
int main()
{/*读入要计算直方图的图片*注意这里要用“\\”*/cv::Mat src = imread("C:\\Users\\STAR ZHANG\\Pictures\\3.jpg");//调用函数Calc_histogram(src);/*WaitKey(n)是Opencv自带的函数*其中n表示等待按键n毫秒后,关闭显示的窗口*n为0或者WaitKey()(形参缺省)表示一直等待按键*/waitKey(0);return 0;
}

运行结果:
原图:

分离出的RGB三通道直方图:

总结

直方图在数字图像处理中一个非常重要的概念,具有广泛的应用。 以上作为课堂学习和课外练习的总结整理,部分资料出自老师的课件。 我永远热爱hdms lizhu老师!

【Opencv入门】RGB三通道直方图的计算与绘制相关推荐

  1. opencv分离RGB三通道

    注:本文非标准教程,仅是总结个人学习过程,可能存在纰漏,如有错误之处欢迎留言告知,非常感谢 本文用RGB通道来改变图像颜色. #include <iostream> #include &l ...

  2. OpenCV入门(三)快速学会OpenCV2图像处理基础(一)

    OpenCV入门(三)快速学会OpenCV2图像处理基础(一) 作者:Xiou 1.颜色变换cvtColor imgproc的模块名称是由image(图像)和process(处理)两个单词的缩写组合而 ...

  3. 《OpenCV3编程入门》学习笔记9 直方图与匹配(一二) 图像直方图概述直方图的计算与绘制

    第9章 直方图与匹配 9.1 图像直方图(Histogram)概述 1.作用:   在每个兴趣点设置一个有相近特征的直方图所构成的标签,通过标记帧与帧之间显著的边缘.颜色.角度等特征的统计变化,来检测 ...

  4. 彩色图像RGB三通道问题探究

    之前做图像问题研究时经常会提到RGB通道,这次做一个小研究,对最底层的东西深究一二-- 直接上全部代码吧,一点点来: # -*- coding: utf-8 -*- import cv2 img=cv ...

  5. 使用Python,Opencv进行二维直方图的计算及绘制

    使用Python,Opencv进行二维直方图的计算及绘制 1. 效果图 2. 源码 参考 这篇博客将介绍如何使用Python,Opencv进行二维直方图的计算及绘制(分别用Opencv和Numpy计算 ...

  6. OpenCV中直方图的计算和绘制

    OpenCV中直方图的计算和绘制 主要记录一下几个关键的API: cvRound(输入一个浮点数 );//返回一个整型数,取整的方法为四舍五入 split(输入多通道图像,数组或者vector变量. ...

  7. BMP位图转为RGB三通道图

    文章目录 读取BMP位图转为RGB三通道图 注意 相关/参考链接 本人机器开发环境 用到的图像 大小端模式介绍: 完整代码: 结果 读取BMP位图转为RGB三通道图 个人总结,目的是给自己日后参考,或 ...

  8. 提取图片RGB三通道数据+用RGB恢复原始图片

    提取图片的RGB三通道数据+用RGB恢复原始图片 提取图片的RGB三通道数据 用RGB恢复原始图片 功能实现: 提取出一张图片的R.G.B三个通道的值并且将其分别转换为十进制数据存储到R.txt.G. ...

  9. PIL将png的RGBA四通道改为jpg的RGB三通道方法

    将一张png图像使用PIL读入的时候,发现是一个四通道图像,即:RGBA,分别代表Red(红色)Green(绿色)Blue(蓝色)和Alpha的色彩空间.其中Alpha通道一般用做透明度参数,这就是为 ...

最新文章

  1. 远哥谈 使用WebSocket开发在线实时看远程服务器log日志的工具
  2. 一份详尽的IPC$***资料
  3. 快速pow算法c语言_嵌入式必知基础算法(二)
  4. RocketMQ 源码学习笔记 Producer 是怎么将消息发送至 Broker 的?
  5. flex 左右布局_web前端学习:移动端开发常用布局—前端弹性布局总结
  6. SpringBoot配置绑定的两种方式
  7. 大规模部署桌面虚拟化时的一些思考
  8. JAVA里的jsp网页背景_Java-带CSS的JSP不显示背景图像
  9. Matlab画图设置指数坐标
  10. 【PFC】PFC测试指令
  11. 卷积神经网络以LeNet网络为例的手写体识别
  12. mysql查询表升序降序_创建一个按钮,对MYSQL查询进行升序和降序排序
  13. 人肝源间充质样干细胞的肝源性潜能及肝再生效应
  14. 「AR裸眼插画」零基础入门级教程来啦
  15. 火山PC自绘高级表格及超级列表框
  16. 湖南中医药大学成考2022年下学期网络课程学习与考试工作安排
  17. UVa1218完美的服务
  18. urlscan_砍死! 我不喜欢它-URLScan为零步
  19. 请输入一个数字作为秒数,在页面按时间,分钟,秒的格式输出(如输入600,页面显示:0时10分0秒
  20. 勾股数(毕达哥拉斯三元组)

热门文章

  1. Aggressive cows POJ - 2456
  2. linux卸载软件出现依赖,关于ubuntu循环依赖软件的删除
  3. Web基础配置篇(十四): Kafka单机、集群的安装配置及使用
  4. 海外置业房便宜 税受不了
  5. 叶武滨老师时间管理感悟分享5
  6. [案例]华为数据中心专业服务助力襄阳“云谷”战略
  7. 饱和约束下轮式机器人的轨迹跟踪控制算法 (MATLAB实现)
  8. 服务器查看硬盘状态在哪里看,hpacucli查看HP服务器硬盘状态
  9. 女神节,谈美工和美编
  10. Hi3531DV200的IVE中KCF目标跟踪