当前位置: 首页 > news >正文

直方图及其应用

直方图定义

直方图是一种描述数据的分布

通过将连续变量划分成一系列区间,统计区间频率,并用来表示,以表征其统计特征

在图像处理中,直方图可以用来表示图像中像素值的分布状况,描述不同灰度级的像素在图像中的占比

直方图应用

1. 图像增强。通过调整像素值,让图像的像素复合某种统计特性,达到增强图像的目的

2. 图像分割。利用直方图来将图像划分为多个区域,从而进行目标分割

3. 像素的统计特性,可以作为图像的一种特征,用于对图像内容进行分类、检索、压缩

https://blog.csdn.net/yishuihanq/article/details/120220374

OpenCV画直方图

  1. cv2.calcHist(images,channels,mask,histSize,ranges)

关于`cv2.calcHist`函数的说明

hist = cv2.calcHist(images, channels, mask, histSize, ranges, accumulate)

- images: 源图像

- channels:参与计算直方图的通道

- mask:一个可选的掩膜,它与源图像具有相同的尺寸,用于指定计算直方图的区域。例如,可以通过指定一个矩形来计算图像的某个区域的直方图。

- histSize:表示要计算的直方图的大小以方括号形式传入。如果输入图像是灰度图像,则为灰度级别数;如果是彩色图像,则可以对每个通道指定不同的大小,例如 [256, 256, 256] 表示每个通道的直方图大小为 256。

- ranges:表示像素值的范围,以方括号形式传入。如果输入图像是灰度图像,则范围应该是 [0, 256];如果是彩色图像,则可以为每个通道指定不同的范围,例如 [0, 256, 0, 256, 0, 256] 表示每个通道的范围分别为 [0, 256]。

- accmulate:一个可选的参数,用于指定是否要累加直方图。如果指定为 True,则计算整幅图像的直方图;如果指定为 False,则只计算当前区域的直方图。

2. (numpy)np.histagram

关于np.histagram的用法:

hist, bins = np.histogram(a, bins=10, range=None, normed=False, weights=None, density=None)

- a: 输入的一维数组。

- bins: 直方图的bin数量,也可以指定每个bin的边界,如[0, 10, 20, 30, 40]。

- range: 直方图统计的范围。

- normed和density:两个参数效果相同,设置是否对结果进行归一化。

对比度增强

对比度:最暗的像素和最大的像素值的对比

一个经典的对比度增强的方法:对比度拉伸,局限:仅适用于低动态图像

https://blog.csdn.net/xinjay1992/article/details/108672007

直方图均衡化

直方图最广泛的应用之一,就是直方图均衡化。

直方图均衡化,是一种对**图像增强**的方法:通过重新分配像素值的灰度级,来增强图像的对比度

对于矩阵的意义:让像素在整个像素范围更加均匀

基本思想

将直方图变换为一个均匀分布的直方图,使得像素值更加均匀,从而达到增强图像的目的。

通常,直方图中呈现尖峰的位置,说明处于该值的像素较为接近

而直方图均衡化后,可以令这些像素取值更加分散,因此视觉上可以将不明显的物体与周围物体区分开来

计算过程

https://blog.csdn.net/weixin_45930877/article/details/119581282

直方图性质等详解:https://zhuanlan.zhihu.com/p/411042641

底层代码

np.interp 是 NumPy 中的一个函数,用于进行线性插值。具体来说,

np.interp(x, xp, fp, left=None, right=None, period=None) 函数用于计算一个新的数组 x 对应的线性插值结果。其中,x 表示需要进行插值的位置,xp 表示已知数据的位置,fp 表示已知数据的取值。

具体地说,np.interp 的计算方式为:对于 x 中的每一个位置,找到其在 xp 中的相邻位置 xp_i 和 xp_{i+1},然后在这两个位置的 fp 取值中进行线性插值,得到 x 对应位置的插值结果。

如果 x 中的某个位置超出了 xp 的取值范围,那么根据参数 left 和 right 的取值,有不同的处理方式。如果 left 和 right 都未指定,那么超出取值范围的位置将返回 np.nan;如果 left 和 right 中的一个指定了值,那么超出取值范围的位置将使用该值进行插值;如果两者都指定了值,那么会根据超出位置的方向分别使用两个值进行插值。

