opencv直方图绘制详解

文章目录

  • 1.直方图的定义、意义和特征
    • 1. 定义
    • 2. 意义
    • 3. 特征
    • 4. 方法和参数
  • 2.灰度直方图
  • 3.mask详解
  • 4.彩色直方图

1.直方图的定义、意义和特征

1. 定义

在统计学中,直方图是一种对数据分布情况的图形表示,是一种二维统计图表,
他的两个坐标分别是统计样本(图像、视频帧)和样本的某种属性(亮度,像素值,梯度,方向,色彩等等任何特征)
在这里插入图片描述

在这里插入图片描述

2. 意义

(1)直方图是图像中像素强度分布的图形表达方式。
(2)直方图统计了每一个强度值所具有的像素个数。

3. 特征

(1)直方图不再表征任何的图像纹理信息,而是对图像像素的统计。
(2)由于同一物体无论是旋转还是平移在图像中都具有相同的灰度值,因此直方图具有平移不变性、放缩不变性等优点。

4. 方法和参数

cv2.calcHist(images, channels, mask, histSize, ranges[hist[, accumulate]])
(1)images : 整型类型(uint8和float32)的原图(list或tuple形式的输入)。
(2)channels : 通道的索引,例如:[0]代表灰度图片,[0],[1],[2]代表多通道,list或tuple形式的输入。

(3)mask : 计算图片指定区域的直方图。如果mask为none,那么计算整张图。
(4)histSize( bins ) : 每个色调值(范围: 0 ~ 255)对应的像素数量/频率。[这256个值中的每一个都被称为bin,它的取值有8,16,32,64,128,256。在OpenCV中,用histSize表示bins。],list或tuple形式的输入
(5)range : 强度值的范围,[0, 256]。

cv2.calcHist()函数的返回值
对于hist = cv2.calcHist([img],[0],None,[256],[0,256])中,hist是一个256*1的矩阵,每一个值代表了每个灰度值对应的像素点数目
print(type(hist))
<class ‘numpy.ndarray’>

输出的结果表示这是一个多维数组

print(hist)
[[1.000e+00]
[0.000e+00]
[2.000e+00]
[0.000e+00]

[2.010e+02]
[2.180e+02]
[2.160e+02]
[2.660e+02]
[3.350e+02]
[3.110e+02]
[4.670e+02]]

经计算,共有256个值,即可以输出hist[0]到hist[255]。整个hist[i]则表示灰度值
在这里插入图片描述

print(hist[175],hist[255])
[3181.] [467.]

通过直方图可看出输出的结果就是每一个灰度值对应的像素数目,横坐标是bins区间值,纵坐标是每个bins的像素数目

2.灰度直方图

# 1 导入库
import cv2
import matplotlib.pyplot as plt
import numpy as np

# 2 方法:显示图片
def show_image(image, title, pos):
    #  顺序转换:BGR TO RGB
    #height和width是不变的,channel倒序输出
    image_RGB = image[:, :, ::-1] # shape : (height, width, channel)
    # 显示标题
    plt.title(title)
    plt.subplot(2, 3, pos) # 定位
    plt.imshow(image_RGB)

# 3 方法:显示图片的灰度直方图
def show_histogram(hist, title, pos, color):
    # 显示标题
    plt.title(title)
    plt.subplot(2, 3, pos) # 定位图片
    plt.xlabel("Bins") # 横轴信息
    plt.ylabel("Pixels") # 纵轴信息
    plt.xlim([0, 256]) # 范围
    plt.plot(hist, color=color) # 绘制直方图


# 4 主函数 main()
def main():
    # 5 创建画布
    plt.figure(figsize=(15, 6)) # 画布大小
    #设置标题,给画布添加标题
    plt.suptitle("Gray Image Histogram", fontsize=14, fontweight="bold") # 设置标题形式

    # 6 加载图片
    img = cv2.imread("children.jpg")

    # 7 灰度转换
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 8 计算灰度图的直方图
    hist_img = cv2.calcHist([img_gray], [0], None, [256], [0, 256])

    # 9 展示灰度直方图
    # 灰度图转换成BGR格式图片
    img_BGR = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2BGR)
    show_image(img_BGR, "BGR image", 1)
    show_histogram(hist_img, "gray image histogram", 4, "m")

    plt.show()

