OpenCV官方教程中文版 —— 直方图的计算,绘制与分析

news2024/9/28 23:26:09

OpenCV官方教程中文版 —— 直方图的计算,绘制与分析

  • 前言
  • 一、原理
    • 1.统计直方图
    • 2. 绘制直方图
    • 3. 使用掩模

前言

使用 OpenCV 或 Numpy 函数计算直方图

使用 Opencv 或者 Matplotlib 函数绘制直方图

将要学习的函数有:cv2.calcHist(),np.histogram()

一、原理

什么是直方图呢?通过直方图你可以对整幅图像的灰度分布有一个整体的了解。直方图的 x 轴是灰度值(0 到 255),y 轴是图片中具有同一个灰度值的点的数目。

直方图其实就是对图像的另一种解释。一下图为例,通过直方图我们可以对图像的对比度,亮度,灰度分布等有一个直观的认识。几乎所有的图像处理软件都提供了直方图分析功能。下图来自Cambridge in Color website,强烈推荐你到这个网站了解更多知识。

在这里插入图片描述
让我们来一起看看这幅图片和它的直方图吧。(要记住,直方图是根据灰度图像绘制的,而不是彩色图像)。直方图的左边区域像是了暗一点的像素数量,右侧显示了亮一点的像素的数量。从这幅图上你可以看到灰暗的区域比两的区域要大,而处于中间部分的像素点很少。

1.统计直方图

现在我们知道什么是直方图了,那怎样获得一副图像的直方图呢?OpenCV 和 Numpy 都有内置函数做这件事。在使用这些函数之前我们有必要想了解一下直方图相关的术语。

BINS:上面的直方图显示了每个灰度值对应的像素数。如果像素值为 0到 255,你就需要 256 个数来显示上面的直方图。但是,如果你不需要知道每一个像素值的像素点数目的,而只希望知道两个像素值之间的像素点数目怎么办呢?举例来说,我们想知道像素值在 0 到 15 之间的像素点的数目,接着是 16 到 31,…,240 到 255。我们只需要 16 个值来绘制直方图。

那到底怎么做呢?你只需要把原来的 256 个值等分成 16 小组,取每组的总和。而这里的每一个小组就被成为 BIN。第一个例子中有 256 个 BIN,第二个例子中有 16 个 BIN。在 OpenCV 的文档中用 histSize 表示 BINS。

DIMS:表示我们收集数据的参数数目。在本例中,我们对收集到的数据只考虑一件事:灰度值。所以这里就是 1。

RANGE:就是要统计的灰度值范围,一般来说为 [0,256],也就是说所有的灰度值

cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])
  1. images: 原图像(图像格式为 uint8 或 float32)。当传入函数时应该用中括号 [] 括起来,例如:[img]。
  2. channels: 同样需要用中括号括起来,它会告诉函数我们要统计那幅图像的直方图。如果输入图像是灰度图,它的值就是 [0];如果是彩色图像的话,传入的参数可以是 [0],[1],[2] 它们分别对应着通道 B,G,R。
  3. mask: 掩模图像。要统计整幅图像的直方图就把它设为 None。但是如果你想统计图像某一部分的直方图的话,你就需要制作一个掩模图像,并使用它。(后边有例子)
  4. histSize:BIN 的数目。也应该用中括号括起来,例如:[256]。
  5. ranges: 像素值范围,通常为 [0,256]

让我们从一副简单图像开始吧。以灰度格式加载一幅图像并统计图像的直方图。

img = cv2.imread('home.jpg',0)
# 别忘了中括号 [img],[0],None,[256],[0,256],只有 mask 没有中括号
hist = cv2.calcHist([img],[0],None,[256],[0,256])

hist 是一个 256x1 的数组,每一个值代表了与次灰度值对应的像素点数目。

使用 Numpy 统计直方图 Numpy 中的函数 np.histogram() 也可以帮我们统计直方图。你也可以尝试一下下面的代码:

#img.ravel() 将图像转成一维数组,这里没有中括号。
hist,bins = np.histogram(img.ravel(),256,[0,256])

hist 与上面计算的一样。但是这里的 bins 是 256,因为 Numpy 计算bins 的方式为:0-0.99,1-1.99,2-2.99 等。所以最后一个范围是 255-255.99。为了表示它,所以在 bins 的结尾加上了 256。但是我们不需要 256,到 255就够了。

其他:Numpy还有一个函数 np.bincount(),它的运行速度是np.histgram 的十倍。所以对于一维直方图,我们最好使用这个函数。使用 np.bincount 时别忘了设置 minlength=256。 例如,hist=np.bincount(img.ravel(),minlength=256)

注意:OpenCV 的函数要比 np.histgram() 快 40 倍。所以坚持使用OpenCV 函数。

2. 绘制直方图