此外,如果 xp 中的值不是单调递增的,那么可以使用参数 period 指定数据的周期,从而进行周期性插值。

import cv2
import numpy as np
import matplotlib.pyplot as plt# 先把图像变暗
img = cv2.imread('E:/notebook/lena.png', 0)
plt.imshow(img, cmap='gray')
plt.show()
dark = (0.5 * img).astype('uint8')
# cv2.imwrite("E:/notebook/dark_lena.jpg", dark)
image = cv2.imread("E:/notebook./dark_lena.jpg")
plt.imshow(image, cmap='gray')
plt.show()
# 计算直方图
hist, bins = np.histogram(img.flatten(), 256, [0,256])
plt.hist(hist, bins=bins)
plt.show()
print(hist[100:105])
# [1950 1950 1881 1862 1683]
# 直方图归一化
hist_norm = hist.astype(np.float32) / hist.sum()
print(hist_norm[100:105])
# [0.00743866 0.00743866 0.00717545 0.00710297 0.00642014]
# 计算累积直方图
cum_hist = hist_norm.copy()
for i in range(1, len(cum_hist)):cum_hist[i] = cum_hist[i-1] + cum_hist[i]
print(cum_hist[100:105])
# [0.32024384 0.3276825  0.33485794 0.34196091 0.34838104]
# 均衡化
img_equalized = np.interp(img.flatten(), bins[:-1], cum_hist).reshape(img.shape)
# print(bins)
plt.imshow(img_equalized, cmap='gray')
plt.show()

缺点

直方图整体均衡化用于增强图像质量。通过将图像映射到小区间,并进行归一化,使得其像素范围能够充斥整个空间。从而达到增强图像对比度,或者将亮度调整到适宜空间内的效果。

然而,对图像总体进行直方图均衡化,也会造成一些负面效果。

* 图像中某部分很亮,其他部分很暗,直方图均衡化会导致亮部过曝

* 图像分层

* 噪声问题

自适应直方图均衡(AHE, adaptive histogram equalization)

将图像分成若干的各区域对每个小区域做直方图均衡化

def AHE(im, wsz=100):h, w = im.shapeout = np.zeros(im.shape) # Declare output variablefor x in range(wsz//2, h + wsz//2):for y in range(wsz//2, w + wsz//2):blk = im[x-wsz//2:x+wsz//2, y-wsz//2:y+wsz//2]tmp = cv2.equalizeHist(blk)out[x-wsz//2:x+wsz//2, y-wsz//2:y+wsz//2] = tmpreturn out
img = cv2.imread("E:/notebook/person.png", 0)
plt.imshow(img, cmap="gray")
plt.show()
img = AHE(cv2.imread("E:/notebook/person.png", 0), wsz=50)
plt.imshow(img, cmap="gray")
plt.show()

CLAHE (contrast limited adaptive histogram equalization)

**核心思想** 将图像划分为若干个小块,并在小块内进行限制性直方图均衡化,经双线性最后的均衡化后的图像。

**步骤**

1. 将图像划分成若干个大小相等的块

2. 对每个子图进行“限制性”均衡化

3. 插值,得到均衡化后的像素值

“限制性”均衡化

**参数解释**

`clipLimit`: 控制了直方图均衡化中对比度增强的程度。该参数的数值越大,对比度增强的程度也越大,但是同时也会增加图像出现伪影的概率。

clip_limit = clip_limit_factor * (M / N)

其中,clip_limit_factor是一个用户定义的参数,通常取值在0.01到0.1之间;M是图像像素数量,N是直方图中的最高峰的数量。通常情况下,N的取值在50到200之间。

import numpy as np
arr = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
clip_limit = 5
arr_clipped = np.clip(arr, a_min=None, a_max=clip_limit)
print(arr_clipped)
# [1 2 3 4 5 5 5 5 5]

平滑伪影

`tileGridSize` 表示将图像分割成的小块的大小。它对均衡化结果的影响主要体现在以下两个方面:

* 计算直方图时的像素点数量:由于 CLAHE 算法是在每个小块上进行直方图均衡化,因此 tileGridSize 的大小会直接影响每个小块中包含的像素点数量。如果 tileGridSize 太小,每个小块中的像素点数量就会很少,可能会导致直方图统计不准确,从而影响均衡化结果。而如果 tileGridSize 太大,每个小块中的像素点数量就会很多,可能会导致直方图过于集中,也会影响均衡化结果。因此,要根据具体的图像特征和处理需求,选择适当的 tileGridSize 大小。

* 均衡化效果的细节保留:tileGridSize 的大小还会影响均衡化结果中细节的保留程度。如果 tileGridSize 太小,每个小块中的像素点数量较少,可能会导致细节的损失。而如果 tileGridSize 太大,每个小块中的像素点数量较多,可能会导致一些小细节被平滑掉,从而导致细节不够清晰。因此,要根据具体的需求和图像特征,选择适当的 tileGridSize 大小,以达到最优的均衡化效果和细节保留程度。

cl = cv2.createCLAHE(clipLimit=3, tileGridSize=(8, 8))
im = cl.apply(cv2.imread("E:/notebook/person.png", 0))
plt.imshow(im, cmap='gray')
plt.show()

直方图应用---图像分割

直方图的波动曲线,表示了不同像素等级的统计信息

对于一个语义上关联较为紧密的物体,其像素的关联可能也较为紧密

因此,在对某个高频像素进行处理的时候,往往也是对于语义关联较为紧密的物体进行处理

最优阈值怎么选?

img = cv2.imread('E:/notebook/greenscreen.png')
plt.imshow(img)
plt.show()
hist, bins = np.histogram(img.flatten(), 256, [0, 256])
print(hist)
plt.bar(range(256), hist.ravel())
plt.show()
max_peak = np.argmax(hist)
print(max_peak) # 最多的43阈值1
second_peak = np.argmin(hist[100: 150]) + 100
print(second_peak) # 第二多的119阈值2
# 区间1 [0: max]
img_bin = np.zeros_like(img)
img_bin = np.where((img >= max_peak), 255, img_bin)[:, :, 0]
plt.imshow(img_bin, cmap='gray')
plt.show()
img_bin_2 = np.ones_like(img) * 0
img_bin_2 = np.where((img <= second_peak), 255, img_bin_2)[:, :, 0]
plt.imshow(img_bin_2, cmap='gray')
plt.show()
mask = img_bin * img_bin_2
plt.imshow(mask, cmap='gray')
plt.show()

[ 4453 8 45 52 136 241 268 419 321 185

125 146 146 151 149 168 178 251 253 323

375 475 584 1422 6139 48787 56813 54050 46046 43175

44371 46881 50671 58219 67125 74001 79400 86139 94594 101315

106251 109673 111434 112107 108057 98107 82611 64185 45954 32076

21640 15553 11695 9372 7469 6331 5179 4293 4001 4069

4792 6236 7699 8896 9643 10292 10823 11433 11818 11658

11690 11837 11720 10725 9846 8624 8447 8868 9864 11090

12556 13322 14375 14455 14782 15375 16505 18185 20749 23972

27871 32725 37063 40653 43648 46654 50872 55540 60205 64409

68385 71674 73997 71533 64290 54777 45432 38829 34013 27982

19619 11758 5682 2464 1106 706 514 488 441 417

438 421 431 444 427 437 465 474 555 690

1209 2081 3344 4898 6402 7349 7833 7570 7398 7632

7893 8051 8164 8724 10058 10658 10922 10622 9631 8468

7228 6841 7235 7717 8257 8614 8938 9540 10613 11682

12396 12713 13697 14371 14911 16181 17299 19732 21809 24816

27204 29519 32065 37209 41996 45069 46880 49048 51798 53681

54753 57345 63271 69282 69754 65532 56153 46119 39935 33199

23103 10697 3033 681 246 182 183 124 108 104

86 100 81 95 73 84 79 86 81 73

81 106 119 131 119 125 113 124 128 132

142 126 157 133 129 142 181 169 183 140

100 82 100 93 107 150 169 182 145 195

250 318 440 511 573 544 426 427 376 354

276 230 161 115 110 95]