if __name__ == '__main__':
    main()

运行结果
在这里插入图片描述

设置画布标题函数介绍
matplotlib.pyplot.suptitle(t,x=0.5,y=0.98,horizontalalignment=‘center’,verticalalignment=‘top’, fontsize=‘large’,
fontweight=‘normal’, **kwargs)

参数 含义
在这里插入图片描述

灰度直方图进阶
对图像像素添加或减少展示

代码:

# 1 导入库
import cv2
import matplotlib.pyplot as plt
import numpy as np

# 2 方法:显示图片
def show_image(image, title, pos):
    #  顺序转换:BGR TO RGB
    image_RGB = image[:, :, ::-1] # shape : (height, width, channel)
    # 显示标题
    plt.title(title)
    plt.subplot(2, 3, pos) # 定位
    plt.imshow(image_RGB)

# 3 方法:显示图片的灰度直方图
def show_histogram(hist, title, pos, color):
    # 显示标题
    plt.title(title)
    plt.subplot(2, 3, pos) # 定位图片
    plt.xlabel("Bins") # 横轴信息
    plt.ylabel("Pixels") # 纵轴信息
    plt.xlim([0, 256]) # 范围
    plt.plot(hist, color=color) # 绘制直方图


# 4 主函数 main()
def main():
    # 5 创建画布
    plt.figure(figsize=(15, 6)) # 画布大小
    plt.suptitle("Gray Image Histogram", fontsize=14, fontweight="bold") # 设置标题形式

    # 6 加载图片
    img = cv2.imread("children.jpg")

    # 7 灰度转换
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 8 计算灰度图的直方图
    hist_img = cv2.calcHist([img_gray], [0], None, [256], [0, 256])

    # 9 展示灰度直方图
    # 灰度图转换成BGR格式图片
    img_BGR = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2BGR)
    show_image(img_BGR, "BGR image", 1)
    show_histogram(hist_img, "gray image histogram", 4, "m")

    # 10 对图片中的每个像素值增加50个像素
    M = np.ones(img_gray.shape, np.uint8) * 50 # 构建矩阵

    #使用cv2.add()方法进行相加减
    added_img = cv2.add(img_gray, M)
    add_img_hist = cv2.calcHist([added_img], [0], None, [256], [0, 256]) # 计算直方图
    added_img_BGR = cv2.cvtColor(added_img, cv2.COLOR_GRAY2BGR)
    show_image(added_img_BGR, "added image", 2)
    show_histogram(add_img_hist, "added image hist", 5, "m")

    # 11 对图片中的每个像素值减去50个像素
    subtract_img = cv2.subtract(img_gray, M)
    subtract_img_hist = cv2.calcHist([subtract_img], [0], None, [256], [0, 256]) # 计算直方图
    subtract_img_BGR = cv2.cvtColor(subtract_img, cv2.COLOR_GRAY2BGR)
    show_image(subtract_img_BGR, "subtracted image", 3)
    show_histogram(subtract_img_hist, "subtracted image hist", 6, "m")

    plt.show()

if __name__ == '__main__':
    main()

可以看到增加了50像素的图片变亮,减少了50个像素的变暗
在这里插入图片描述

3.mask详解

mask : 提取感兴趣区域。
如下图,设置了mask区域被显示出来,其他区域被覆盖
在这里插入图片描述
在这里插入图片描述

实战

# 1 导入库
import cv2
import matplotlib.pyplot as plt
import numpy as np

# 2 方法:显示图片
def show_image(image, title, pos):
    img_RGB = image[:, :, ::-1] # BGR to RGB
    plt.title(title)
    plt.subplot(2, 2, pos)
    plt.imshow(img_RGB)

# 3 方法:显示灰度直方图
def show_histogram(hist, title, pos, color):
    plt.subplot(2, 2, pos)
    plt.title(title)
    plt.xlim([0, 256])
    plt.plot(hist, color=color)