有两种方法来绘制直方图:

  1. Short Way(简单方法):使用 Matplotlib 中的绘图函数。
  2. Long Way(复杂方法):使用 OpenCV 绘图函数

使用 Matplotlib Matplotlib 中有直方图绘制函数:matplotlib.pyplot.hist()它可以直接统计并绘制直方图。

# -*- coding: utf-8 -*-
import cv2
from matplotlib import pyplot as plt
import numpy as np
A = cv2.imread('apple.png', 0)
plt.figure()
plt.subplot(1, 2, 1)
plt.imshow(A, cmap='gray', interpolation='bicubic')  # expect true color
plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
plt.subplot(1, 2, 2)
plt.hist(A.ravel(), 256, [0, 256])
plt.show()

你会得到下面这样一幅图:
在这里插入图片描述
或者你可以只使用 matplotlib 的绘图功能,这在同时绘制多通道(BGR)的直方图,很有用。但是你首先要告诉绘图函数你的直方图数据在哪里。运行一下下面的代码:

img = cv2.imread('apple.png')
color = ('b', 'g', 'r')
# 对一个列表或数组既要遍历索引又要遍历元素时
# 使用内置 enumerrate 函数会有更加直接,优美的做法
# enumerate 会将数组或列表组成一个索引序列。
# 使我们再获取索引和索引内容的时候更加方便
for i, col in enumerate(color):
    histr = cv2.calcHist([img], [i], None, [256], [0, 256])
    plt.plot(histr, color=col)
    plt.xlim([0, 256])
plt.show()

在这里插入图片描述

3. 使用掩模

要统计图像某个局部区域的直方图只需要构建一副掩模图像。将要统计的部分设置成白色,其余部分为黑色,就构成了一副掩模图像。然后把这个掩模图像传给函数就可以了。

img = cv2.imread('home.jpg',0)
# create a mask
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:300, 100:400] = 255
masked_img = cv2.bitwise_and(img,img,mask = mask)
# Calculate histogram with mask and without mask
# Check third argument for mask
hist_full = cv2.calcHist([img],[0],None,[256],[0,256])
hist_mask = cv2.calcHist([img],[0],mask,[256],[0,256])
plt.subplot(221), plt.imshow(img, 'gray')
plt.subplot(222), plt.imshow(mask,'gray')
plt.subplot(223), plt.imshow(masked_img, 'gray')
plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask)
plt.xlim([0,256])
plt.show()

结果如下,其中蓝线是整幅图像的直方图,绿线是进行掩模之后的直方图。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[100天算法】-不同路径(day 37)

题目描述 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。问总共有多少条不同的路径?例如…

MATLAB | 两种上色方式的旭日图绘制

嘿,这次真的是好久不见了,好不容易才有点空写点文章,这段时间忙到后台回复都有点来不及看,很抱歉有一部分后台留言刚看到就已经超过时限没法回复了,不过根据大家的留言,需求主要集中在希望出一期旭日图的教…

12、Python -- if 分支 的讲解和使用

目录 程序结构顺序结构分支结构分支结构注意点不要忘记冒号 if条件的类型if条件的逻辑错误if表达式pass语句 程序流程 分支结构 分支结构的注意点 if条件的类型 if语句的逻辑错误 if表达式 程序结构 Python同样提供了现代编程语言都支持的三种流程 顺序结构 分支结构 循环结构…

CPU核检测

import psutil num_cpus psutil.cpu_count(logicalFalse) print(num_cpus) num_cpus psutil.cpu_count(logicalTrue) print(num_cpus)结果如下 可以看到这个结果是不同的

fiddler导出录制脚本并导出jmter脚本文件

1、fiddler导出录制脚本 可以通过save保存录制的脚本: 也可以选中这些链接,点击右键-->save-->select sessions -->选择要导入的文件 2、导入录制的脚本 再fiddler-->file--->load ARCHIVERS--->选择刚导出的.saz文件,正…

01-初识VUE3

01.初识VUE3 1.创建VUE3项目 1).使用 vue-cli 创建 ## 查看vue/cli版本,确保vue/cli版本在4.5.0以上 vue --version ## 安装或者升级你的vue/cli npm install -g vue/cli ## 创建 vue create vue_test ## 启动 cd vue_test npm run serve2).使用 vite 创建 ## 创…

吃豆人C语言开发—Day2 需求分析 流程图 原型图

目录 需求分析 流程图 原型图 主菜单: 设置界面: 地图选择: 游戏界面: 收集完成提示: 游戏胜利界面: 游戏失败界面 死亡提示: 这个项目是我和朋友们一起开发的,在此声明一下…

【C#】委托与事件