相关文章:

直方图及其应用

直方图定义直方图是一种描述数据的分布通过将连续变量划分成一系列区间&#xff0c;统计区间频率&#xff0c;并用来表示&#xff0c;以表征其统计特征在图像处理中&#xff0c;直方图可以用来表示图像中像素值的分布状况&#xff0c;描述不同灰度级的像素在图像中的占比直方图…...

《SpringBoot篇》26.SpringBoot整合Jackson超详细教程(附Jackson工具类)

陈老老老板&#x1f9b8;&#x1f468;‍&#x1f4bb;本文专栏&#xff1a;SpringBoot篇&#xff08;主要讲一些与springboot整合相关的内容&#xff09;&#x1f468;‍&#x1f4bb;本文简述&#xff1a;本文讲一下Jackson常见用法&#xff0c;超级详细。&#x1f468;‍&am…...

Redis 如何实现库存扣减操作和防止被超卖?

本文已经收录到Github仓库&#xff0c;该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点&#xff0c;欢迎star~ Github地址&#xff1a;https://github.com/…...

(Linux)Ubuntu查看系统版本

uname -a : 查看操作系统的发行版号和操作系统版本 Command: uname -aResult: Linux SERVER 5.19.0-35-generic #36-Ubuntu SMP PREEMPT_DYNAMIC Fri Feb 3 18:36:56 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux uname -v : 查看版本号 Command: uname -vResult: #36-Ubuntu …...

VxWorkds 内存管理(3)

虚拟内存管理 对于带MMU的目标板&#xff0c;VxWorks提供虚拟内存的支持&#xff0c;VxWorks提供了两种虚拟内存管理单元(MMU)的支持: 基本MMU和VxVMI 基本MMU邦定于VxWorks中&#xff0c;可以通过config.h中宏定义INCLUDE MMU BASIC或Tornado工程配置中包含基本MMU组件 VxV…...

单元测试、反射、注解、动态代理

&#x1f3e1;个人主页 &#xff1a; 守夜人st &#x1f680;系列专栏&#xff1a;Java …持续更新中敬请关注… &#x1f649;博主简介&#xff1a;软件工程专业&#xff0c;在校学生&#xff0c;写博客是为了总结回顾一些所学知识点 目录单元测试、反射、注解、动态代理单元测…...

【数据结构】夯实基础|线性表刷题01

作者&#xff1a;努力学习的大一在校计算机专业学生&#xff0c;热爱学习和创作。目前在学习和分享&#xff1a;算法、数据结构、Java等相关知识。博主主页&#xff1a; 是瑶瑶子啦所属专栏: 【数据结构|刷题专栏】&#xff1a;该专栏专注于数据结构知识&#xff0c;持续更新&a…...

Java怎么实现几十万条数据插入(30万条数据插入MySQL仅需13秒)

本文主要讲述通过MyBatis、JDBC等做大数据量数据插入的案例和结果。 30万条数据插入插入数据库验证实体类、mapper和配置文件定义User实体mapper接口mapper.xml文件jdbc.propertiessqlMapConfig.xml不分批次直接梭哈循环逐条插入MyBatis实现插入30万条数据JDBC实现插入30万条数…...

java多线程之线程的六种状态

线程的六种状态(1) NEW(初始状态)(2) TERMINATED(终止状态 / 死亡状态)(3) RUNNABLE(运行时状态)(4) TIMED_WAITING(超时等待状态)(5) WAITING(等待状态)(6) BLOCK(阻塞状态)sleep和wait的区别:操作系统里的线程自身是有一个状态的,但是java Thread 是对系统线程的封装,把这里的…...

UnixBench----x86架构openEuler操作系统上进行性能测试

【原文链接】UnixBench----x86架构openEuler操作系统上进行性能测试 &#xff08;1&#xff09;打开github上 UnixBench 地址&#xff0c;找到发布的tag &#xff08;2&#xff09;找到tar.gz包&#xff0c;右键复制链接 比如这里是 https://github.com/kdlucas/byte-unix…...

于Java8 Stream教程之collect()