# 4 主函数
def main():
    # 5 创建画布
    plt.figure(figsize=(12, 7))
    plt.suptitle("Gray Image and Histogram with mask", fontsize=14, fontweight="bold")

    # 6 读取图片并灰度转换,计算直方图,显示
    img_gray = cv2.imread("children.jpg", 0) # 读取并进行灰度转换
    img_gray_hist = cv2.calcHist([img_gray], [0], None, [256], [0, 256]) # 计算直方图
    # 灰度图转换成BGR格式图片
    img_BGR = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2BGR)
    show_image(img_BGR, "BGR image", 1)
    # show_image(img_gray, "image gray", 1)
    show_histogram(img_gray_hist, "image gray histogram", 2, "m")

    # 7 创建mask,计算位图,直方图
    mask = np.zeros(img_gray.shape[:2], np.uint8)
    #截取mask区域
    mask[130:500, 400:1400] = 255 # 获取mask,并赋予颜色
    img_mask_hist = cv2.calcHist([img_gray], [0], mask, [256], [0, 256]) # 计算mask的直方图,这里的mask直接写上即可,不要写成mask=mask

    # 8 通过位运算(与预算)计算带有mask的灰度图片
    mask_img = cv2.bitwise_and(img_gray, img_gray, mask = mask)   #这里的mask一定要写成mask=mask,否则无法实现mask功能
    #将灰色图片转换成BGR格式图片
    mask_BGR =  cv2.cvtColor(mask_img, cv2.COLOR_GRAY2BGR)
    # 9 显示带有mask的图片和直方图
    show_image(mask_BGR, "gray image with mask", 3)
    show_histogram(img_mask_hist, "histogram with masked gray image", 4, "m")

    plt.show()
if __name__ == '__main__':
    main()

可以看到mask显示出来
在这里插入图片描述

4.彩色直方图

记住三点:

(1)直方图是图像中像素强度分布。

(2)直方图统计了每一个强度值所具有的像素个数。
(3)cv2.calcHist(images, channels, mask, histSize, ranges)

代码

# 1 导入库
import cv2
import matplotlib.pyplot as plt
import numpy as np

# 2 方法:显示图片
def show_image(image, title, pos):
    plt.subplot(3, 2, pos)
    plt.title(title)
    image_RGB = image[:, :, ::-1] # BGR to RGB
    plt.imshow(image_RGB)
    #关闭坐标轴
    plt.axis("off")

# 3 方法:显示彩色直方图 b, g, r
def show_histogram(hist, title, pos, color):
    plt.subplot(3, 2, pos)
    plt.title(title)
    plt.xlim([0, 256])
    #灰度只有一种颜色,彩色直方图是有三个通道的,RGB都要绘制出来,需要用循环来分别显示
    for h, c in zip(hist, color): # color: ('b', 'g', 'r')
        plt.plot(h, color=c)


# 4 方法:计算直方图,每个通道都要计算
def calc_color_hist(image):
    # b, g, r
    hist = []
    hist.append( cv2.calcHist([image], [0], None, [256], [0, 256]))
    hist.append( cv2.calcHist([image], [1], None, [256], [0, 256]))
    hist.append( cv2.calcHist([image], [2], None, [256], [0, 256]))
    return hist

# 5 主函数
def main():
    # 5.1 创建画布
    plt.figure(figsize=(12, 8))
    plt.suptitle("Color Histogram", fontsize=14, fontweight="bold")

    # 5.2 读取原图片
    img = cv2.imread("children.jpg")

    # 5.3 计算直方图
    img_hist = calc_color_hist(img)

    # 5.4 显示图片和直方图
    show_image(img, "RGB Image", 1)
    #彩色的,传颜色,必须传进去三个通道
    show_histogram(img_hist, "RGB Image Hist", 2, ('b', 'g', 'r'))

   
    # 5.5 原始图片中的每个像素增加50个像素值
    M = np.ones(img.shape, dtype="uint8") * 50

    added_image = cv2.add(img, M) # 像素一一对应相加
    added_image_hist = calc_color_hist(added_image)
    show_image(added_image, 'added image', 3)
    show_histogram(added_image_hist, 'added image hist', 4, ('b', 'g', 'r'))


   
    # 5.6 原始图片中的每个像素减去50个像素值
    subtracted_image = cv2.subtract(img, M)
    subtracted_image_hist = calc_color_hist(subtracted_image)
    show_image(subtracted_image, 'subtracted image', 5)
    show_histogram(subtracted_image_hist, 'subtracted image hist', 6, ('b', 'g', 'r'))

    plt.show()
