从零开始学cv-8:直方图操作进阶

news2024/12/28 20:21:52

文章目录

  • 一,简介
  • 二、直方图匹配
  • 三、局部直方图均衡化
  • 四、彩色直方图均衡化
    • 4.1 rgb彩色直方图均衡化
    • 4.2 ycrb 彩色直方图均衡化


一,简介

在上一篇文章中,我们探讨了直方图的基本概念,并详细讲解了如何利用OpenCV来查看图像直方图,以及如何实现直方图均衡化。在此基础上,本篇将继续深入,介绍直方图均衡化的高级应用,包括直方图匹配、局部直方图均衡化以及彩色图像的直方图均衡化技术。

二、直方图匹配

直方图均衡化能自动增强图像的整体对比度,但是往往结果难以受到控制。实际中常常需要增强某个特定灰度值范围内的对比度或使图像灰度值的分布满足特定需求这个时候就需要直方图匹配技术。
直方图匹配,亦称作直方图规定化,是一种旨在调整图像灰度分布的图像处理技术,目的是使其与指定参考图像的直方图相吻合。此技术有助于提升图像的视觉效果,尤其在需要特定灰度分布以凸显图像特征时尤为有效。直方图匹配的执行步骤包括:

  1. 参考图像直方图计算:选取一个参考图像,并计算其直方图。
  2. 累积分布函数(CDF)计算:计算参考图像直方图的累积分布函数。
  3. 目标图像直方图与CDF计算:对目标图像执行相同的操作,获取其直方图和CDF。
  4. 映射关系建立:通过比较目标图像与参考图像的CDF,建立灰度级之间的映射关系,通常通过查
    找目标图像CDF值在参考图像CDF中的对应灰度级来实现。
  5. 映射应用:依据建立的映射关系,将目标图像的每个像素值重新映射到新的灰度级。
  6. 生成匹配后的图像:应用映射后的灰度值,创建出具有参考图像直方图特征的新图像。

直方图匹配的应用领域包括:
图像风格转换:使一幅图像在视觉上更接近另一幅图像的风格。
图像增强:在特定应用场景中,通过匹配特定直方图来增强图像的特定特征。
图像复原:在图像复原过程中,利用直方图匹配调整灰度分布,以改善复原效果。
注意事项:
直方图匹配过程主要是改变目标图像的灰度分布,使其与参考图像的直方图相似,但这种改变并不涉及图像的实际内容,如形状、纹理或场景结构等。因此,尽管目标图像的灰度分布(即像素的亮度级别)会发生变化,图像中的物体、形状、颜色等视觉内容可能并不会与参考图像保持一致。换句话说,直方图匹配可能会改变图像的整体外观,但不会改变图像中对象的具体识别信息或场景的实质性内容,并且匹配过程可能会引入噪声或失真,因此需根据实际情况进行适当调整。

使用代码:

# 1.60 彩色图像的直方图匹配
import cv2
import numpy as np

# 读取并调整图像大小到640x480
img = cv2.resize(cv2.imread("sky1.jpg", flags=1),(640,480)) # flags=1 表示以彩色图像格式读取
imgRef = cv2.resize(cv2.imread("sky2.jpg", flags=1),(640,480))  # 读取并调整参考图像的大小,用于直方图匹配

# 获取图像的通道数
_, _, channel = img.shape

# 初始化输出图像,其大小和类型与原始图像相同
imgOut = np.zeros_like(img)

# 遍历每个通道
for i in range(channel):
    # 计算原始图像在当前通道的直方图,并返回直方图数组和每个箱子的边界
    histImg, _ = np.histogram(img[:, :, i], 256)
    # 计算参考图像在当前通道的直方图
    histRef, _ = np.histogram(imgRef[:, :, i], 256)
    
    # 计算原始图像的累积分布函数 (CDF)
    cdfImg = np.cumsum(histImg)
    # 计算参考图像的累积分布函数 (CDF)
    cdfRef = np.cumsum(histRef)
    
    # 对每个灰度级进行遍历
    for j in range(256):
        # 计算当前灰度级的CDF值与参考图像CDF值的差值的绝对值
        tmp = abs(cdfImg[j] - cdfRef)
        # 将numpy数组转换为列表
        tmp = tmp.tolist()
        # 找到差值最小的索引,即最接近的灰度级
        index = tmp.index(min(tmp))
        # 将原始图像中对应灰度级的像素值替换为匹配后的灰度级
        imgOut[:, :, i][img[:, :, i] == j] = index