目录 一、委托 1.什么是委托 2.委托类型的声明与初始化 3.委托类型引用方法的调用 4.使用委托类型作为方法的参数 5.Action委托 6.Func委托 7.通用类型冒泡排序 8.多播委托 二、Lambda表达式 1.匿名方法 2.Lambda表达式表示匿名方法 三、事件 1.什么是事件 2.事件…

Django viewsets 视图集与 router 路由实现评论接口开发

正常来说遵循restful风格编写接口,定义一个类包含了 get post delete put 四种请求方式,这四种请求方式是不能重复的 例如:获取单条记录和多条记录使用的方式都是get,如果两个都要实现的话那么得定义两个类,因为在同一个类中不能有…

【vue3 】 创建项目vscode 提示无法找到模块

使用命令创建 vue3 创建新应用 npm create vuelatest会看到一些可选功能的询问? √ 请输入项目名称: … vue-project √ 是否使用 TypeScript 语法? … 否 / 是 √ 是否启用 JSX 支持? … 否 / 是 √ 是否引入 Vue Router 进行单…

useReducer的使用以及与useState、useImmerReducer的对比使用

前言 对于拥有许多状态更新逻辑的组件来说,过于分散的事件处理程序可能会影响代码的可读性。这种情况,可以将组件的所有状态更新逻辑整合到一个外部函数中,这个函数就是reducer。 使用 useReducer(reducer, initialArg, init?) 参数 redu…

电力通信与泛在电力物联网技术的应用与发展-安科瑞黄安南

摘要:随着我国社会经济的快速发展,我国科技实力得到了非常大的提升,当前互联网通信技术在社会中得到了广泛的应用。随着电力通信技术的快速发展与更新,泛在电力物联网建设成为电力通讯发展的重要方向。本文已泛在电力物联网系统为…

化工园区数字孪生可视化管控平台,赋予园区安全环保智慧发展

化工行业作为国民经济的支柱和工业发展的引擎,对安全生产、环保节能、应急管控有着很高的要求。目前国内外化工园区面临安全和环保两大压力。为有效解决这两大难题,巨蟹数科综合运用物联网、数字孪生等新一代信息技术,建设了数字孪生园区智慧…

Docker下安装MSSQL并使用Navicat远程连接(备忘录)

Docker下安装MSSQL并使用Navicat远程连接 一. Docker下安装MSSQL备忘录一、安装SQL Server1、从 Microsoft 容器注册表中请求 SQL Server 2022 (16.x) Linux 容器映像:注意:2、运行这个cu5的版本下表对前一个 docker run 示例中的参数进行了说明:3、看这个MSSQL运行没有?用…

JAVA基础——编译器报告的错误信息总结

1. Invalid character(无效字符) 中英文符号错误 2. 数组的常见异常 数组越界异常ArrayIndexOutOfBoundsException: 在使用索引访问数组的元素时超出了数组的索引范围0~length-1。 空指针异常NullPointerException: 在使用变量引用一个数…

CSS - 常用属性和布局方式

目录 前言 一、常用属性 1.1、字体相关 1.2、文本相关 1.3、背景相关 1.3.1、背景颜色 1.3.2、背景图片 1.4、圆角边框 二、常用布局相关 2.1、display 2.2、盒子模型 2.2.1、基本概念 2.2.2、border 边框 2.2.3、padding 内边距 2.2.4、margin 外边距 2.3、弹…

【Android】MQTT

目录 MQTT 协议简介应用场景优点缺点 部署服务端下载安装包启动服务器 搭建客户端下载SDK添加依赖配置MQTT服务和权限建立连接订阅主题发布消息取消订阅断开连接 MQTT客户端工具最终效果实现传感器数据采集与监测功能思路 MQTT 协议 简介 MQTT(Message Queuing Te…

【目标跟踪】多目标跟踪测距

文章目录 前言python代码(带注释)main.pysort.pykalman.pydistance.py 结语 前言 先放效果图。目标框内左上角,显示的是目标距离相机的纵向距离。目标横向距离、速度已求出,没在图片展示。这里不仅仅实现对目标检测框的跟踪&#…

【Django restframework】django跨域问题,解决PUT/PATCH/DELETE用ajax请求无法提交数据的问题

【Django restframework】django跨域问题,解决PUT/PATCH/DELETE用ajax请求无法提交数据的问题 1 问题描述: 我用restframework(ModelSerializerGenericApiView)开发了一组符合RestFul接口标准的接口,这意味着它将支持客户端发来的GET、POST、…

矢量图形编辑软件 illustrator 2023 mac 中文软件特点

illustrator 2023 mac是一款矢量图形编辑软件,用于创建和编辑排版、图标、标志、插图和其他类型的矢量图形。 illustrator 2023 mac软件特点 矢量图形:illustrator创建的图形是矢量图形,可以无限放大而不失真,这与像素图形编辑软…