openCV实战-系列教程8:直方图与均衡化(直方图定义/mask操作/均衡化原理/均衡化效果/自适应均衡化)、原理解析、源码解读

news2024/12/25 14:07:15

OpenCV实战系列总目录

打印图像直接用这个函数:

import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline
def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

1、直方图

1.1 基本定义

图像中的直方图概念,将图像分解成像素点,直方图对像素点进行统计。

如左图读进来一个灰度图,用数值的形式展示出来,直方图就是统计0-255个像素值的分布情况,其中横坐标是0-255的像素值,纵坐标是每个像素值出现的次数。

需要用到这个函数:cv2.calcHist(images,channels,mask,histSize,ranges)

  • images: 原图像图像格式为 uint8 或 float32。当传入函数时应 用中括号 [] 括来例如**[img]**
  • channels: 同样用中括号括来它会告函数我们统幅图像的直方图。如果入图像是灰度图它的值就是 [0]如果是彩色图像 的传入的参数可以是 [0] [1] [2] 它们分别对应着 BGR。
  • mask: 掩码图像。统整幅图像的直方图就把它为 None。但是如果你想统图像某一分的直方图的你就制作一个掩码图像并使用它。
  • histSize:BIN的数目,也就是你需要多少根柱子,函数会自动按照柱子个数将取值范围均匀分布进去,也要用中括号括起来。
  • ranges: 像素值范围常为 [0,256],python左闭右开嘛

所以后面两个参数基本不用改了。

1.2 代码实例

读进来一个小猫的灰度图,获取像素统计信息:

img = cv2.imread('cat.jpg',0) #0表示灰度图
hist = cv2.calcHist([img],[0],None,[256],[0,256])
print(hist.shape)

hist就是一个二维的ndarray,打印结果:

(256, 1)

将这个直方图用matplotlib画出来:

plt.hist(img.ravel(),256); 
plt.show()

打印结果:

将刚刚的小猫图对三个颜色通道都进行统计:

img = cv2.imread('cat.jpg') 
color = ('b','g','r')
for i,col in enumerate(color): 
    histr = cv2.calcHist([img],[i],None,[256],[0,256]) 
    plt.plot(histr,color = col) 
    plt.xlim([0,256]) 

打印结果:
在这里插入图片描述

2 mask操作

怎样创建一个掩码,以及掩码的定义:

# 创建mast
mask = np.zeros(img.shape[:2], np.uint8)
print (mask.shape)
mask[100:300, 100:400] = 255
cv_show(mask,'mask')

打印结果:

(414, 500)

在这里插入图片描述
这个掩码只有两部分,一部分为黑一部分为白,当把这个掩码图像和原始图像结合在一起的效果就是图三。掩码图像和原始图像大小是一样的,掩码覆盖的地方设置成255,其他地方设置成0,掩码图像和原始图像结合相当于截取操作。

掩码的定义,就是利用np.zeros来定义,大小按照图像长宽的尺寸,然后按照数组的索引范围选择要保存的部位,把要保存的地方全部赋值为255。

把原始图像读进来:

img = cv2.imread('cat.jpg', 0)
cv_show(img,'img')

打印结果:
在这里插入图片描述
将原始图像和掩码图像做与操作:

masked_img = cv2.bitwise_and(img, img, mask=mask)#与操作
cv_show(masked_img,'masked_img')

对带掩码和不带掩码的图像都做一下直方图统计,通过子图的方式进行展示:
在这里插入图片描述

3、直方图的均衡化

如图这个直方图的像素分布特别不均匀,如何让他的像素分布稍微均匀一点呢?
在这里插入图片描述
均衡化的过程就是像素值的分布从左1变成左2,最后的效果是左3
在这里插入图片描述
比如下图的这两个个像素点表格,左边是原始图像,右边是均衡化后的图像。将原来的像素分布用一个固定的计算方法映射到另一个分布:
在这里插入图片描述
这个过程是怎么做的呢?

  1. 将像素值从大到小进行统计,如上图的第三个表格有四个像素值以及个数的统计,根据统计结果,将每个像素对应出现的概率如表格所示计算出来
  2. 按照大小进行计算累积概率。比如像素值为50的有4个,概率为0.25,累积概率仍为0.25,如果是128,有3个,概率为0.1875,累积概率就会加上它自己以及比它小的所有像素的概率,所以是0.4375,依次类推。
  3. 得到所有像素值的累积概率,再乘上像素的取值范围再取整。
    读进来一个小猫的灰度图,获取像素统计信息:
img = cv2.imread('clahe.jpg',0) #0表示灰度图 #clahe
plt.hist(img.ravel(),256); 
plt.show()

打印结果:
在这里插入图片描述
进行均衡化处理:

equ = cv2.equalizeHist(img) 
plt.hist(equ.ravel(),256)
plt.show()

打印结果:
在这里插入图片描述
将均衡化处理前后的图作比较:

res = np.hstack((img,equ))
cv_show(res,'res')

打印结果:
在这里插入图片描述
换成lena的图:
在这里插入图片描述

4、自适应均衡化

均衡化实际上是整体上对像素进行了一个平均的处理操作,这意味着可能会丢失一些细节。那如何避免出现这种情况呢?我们可以将图像分成若干个部分,然后各个部分做自己的均衡化,这样就缓冲了细节的丢失。
在openCV中已经给了我们一些现成的函数来进行这个操作,这就是自适应直方图均衡化。
首先将自适应直方图均衡化的方法生成出来:

clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) 

然后将这个自适应方法应用到当前的输出当中,将原始图像、均衡化处理图像、自适应均衡化处理图像都打印出来:

res_clahe = clahe.apply(img)
res = np.hstack((img,equ,res_clahe))
cv_show(res,'res')

打印结果:
在这里插入图片描述
如上图的1、2、3,很显然3图在细节的处理和保留比2要强出很多。

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

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

相关文章

初阶数据结构(三)链表

💓博主csdn个人主页:小小unicorn💓 ⏩专栏分类:c 🚚代码仓库:小小unicorn的学习足迹🚚 🌹🌹🌹关注我带你学习编程知识 前面我们讲的线性表的顺序存储结构。它…