# 显示原始图像
cv2.imshow("img", img)
# 显示参考图像
cv2.imshow("imgRef", imgRef)
# 显示直方图匹配后的图像
cv2.imshow("imgOut", imgOut)
# 等待按键后关闭所有窗口
cv2.waitKey(0)

效果:
在这里插入图片描述
可以实现类似图像风格迁移的效果,但速度较慢,可用来扩充数据集或者批量P图

三、局部直方图均衡化

局部直方图均衡化(Local Histogram Equalization)是一种针对传统直方图均衡化方法的改进,其目的是避免传统方法可能导致的局部对比度降低的问题。传统直方图均衡化会对整个图像的灰度分布进行全局调整,以实现灰度级的均匀分布,但这有时会牺牲图像中特定区域的对比度。相比之下,局部直方图均衡化通过在图像的不同区域实施差异化的均衡化策略,旨在保留这些区域的局部细节和对比度。

局部直方图均衡化的实施过程包括以下几个步骤:

  1. 图像分割:将输入图像划分为若干个小的区域,这些区域通常被称为块或窗口。
  2. 局部直方图计算:对每个小区域单独计算其局部直方图,以反映该区域的灰度分布特性。
  3. 局部累积分布函数(CDF)计算:对每个局部直方图计算累积分布函数,以获得每个灰度级在该区域中的分布情况。
  4. 局部映射关系建立:根据每个区域的CDF建立相应的灰度级映射关系,这些映射关系反映了均衡化后的灰度级分布。
  5. 局部映射应用:将每个小区域的像素值按照其CDF映射到新的灰度级,从而实现局部均衡化。
  6. 合成匹配后的图像:将所有小区域的均衡化结果合并,得到最终的均衡化图像。

局部直方图均衡化的优势在于:

  1. 保留局部对比度:通过局部处理,可以保留图像中的局部对比度,避免全局均衡化可能导致的细节丢失。
  2. 适应性:该方法能够更好地适应图像中不同区域的照明变化和对比度差异

注意:
在实施局部直方图均衡化时,选择合适的块大小对于取得理想效果至关重要。如果块大小设置过小,可能会丢失图像中的细节信息;相反,如果块过大,可能会引入额外的噪声。因此,确定一个既能保留必要细节又能有效抑制噪声的块大小是关键。
此外,由于局部直方图均衡化需要对每个小区域分别计算直方图和累积分布函数,这相对于全局直方图均衡化来说,计算效率可能会较低。全局均衡化只需要对整个图像进行一次直方图和CDF的计算,而局部均衡化则需要重复这个过程对每个区域进行处理。尽管如此,局部均衡化在保持图像局部对比度和适应图像局部特征方面具有显著优势,因此在需要精细调整图像对比度和细节保留的场景中,它仍然是首选的方法。

在opencv中有一个实现局部直方图均衡化的方法cv2.createCLAHE(clipLimit, tileGridSize)函数说明:

参数说明:
clipLimit 参数定义了一个对比度增强的阈值。当直方图中某个灰度级的对比度增强超过这个阈值时,该灰度级的对比度增强会被限制在 clipLimit 以下。。
tileGridSize: 这是一个整数元组,表示将图像分割成的小块的大小。例如,(8, 8) 表示将图像分割成 8x8 的块。每个小块的直方图将被单独计算和均衡化,然后将结果合并以形成最终的均衡化图像。

使用代码:

# 1.60 彩色图像的直方图匹配
import cv2
import numpy as np
path = r"E:\PS\2.png"
img = cv2.imread(path, 0)
equ1 = cv2.equalizeHist(img)  # 普通的直方图均衡化
clahe = cv2.createCLAHE(8, (8, 8))  # 局部直方图均衡化,创建clahe对象
equ2 = clahe.apply(img)  # 将clahe对象应用到img上,返回增强图片