if __name__ == '__main__':
    main()

可见,绘制出了原始图片,加强像素,减小像素后的图片和彩色直方图
在这里插入图片描述

注意:彩色直方图与灰度直方图绘制基本相同,最大区别在于,彩色直方图绘制需要将三个通道色彩全部绘制出来

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/406064.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTML+CSS:动态搜索框

效果演示 这段代码实现了一个简单的搜索栏效果。页面背景为从天蓝色到深蓝色的渐变色&#xff0c;搜索栏包括一个圆形背景的搜索图标和一个输入框。当用户点击搜索图标时&#xff0c;输入框会从搜索图标的位置滑出&#xff0c;显示一个输入框和一个清除按钮。用户可以在输入框中…

MySQL数据库基础(十三):关系型数据库三范式介绍

文章目录 关系型数据库三范式介绍 一、什么是三范式 二、数据冗余 三、范式的划分 四、一范式 五、二范式 六、三范式 七、总结 关系型数据库三范式介绍 一、什么是三范式 设计关系数据库时&#xff0c;遵从不同的规范要求&#xff0c;设计出合理的关系型数据库&…

JavaSec 之 XXE 简单了解

文章目录 XMLReaderSAXReaderSAXBuilderDocumentBuilderUnmarshaller**SAXParserFactory**XMLReaderFactoryDigester总结 XMLReader public String XMLReader(RequestBody String content) {try {XMLReader xmlReader XMLReaderFactory.createXMLReader();// 修复&#xff1a…

ELK介绍以及搭建

基础环境 hostnamectl set-hostname els01 hostnamectl set-hostname els02 hostnamectl set-hostname els03 hostnamectl set-hostname kbased -i s/SELINUXenforcing/SELINUXdisabled/ /etc/selinux/config systemctl stop firewalld & systemctl disable firewalld# 安…

LVS-NAT之VMNET环境搭建

目录 搭建拓扑图 搭建规划 VMNET0 搭建 VMNET2 搭建 LVS端增加网卡 搭建拓扑图: 搭建规划: CLIENT(servera): VMNET0 LVS(serverb): VMNET0 VMNET2 WEB1(serverd): VMNET2 WEB2(servere): VMNET2 VMNE…

R的seurat和python的scanpy对比学习

现在的单细胞分析&#xff0c;往往避免不了scanpy的使用&#xff0c;我们可以通过对比seurat来学习scanpy 今天的格式怎么都改不了。。。手机阅读有点费劲&#xff0c;&#xff0c;推荐电脑阅读。 单细胞数据分析概览 单细胞分析&#xff0c;总流程 python教程 seurat教程 se…

算法题目中图和树的存储

邻接表的方式存储图和树 这就是邻接表&#xff0c;就是将每个结点的孩子结点用链表表示出来&#xff0c;再将所有结点以数组形式连起来。 存储树和图我们需要三个数组&#xff0c;h[N], e[N], ne[N],分别表示邻接表&#xff0c;结点值&#xff0c;结点的next值&#xff0c;h[i…

C/C++内存管理学习【new】

文章目录 一、C/C内存分布二、C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free三、C内存管理方式3.1 new/delete操作内置类型3.2 new和delete操作自定义类型四、operator new与operator delete函数五、new和delete的实现原理5.1 内置类型 六、定位new表达式(pl…

Codeforces Round 494 (Div. 3)

目录 A. Polycarps Pockets B. Binary String Constructing C. Intense Heat D. Coins and Queries E. Tree Constructing F. Abbreviation A. Polycarps Pockets 记录数量可以直接开一个桶即可然后求最大值 void solve(){cin>>n;vector<int> ton(105);int …

Go 中如何高效遍历目录?探索几种方法

嗨&#xff0c;大家好&#xff01;我是波罗学。本文是系列文章 Go 技巧第十八篇&#xff0c;系列文章查看&#xff1a;Go 语言技巧。 目录遍历是一个很常见的操作&#xff0c;它的使用场景有如文件目录查看&#xff08;最典型的应用如 ls 命令&#xff09;、文件系统清理、日志…

FastJson反序列化漏洞(Fastjson1.2.47)

一、FastJson Fastjson 是一个阿里巴巴公司开源的 Java 语言编写的高性能功能完善的 JSON 库。可以将Java 对象转换为 JSON 格式(序列化)&#xff0c;当然它也可以将 JSON 字符串转换为 Java 对象&#xff08;反序列化&#xff09; 它采用一种“假定有序快速匹配”的算法&…

Sora-OpenAI 的 Text-to-Video 模型:制作逼真的 60s 视频片段

OpenAI 推出的人工智能功能曾经只存在于科幻小说中。 2022年&#xff0c;Openai 发布了 ChatGPT&#xff0c;展示了先进的语言模型如何实现自然对话。 随后&#xff0c;DALL-E 问世&#xff0c;它利用文字提示生成令人惊叹的合成图像。 现在&#xff0c;他们又推出了 Text-t…

Facebook的数字社交使命:连接世界的下一步

在数字化时代&#xff0c;社交媒体已成为人们生活的重要组成部分&#xff0c;而Facebook作为其中最具影响力的平台之一&#xff0c;一直以来都在努力履行着自己的使命——连接世界。然而&#xff0c;随着时代的变迁和技术的发展&#xff0c;Facebook正在不断探索着连接世界的下…

嵌入式按键处理驱动(easy_button)

简介 在嵌入式裸机开发中&#xff0c;经常有按键的管理需求&#xff0c;GitHub上已经有蛮多成熟的按键驱动了&#xff0c;但是由于这样那样的问题&#xff0c;最终还是自己实现了一套。本项目地址&#xff1a;bobwenstudy/easy_button (github.com)。 项目开发过程中参考了如…

【数据分享】中国首套1公里高分辨率大气湿度指数数据集(6个指标\免费获取)

湿度数据是气象学和许多其他领域中至关重要的数据&#xff0c;可用于气象预测与气候研究。之前我们分享过Excel格式和GIS矢量格式&#xff08;均可查看之前的文章获悉详情&#xff09;的2000-2020年全国各城市逐日、逐月和逐年的湿度数据。 本次我们给大家带来的是中国首套1公…

ElasticSearch 环境安装

ElasticSearch 安装 下载地址&#xff1a;https://www.elastic.co/downloads/past-releases#elasticsearch elasticsearch 使用的jdk说明&#xff1a; elasticsearch自带有jdk&#xff0c;如果需要使用自带的jdk则需要自定义环境变量ES_JAVA_HOME到es下的jdk目录 D:\fenbushi\e…

Linux之用户跟用户组

目录 一、简介 1.1、用户 1.2用户组 1.3UID和GID 1.4用户账户分类 二、用户 2.1、创建用户&#xff1a;useradd 2.2、删除用户&#xff1a;userdel 2.3 、修改用户 usermod 2.4、用户口令的管理:passwd 2.5、切换用户 三、用户组 3.1、增加一个用户组:groupadd 3.…

洛谷 【算法1-6】二分查找与二分答案

【算法1-6】二分查找与二分答案 - 题单 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 鄙人不才&#xff0c;刷洛谷&#xff0c;迎蓝桥&#xff0c;【算法1-6】二分查找与二分答案 已刷&#xff0c;现将 AC 代码献上&#xff0c;望有助于各位 P2249 【深基13.例1】查找 - 洛谷…

开发分销商城小程序助力您的业务快速增长

一、什么是分销商城小程序&#xff1f; 分销商城小程序是一种基于微信平台开发的小程序&#xff0c;可以帮助商家快速建立自己的分销体系&#xff0c;实现商品的快速销售。 二、分销商城小程序的优势&#xff1a; 低成本&#xff1a;开发成本低&#xff0c;无需投入大量资金…

架构设计:数据库扩展

引言 随着业务的发展和用户规模的增长&#xff0c;数据库往往会面临着存储容量不足、性能瓶颈等问题。为了解决这些问题&#xff0c;数据库扩展成为了一种常见的解决方案。在数据库扩展的实践中&#xff0c;有许多不同的策略和技术可供选择&#xff0c;其中包括水平拆分、垂直…