2023年03月 C/C++(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题:最佳路径 如下所示的由正整数数字构成的三角形: 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,和最大的路径称为最佳路径。你的任务就是求出最佳路径上的…

天正(建筑、暖通、给排水、电气、结构)软件安装包分享(附安装教程)

目录 一、软件简介 二、软件下载 一、软件简介 天正软件是一款由天正集团开发的建筑工程设计软件,广泛应用于建筑设计领域。该软件旨在提供便捷、高效的建筑设计工具,帮助设计师快速创建高质量的建筑图纸。 以下是天正软件的主要特点: 支…

Spring注解之@validated的使用

使用步骤 1.引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> 2.异常拦截类 /*** 全局异常处理*/ Slf…

二级MySQL(九)——表格数据处理练习

在Mysql中&#xff0c;可以用INSERT或【REPLACE】语句&#xff0c;向数据库中已一个已有的表中插入一行或多行记录。 在Mysql中&#xff0c;可以用【DELETE】或【TRUNCATE】语句删除表中的所有记录。 在Mysql中&#xff0c;可以用【UPDATE】语句来修改数据表中的记录。 为了完…

齐套检查与分配在生产计划中的实现

最近一段时间看到很多关于生产计划中&#xff0c;作齐套检查与分析讨论&#xff0c;正好我们的易排1.5版添加了类似功能。本文结合易排平台上相应的功能与特征&#xff0c;介绍一下我们在这方面的些许研究结论与看法。 本文中用到些引用自易排平台的概念&#xff0c;先行给出定…

React笔记(一)初识React

一、React概述 1、什么是react react的官网:React 用于构建用户界面的 JavaScript 库&#xff0c;它也是一个渐进式的用于构建用户界面的javascript框架 2、主要特征 声明式&#xff1a;使用原生JS编写的页面存在着开发效率低下、性能较差的情况&#xff0c;使用react大家就…

JavaWeb 速通JQuery

目录 一、JQuery快速入门 1.基本介绍 : 2.入门案例 : 二、JQuery对象 1.基本介绍 : 2.DOM对象 --> JQuery对象 : 3.JQuery对象 --> DOM对象 : 三、JQuery选择器 1.简介 : 2.基本选择器 : 3.层次选择器 : 4.过滤选择器 : 4.1 基础过滤选择器 4.2 内容过滤选择…

wget方式下载DAAC数据

1. 注册DAAC账号 2. 申请数据&#xff0c;获得含下载链接的txt文件 3. 下载配置wget 4.下载&#xff1a; 4.1 创建目录用来保存数据&#xff08;如 E:\3CMB&#xff09; 4.2 在新创建目录下 创建文件 cookies.txt文件 4.3 将含下载链接的txt文件移动到新创建的文件夹中 …

老胡的周刊(第105期)

老胡的信息周刊[1]&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 &#x1f3af; 项目 Piwigo[2] Piwigo 是一个开源的网络照片库软…

01 java 学习 数据类型、基础语法、封装、继承、多态、接口、泛型、异常等

目录 环境搭建和基础知识 什么是JRE: 什么是JDK: 基础数据类型 分支选择if else switch和c一毛一样 for和while循环还有数组基本和c一样 封装 函数调用、传参、命名规范、数组新命名规范 java输入Scanner scanner new Scanner(System.in); 类的创建和使用以及封装修饰符…

【马拉车算法/动态规划】最长回文字串

最长回文字串 1.问题描述2.中心扩展法&#xff08;O(N^2)&#xff09;3.动态规划4.Manacher(马拉车算法) 1.问题描述 常用有3种算法&#xff1a;中心扩展法、动态规划和Manacher算法 2.中心扩展法&#xff08;O(N^2)&#xff09; 解释&#xff1a; 从中心向外扩展。 分为两种…

Please use ‘App‘ component instead.报错问题解决

今天我在用 antd 组件库编写项目发生了如下报错 这个警告是关于 antd 组件库中的一个问题&#xff0c;提示在静态函数中无法像动态主题一样使用上下文&#xff08;context&#xff09;。建议使用 App 组件来解决此问题。 具体解决方法如下&#xff1a; 确保你的应用程序包含一…

深入解析Java中的位运算符:<<、>>和>>>

当谈到位运算符时&#xff0c;Java中的<<、>>和>>>运算符在源码中无疑是经常出现的。这些运算符在处理整数类型的数据时发挥着重要作用。它们主要用于对二进制位进行操作&#xff0c;是一种高效处理位级信息的方式。让我们深入探讨一下这些运算符的工作原…

数据库的类型

一说到数据库&#xff0c;大多数人可能像我一样&#xff0c;首先想到的就是 MySQL、Oracle 这样的关系型数据库。因为我们平时接触的最多&#xff0c;而且大学课程中有关于数据库的&#xff0c;也是以关系型数据库为主的。 其实&#xff0c;除了关系型数据库外&#xff0c;还有…

八大排序算法 (python版本)

八大排序算法 个人学习笔记 如有问题欢迎指正交流快速排序经常考&#xff0c; 如果只掌握一个排序算法的话&#xff0c;首选快速排序算法 八大排序算法通常指的是以下八种经典排序算法&#xff1a; 1. 冒泡排序 (Bubble Sort) 使用场景&#xff1a;适用于小规模数据的排序&a…

openCV实战-系列教程9:傅里叶变换(傅里叶概述/频域变换结果/低通与高通滤波)、原理解析、源码解读

OpenCV实战系列总目录 打印图像直接用这个函数&#xff1a; def cv_show(img,name):cv2.imshow(name,img)cv2.waitKey()cv2.destroyAllWindows()1、傅里叶变换 在生活中&#xff0c;我们的大部分事情都是以时间为参照的&#xff0c;用时间为参照的为时域分析&#xff0c;在频…

【C语言基础】数据输入输出

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

视觉语言多模态预训练综述

论文: https://arxiv.org/pdf/2207.01772 预训练数据集 预训练任务 模型结构 本文根据特征在进行视觉和语言模态融合处理之前是否进行处理,将VLP 模型按结构分为单流式(single-stream) 和双流式( cross-stream) 单流模型将视觉特征和语言特征直接输入融合模块,进行模型训练,…

【小沐学Unity3d】3ds Max 骨骼动画制作(Physique 修改器)

文章目录 1、简介2、Physique 工作流程3、Physique 对象类型4、Physique 增加骨骼5、Physique 应用和初始化6、Physique 顶点子对象7、Physique 封套子对象8、设置关键点和自动关键点模式的区别8.1 自动关键点8.2 设置关键点 结语 1、简介 官方网址&#xff1a; https://help.…