cv2.imshow("equ1", equ1)
cv2.imshow("equ2", equ2)
cv2.waitKey(0)

效果:
左侧普通直方图均衡化,右侧局部直方图均衡化
在这里插入图片描述

四、彩色直方图均衡化

彩色直方图均衡化(Color Histogram Equalization)是一种针对彩色图像的直方图均衡化技术。与灰度图像的直方图均衡化类似,彩色直方图均衡化的目的是通过调整图像的像素分布,使得输出图像的直方图尽可能平坦,从而增强图像的全局对比度。然而,彩色直方图均衡化是在彩色图像的每个颜色通道上分别进行,而不是在整个图像上进行。
彩色直方图均衡化的实现步骤:

  1. 颜色分离:将彩色图像分离成三个或更多颜色通道(红、绿、蓝等)。
  2. 计算每个通道的直方图:对每个颜色通道分别计算直方图。
  3. 计算累积分布函数(CDF):对每个通道的直方图计算累积分布函数。
  4. 计算直方图均衡化映射:将每个通道的累积分布函数值乘以通道的最大灰度级,得到每个通道的新映射值。
  5. 应用映射:根据映射关系,将每个通道的像素值映射到新的灰度级。
  6. 合成匹配后的图像:将所有通道的映射结果合并成最终的匹配图像

在进行彩色直方图均衡化时,需要注意以下几点:首先,选择合适的颜色空间对于实现理想的图像处理效果至关重要,常见的选择包括RGB和HSV等。其次,由于需要对每个颜色通道单独计算直方图和累积分布函数,因此其计算效率可能不如全局直方图均衡化。尽管如此,彩色直方图均衡化仍是一种有用的工具,可以在保持图像颜色信息的同时提高对比度,从而实现更好的视觉效果。
本文将介绍两种实现彩色直方图均衡化的方法。

4.1 rgb彩色直方图均衡化

将图像rgb三色通道拆分,分开进行直方图均衡化,并将处理后的三通道灰度图按照通道维度拼接起来,获得新的三通道图像
实现代码:

# 1.60 彩色图像的直方图匹配
import cv2
import numpy as np
path = r"E:\PS\2.png"
img = cv2.imread(path)
(b, g, r) = cv2.split(img)  # 通道拆分
bH = cv2.equalizeHist(b)  # b通道直方图均衡化
gH = cv2.equalizeHist(g)  # g通道直方图均衡化
rH = cv2.equalizeHist(r)  # r通道直方图均衡化
result = cv2.merge((bH, gH, rH))  # 通道合并
cv2.imshow("result", result)
cv2.waitKey(0)

效果:
原图
在这里插入图片描述
处理后的图片:
在这里插入图片描述
图像亮度提升但部分颜色失真

4.2 ycrb 彩色直方图均衡化

YCbCr(Y’CbCr)是一种用于表示彩色图像中的颜色信息的色彩空间,它根据ITU-R BT.601标准定义,主要用于视频传输和显示。YCbCr色彩空间包括三个分量:Y’(亮度分量),它是一个灰度值,与颜色无关,通常用于彩色视频的亮度信号;Cb(蓝色色差分量),表示蓝色信号与Y’分量之间的差值,包含了蓝色分量的信息;Cr(红色色差分量),表示红色信号与Y’分量之间的差值,包含了红色分量的信息。通过Y’、Cb和Cr三个分量的组合,YCbCr色彩空间能够准确地表示彩色图像中的颜色信息,并在视频处理和显示中发挥重要作用。要对图像进行彩色直方图均衡化,首先先将图像转化到ycrb颜色空间,然后对其中的y通道(亮度通道)做局部直方图均衡化(crcb颜色通道最好不要动,颜色容易变)这样可以减少颜色的失真.。
实现代码:

# 1.60 彩色图像的直方图匹配
import cv2
import numpy as np

path = r"E:\PS\2.png"