目录 前言正文第一个小玩法 将集合通过Stream.collect() 转换成其他集合/数组&#xff1a;第二个小玩法 聚合&#xff08;求和、最小、最大、平均值、分组&#xff09;总结前言 本身我是一个比较偏向少使用Stream的人&#xff0c;因为调试比较不方便。 但是, 不得不说&#…...

Python

1、str 三个关键点&#xff1a; 正着数&#xff0c;0&#xff0c;1&#xff0c;2 反着数&#xff0c;0&#xff0c;-1&#xff0c;-2 str[a&#xff0c;b] 左闭右开 [a&#xff0c;b) str123456789 print(str) # 输出字符串 print(str[0:-1]) # 输…...

Spring框架中IOC和DI详解

Spring框架学习一—IOC和DI 来源黑马Spring课程&#xff0c;觉得挺好的 目录 文章目录Spring框架学习一---IOC和DI目录学习目标第一章 Spring概述1、为什么要学习spring&#xff1f;2、Spring概述【了解】【1】Spring是什么【2】Spring发展历程【3】Spring优势【4】Spring体系…...

本地快速搭建Kubernetes单机版实验环境(含问题解决方案)

Kubernetes是一个容器编排系统&#xff0c;用于自动化应用程序部署、扩展和管理。本指南将介绍Kubernetes的基础知识&#xff0c;包括基本概念、安装部署和基础用法。 一、什么是Kubernetes&#xff1f; Kubernetes是Google开发的开源项目&#xff0c;是一个容器编排系统&…...

FPGA控制DDS产生1CLK周期误差的分析(二)

前文简短的介绍了DDS的产生原理&#xff0c;其实相当的简单&#xff0c;所以也不需要多做解释&#xff0c;本文详细阐述一下在调试DDS的过程中所产生的一个bug 问题发现 正如上文所述&#xff0c;再用FPGA控制存储在rom中的波形信号输出之后&#xff0c;在上板之前&#xff0…...

这一次,吃了Redis的亏,也败给了GPT

关注【离心计划】&#xff0c;一起离开地球表面 背景 组内有一个系统中有一个延迟任务的需求&#xff0c;关于延迟任务常见的做法有时间轮、延迟MQ还有Redis Zset等方案&#xff0c;关于时间轮&#xff0c;这边小苏有一个大学时候做的demo&#xff1a; https://github.com/JA…...

第一章 信息化知识

1、信息是客观事物状态和运动特征的一种普遍形式&#xff0c;信息的概念存在两个基本的层次&#xff0c;即本体论层次和认识论层次&#xff1a; 本体论层次&#xff1a;就是事物的运动状态和状态变化方式的自我表述认识论层次&#xff1a;就是主体对于该事物的运动状态以及状态…...

如何用matlab工具箱训练一个SOM神经网络

本站原创文章&#xff0c;转载请说明来自《老饼讲解-BP神经网络》bp.bbbdata.com本文展示如何用matlab工具箱训练一个SOM神经网络的DEMO并讲解其中的代码含义和相关使用说明- 01.SOM神经网络DEMO代码 -- 本文说明 -下面&#xff0c;我们先随机初始化一些样本点&#xff0c;然后…...

音视频技术开发周刊 | 285

每周一期&#xff0c;纵览音视频技术领域的干货。新闻投稿&#xff1a;contributelivevideostack.com。GPT-4 Office全家桶发布谷歌前脚刚宣布AI工具整合进Workspace&#xff0c;微软后脚就急匆匆召开了发布会&#xff0c;人狠话不多地祭出了办公软件王炸——Microsoft 365 Cop…...

安装flume

flume最主要的作用就是实时读取服务器本地磁盘的数据&#xff0c;将数据写入到hdfs中架构&#xff1a;开始安装一&#xff0c;上传压缩包&#xff0c;解压并更名解压&#xff1a;[rootsiwen install]# tar -zxf apache-flume-1.9.0-bin.tar.gz -C ../soft/[rootsiwen install]#…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中&#xff0c;工业自动化网关起着至关重要的作用&#xff0c;尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关&#xff0c;为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多&#xff0c;其中不少设备采用Devicenet协议。Devicen…...