def hisEqulColor2(imga): #直方图均衡化算法
    ycrcb = cv2.cvtColor(imga, cv2.COLOR_BGR2YCR_CB) # 转换ycrb颜色空间
    channels = cv2.split(ycrcb)
    print(channels)
    clahe = cv2.createCLAHE(clipLimit=4.0, tileGridSize=(11,11))  # 局部直方图均衡化
    clahe.apply(channels[0], channels[0])
    cv2.merge(channels, ycrcb)
    cv2.cvtColor(ycrcb, cv2.COLOR_YCR_CB2BGR, imga)
    return imga
img = cv2.imread(path)
his = hisEqulColor2(img)
cv2.imshow("result", his)
cv2.imshow("img", img)
cv2.waitKey(0)

效果:
在这里插入图片描述
同上面方法相比颜色失真较少,并且不会过度拉伸图像,图像亮度提升可以使用伽马变换或对数变换

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

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

相关文章

王老师 linux c++ 通信架构 笔记(四)继续介绍 nginx 的编译,生成适合本平台的 nginx 可执行程序

(16) 继续介绍 nginx 的文件夹组成: 接着介绍 conf 目录 : 接着介绍 contrib 文件夹 : 接着介绍 html 文件夹 : 接着介绍 man 文件夹: 更正一下: 下图即为此帮助文件的内容&#…

电子电气架构---主流主机厂电子电气架构华山论剑(下)

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…

华为AR1220配置GRE隧道

1.GRE隧道的配置 GRE隧道的配置过程,包括设置接口IP地址、配置GRE隧道接口和参数、配置静态路由以及测试隧道连通性。GRE隧道作为一种标准协议,支持多协议传输,但不提供加密,并且可能导致CPU资源消耗大和调试复杂等问题。本文采用华为AR1220路由器来示例说明。 配置…

Dubbo源码深度解析(六)

上一篇博客《Dubbo源码深度解析(五)》主要讲:当服务消费方发起请求时,服务提供方是通过Netty服务接受请求并处理的,涉及到Netty相关使用及部分原理的讲解,以及最后又是如何将Invoker对象的执行结果返回给服务消费方的等。同时也讲…

LMDeploy 量化部署实践闯关任务

一、LMDeploy量化介绍 1.LMDeploy部署模型的优势 LMDeploy实现了高效的推理、可靠的量化、卓越的兼容性、便捷的服务以及有状态的推理。 相比于vllm具有领先的推理性能: LMDeploy也提供了大模型量化能力:主要包括KV Cache量化和模型权重量化。 LMDepl…

0813作业+梳理

一、实现虚拟机械臂控制 #include<myhead.h> #define SER_PORT 8888 //服务器端口号 #define SER_IP "192.168.0.126" //服务器ip地址 #define CLI_PORT 5555 //客户端端口号 #define CLI_IP "192.168.0.133" //客户端地址 int main(int argc, …

css - word-spacing 属性(指定段字之间的间距大小)属性定义及使用说明

介绍 CSS word-spacing 属性&#xff0c;用于指定段字之间的空间&#xff0c;例如&#xff1a; p {word-spacing:30px; }word-spacing属性增加或减少字与字之间的空白。 注意&#xff1a; 负值是允许的。 浏览器支持 表格中的数字表示支持该属性的第一个浏览器版本号。 属…

sqlserver 消息 9420,级别 16,状态 1,第 7 行

declare TerminalXml xml set TerminalXml(select * from TCK_TerminalInfo(nolock) for xml PATH) 执行时报9420错误,sqlserver 消息 9420,级别 16,状态 1,第 7 行 感觉非常奇怪,这个程序在很多客户多运行.当时以为数据库的配置不对.我重启了数据服务,还是没有解决…

智慧校园信息化服务平台、基于微信小程序的校园服务管理系统

摘 要 本文论述了智慧校园信息化服务平台的设计和实现&#xff0c;该网站从实际运用的角度出发&#xff0c;运用了计算机网站设计、数据库等相关知识&#xff0c;基于 ssm框架和Mysql数据库设计来实现的&#xff0c;网站主要包括用户注册、用户登录、查看教室信息、校园趣事…

mysql聚合函数和分组

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…

Java并发类API -- Future和Callable

1.Future和Callable接口 Future 是一个表示异步计算结果的接口&#xff1b; 接口Callable与线程功能密不可分&#xff0c;但和Runnable的主要区别为&#xff1a; 1&#xff09;Callable接口的call&#xff08;&#xff09;方法可以有返回值&#xff0c;而Runnable接口的run&a…

java:IDEA修改java版本的几个不同的地方

文章目录 项目JDK设置&#xff08;Project SDK&#xff09;项目模块级JDK设置&#xff08;Module SDK&#xff09;IDE级别的JDK设置Maven配置文件编译器&#xff08;Java Compiler&#xff09;构建工具配置文件&#xff08;如build.gradle或pom.xml&#xff09;.idea/misc.xml文…

C语言(17)——单链表的应用

目录 1.单链表经典算法OJ题⽬ 1.1单链表相关经典算法OJ题1&#xff1a;移除链表元素 1.2单链表相关经典算法OJ题2&#xff1a;反转链表 1.3 单链表相关经典算法OJ题3&#xff1a;链表的中间节点 1.单链表经典算法OJ题⽬ 1.1单链表相关经典算法OJ题1&#xff1a;移除链表元素…

还有比这java状态压缩更通俗易懂的解释?

前言 Java中的状态压缩&#xff0c;或者说位运算状态压缩&#xff0c;是一种利用位操作&#xff08;如位与&、位或|、位异或^、位非~、左移<<、右移>>等&#xff09;来高效地存储和处理状态信息的技术。这种技术特别适用于那些状态空间不是很大&#xff0c;但…

微服务:网关路由和登录校验

续上篇&#xff1a;微服务&#xff1a;服务的注册与调用和OpenFiegn-CSDN博客 参考&#xff1a;黑马程序员之微服务 &#x1f4a5; 该系列属于【SpringBoot基础】专栏&#xff0c;如您需查看其他SpringBoot相关文章&#xff0c;请您点击左边的连接 目录 一、网关路由 1. 网关…

苹果注册海外账户|注册海外Apple ID|下载海外App

注册海外apple ID 背景 先前的一直使用的Apple ID注册地区是国内。 但是一些app因地区限制需要海外账户才能下载&#xff0c;因此需要使用海外apple ID。 因此需要注册海外apple ID&#xff08;如美国&#xff09;。 前言 绑定手机号 手机号可以和国内Apple ID一样没关系…

记一次SATA硬盘上电不转问题排查(最终查到和供电线有关)

一、背景 今年把旧的台式机换成了新的台式机&#xff0c;把硬盘挪到新电脑了。 二、问题 把硬盘挪到新电脑后&#xff0c;SSD可以正常使用&#xff0c;但是有个氦气机械盘始终不能用。 三、排查过程 对比实验 做了一些实验&#xff1a; 把硬盘接回旧电脑会正常转&#x…

【轨物洞见】找到技术创新的“真问题”

技术创新是用技术解决真问题&#xff0c;创造真价值。问题是需求&#xff0c;技术是供应&#xff0c;将需求与供应有效连接的能力&#xff0c;是创新力。技术创新的第一步在于找到“真问题”。在找问题之前&#xff0c;我们先了解一下问题是如何产生的。 问题就是期望值与现状之…

eNSP 华为交换机链路聚合

华为交换机链路聚合 链路聚合好处&#xff1a; 1、提高带宽 2、链路冗余 SW_2&#xff1a; <Huawei>sys [Huawei]sys SW_2 [SW_2]vlan batch 10 20 [SW_2]int g0/0/4 [SW_2-GigabitEthernet0/0/4]port link-type access [SW_2-GigabitEthernet0/0/4]port default vl…

ECCV2024|商汤发布3D面部动画系统UniTalker:通过统一模型扩展音频驱动的 3D 面部动画

商汤研究院最新发布了一个先进的3D面部动画系统UniTalker&#xff0c;可以从不同的音频领域生成逼真的面部动作&#xff0c;包括各种语言的清晰和嘈杂的声音、文本到语音生成的音频&#xff0c;甚至伴有背景音乐的嘈杂歌曲。 UniTalker 可以输出多个注释。对于具有新注释的数据…