opencv-python图像增强六:低光照增强

news2024/9/21 12:38:57

文章目录

  • 一:简介
  • 二、低光照图像增强方案:
  • 三、算法实现步骤
    • 3.1 CLAHE直方图均衡化:
    • 3.2 伽马变换:
    • 3.3 对亮度通道做伽马变换
  • 四:整体代码实现
  • 五,效果:

一:简介

低光照图像增强是一种图像处理技术,旨在改善在低光照条件下拍摄的图像的质量。这种技术可以提高图像的亮度、对比度和细节,使其更易于人类视觉系统或后续图像分析任务使用。

二、低光照图像增强方案:

本方案采用图像增强技术以提升图像亮度。首先,对所获取的低光照图像进行噪声消除处理,有效移除大部分暗部噪声。随后,对去噪后的图像实施自适应直方图均衡化,以增强图像的细节与纹理表现。最后,将图像转换至HSV色彩空间,并对V通道(代表亮度)施加伽马变换,以进一步强化图像的亮度水平。

三、算法实现步骤

3.1 CLAHE直方图均衡化:

CLAHE(Contrast Limited Adaptive Histogram Equalization)是一种自适应直方图均衡化的变种,它通过在传统直方图均衡化的基础上增加对比度限制机制,以避免对比度过高和噪声的放大。CLAHE的主要步骤包括将图像分割成多个小区域,计算每个区域的局部直方图,对直方图进行均衡化处理以增强对比度,并在均衡化过程中通过对比度限制参数来控制每个区域的动态范围,以防止对比度过高。最后,调整每个区域的像素值并合并所有处理过的区域,得到最终增强后的图像。这种方法可以更好地保留图像的局部对比度,特别是在图像中存在大范围亮度变化时,能够在每个区域独立处理对比度,同时通过对比度限制机制减少噪声的放大.
为了放大图像细节以及防止图像失真参数全选为1

代码实现:

def hisEqulColor2(imga):
    ycrcb = cv2.cvtColor(imga, cv2.COLOR_BGR2YCR_CB)
    channels = cv2.split(ycrcb)
    clahe = cv2.createCLAHE(clipLimit=1.0, tileGridSize=(1, 1))
    clahe.apply(channels[0], channels[0])
    cv2.merge(channels, ycrcb)
    cv2.cvtColor(ycrcb, cv2.COLOR_YCR_CB2BGR, imga)
    return imga

3.2 伽马变换:

伽马变换(Gamma Transformation)是一种非线性变换,广泛应用于图像处理和计算机视觉领域。伽马变换通过调整像素值来改善图像的对比度和亮度,使其更符合人类视觉系统的感知特性。
代码实现:

def gamma_trans(img, gamma):
    """
    对图像进行gamma变换处理。
    参数:
    img: 输入图像
    gamma: 伽马值
    返回:
    gamma变换后的图像
    """
    gamma_table = [np.power(x / 255.0, gamma) * 255.0 for x in range(256)]
    gamma_table = np.round(np.array(gamma_table)).astype(np.uint8)
    return cv2.LUT(img, gamma_table)

代码首先创建了一个伽马表(gamma_table),该表包含256个元素,每个元素代表输入图像中一个灰度级的变换后的值。通过列表推导式,代码计算了每个灰度级(从0到255)在伽马变换后的值。具体来说,每个灰度级 x 的伽马变换后的值由公式 np.power(x / 255.0, gamma) * 255.0 计算得出,其中 gamma 是用户提供的伽马值。为了适应OpenCV的LUT函数,代码将伽马表从浮点数类型转换为整数类型,首先使用np.round函数将浮点数转换为最接近的整数,然后通过astype(np.uint8)函数将数组转换为无符号8位整数类型。最后,使用cv2.LUT函数将输入图像的像素值与伽马表中的值进行查找和替换,实现伽马变换。

3.3 对亮度通道做伽马变换

根据Retinex理论,光照条件对物体本身的属性,如颜色、纹理等特征,并无直接影响。因此,在执行伽马变换时,应避免对图像的颜色信息进行处理,以防止颜色失真。为此,通常将图像转换至HSV色彩空间,仅对代表亮度的V通道进行伽马增强,从而实现对图像亮度的调节,同时保持原始的颜色信息不受干扰。
实现方法:

hsv_image = cv2.cvtColor(img_equ, cv2.COLOR_BGR2HSV)

# 获取V通道
v_channel = hsv_image[:, :, 2]
# 应用gamma变换
v_channel_gam = gamma_trans(v_channel, 0.3)
hsv_image[:, :, 2] = v_channel_gam
bgr_image = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2BGR)

四:整体代码实现

import numpy as np
import cv2

# 定义引导滤波函数

# 定义gamma变换函数
def gamma_trans(img, gamma):
    """
    对图像进行gamma变换处理。
    参数:
    img: 输入图像
    gamma: 伽马值
    返回:
    gamma变换后的图像
    """
    gamma_table = [np.power(x / 255.0, gamma) * 255.0 for x in range(256)]
    gamma_table = np.round(np.array(gamma_table)).astype(np.uint8)
    return cv2.LUT(img, gamma_table)

# 定义直方图均衡化函数
def hisEqulColor2(imga):
    """
    直方图均衡化处理。
    参数:
    imga: 输入图像
    返回:
    直方图均衡化后的图像
    """
    ycrcb = cv2.cvtColor(imga, cv2.COLOR_BGR2YCR_CB)
    channels = cv2.split(ycrcb)
    clahe = cv2.createCLAHE(clipLimit=1.0, tileGridSize=(1, 1))
    clahe.apply(channels[0], channels[0])
    cv2.merge(channels, ycrcb)
    cv2.cvtColor(ycrcb, cv2.COLOR_YCR_CB2BGR, imga)
    return imga

# 定义路径
path = r"D:\54.png"
# 读取图像
img = cv2.imread(path)

# 应用双边滤波
img_bil = cv2.bilateralFilter(img,5,15,15)
# 应用直方图均衡化
img_equ = hisEqulColor2(img_bil)

hsv_image = cv2.cvtColor(img_equ, cv2.COLOR_BGR2HSV)

# 获取V通道
v_channel = hsv_image[:, :, 2]
# 应用gamma变换
v_channel_gam = gamma_trans(v_channel, 0.4)
hsv_image[:, :, 2] = v_channel_gam
bgr_image = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2BGR)
# 显示结果
cv2.imshow("img_equ", bgr_image)
cv2.waitKey(0)

五,效果:

左侧为增强前,右侧为增强后
在这里插入图片描述

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

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

相关文章

Flink 常见问题汇总:反压积压,checkpoint报错,窗口计算,作业报错,无产出,流批不一致,调优等。

Flink 常见问题汇总 0 如何分析日志0.1作业内部重启异常, 作业正常运行0.2 作业内部重启, 但作业已经手动 kill 整个 yarn-application0.3 作业失败,整个 yarn application 结束运行 1 Flink 作业积压排查流程及解决思路1 反压原因2 反压的危…

Windows下搭建Telegraf+Influxdb+Grafana(详解一)

InfluxDB(时序数据库),常用使用场景:监控数据统计。 grafana,用作监控页面的前端展示。 telegraf,数据采集器。 所有的安装包都上传到网盘 链接: https://pan.baidu.com/s/1Lv6UnfueK7URx7emAatoYg 提取…

oracle 数据中lsnrctl 是干啥的

突然发现lsnrctl stop 之后,依然可以启动数据库 就感觉怪怪的,一直以为这个是数据库的守护进程,原来不是。。。。 lsnrctl 是 Oracle 监听器控制实用程序的命令行界面工具,用于管理 Oracle Net 服务监听器。监听器是 Oracle 网络…

map和set的应用

map、set 1. 序列式和关联式容器2.set和multiset2.1 构造2.2 迭代器2.3 修改 3. map和multimap3.1 map3.2. multimap 1. 序列式和关联式容器 序列式容器:比如:vector、list、deque、forward_list等,这些容器统称为序列式容器,因为…

Vue3+Echarts+饼图环形图

记得给容器宽高 <div id"leftChartguawang" style"height: 28vh"></div> 配置函数 const leftChartguawang () > {const chartBox echarts.init(document.getElementById(leftChartguawang))let datas [[{ name: 居民节能建筑, value…

SmartEDA电路仿真软件革新力作:重塑电子设计界,揭秘其爆红背后的秘密武器!

在这个日新月异的科技时代&#xff0c;每一场技术革新都是推动行业进步的强劲动力。而在电子设计领域&#xff0c;一款名为SmartEDA的电路仿真软件正以前所未有的姿态&#xff0c;颠覆传统设计模式&#xff0c;成为众多工程师和设计师争相追捧的新宠。今天&#xff0c;就让我们…

硬核详解FutureTask设计与实现

写在文章开头 最近看到一篇比较不错的FutureTask实践,于是对FutureTask源码进行了研究,而本文将从实践和源码两个角度分析FutureTask的设计与实现思路,希望对你有帮助。 Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java coder ,是 CSDN的博客专家 ,也是开源项目 …

从零开始搭建 EMQX 集群压测框架

从零开始搭建 EMQX 集群压测框架 架构 在设计以EMQX为中心的MQTT消息队列集群压力测试框架时&#xff0c;我们采用微服务架构模式。EMQX作为消息队列的核心&#xff0c;负责处理MQTT协议的消息发布和订阅。Nginx作为EMQX的反向代理&#xff0c;负责负载均衡和SSL/TLS终端。MQT…

农业上的目标跟踪论文汇总

文章目录 2022Multi-object tracking using Deep SORT and modified CenterNet in cotton seedling counting (Computers and Electronics in Agriculture)A novel apple fruit detection and counting methodology based on deep learning and trunk tracking in modern orcha…

模型部署 - docker

docker简介 Docker 是一种开源的容器化平台&#xff0c;允许开发者将应用程序及其依赖项打包到一个标准化的单元中&#xff0c;称为“容器”。这些容器可以在任何支持 Docker 的系统上运行&#xff0c;无需担心环境差异。 为什么需要 Docker&#xff1f; 在传统的开发中&…

ECharts数据可视化 数据集与事件 入门基础知识【2】

echarts一个基于 JavaScript 的开源可视化图表库。其有丰富的图表类型、强大的渲染引擎、专业多维度的数据分析、灵活配置的可视化设计。关于echarts的下载安装以及在项目中使用的基础知识我们前面已经回顾过了&#xff1a; ECharts 数据可视化 入门基本知识 下载安装常用的图表…

计数排序以及排序总结

技数排序 计数排序又称为鸽巢原理&#xff0c;是对哈希直接定址法的变形应用。 思路&#xff1a; 统计相同元素出现次数根据统计的结果将序列回收到原来的序列中 void CountSort(int* arr, int n) {//寻找最大、最小值int maxarr[0], min arr[0];for (int i 0; i < n;…

【网络】私有IP和公网IP的转换——NAT技术

目录 引言 NAT工作机制​编辑 NAT技术的优缺点 优点 缺点 个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 引言 公网被子网掩码划分为层状结构&#xff0c;一个公网IP的机器又可以用很多私有IP搭建内网。在日常生活场景中用的都是私有IP&#xff0c;例如手机&#xff0c;…

单元训练05:独立按键的基本操作

可以正常运行的&#xff1a; #include "stc15f2k60s2.h"#define LED(x) \{ \P0 x; \P2 P2 & 0x1f | 0x80; \P2 & 0x1f; \}void Timer0_Init(void) // 1毫秒12.000MHz {AUXR | 0x80; …

spring boot 发送微信小程序订阅消息

首先我们需要订阅一个消息&#xff1a; 订阅教程本文章并未提起&#xff0c;感兴趣的同学自行百度。 我们可以看到订阅消息中【消息内容】有很多参数&#xff0c;我们在发送消息时就需要将这些参数进行填充&#xff0c;当然填充的时候要注意格式&#xff0c;如果格式不对还是会…

python字符串方法,格式化字符串format,字符串的编码和解码,字符串的拼接

字符串–不可变序列 1.字符串方法 2.格式化字符串format&#xff0c;通过格式化字符串解决不同数据类型链接时候报错的问题例如用连接字符串和int就会报错 ①占位符需要注意格式print ( ’ 结果:%s %d ’ % (user_inp,ans))&#xff0c;注意需要给输出语句“”,后边需要有%。…

HarmonyOS应用开发者高级认证(一)

1、依次点击A、B、C、D四个按钮&#xff0c;其中不会触发UI刷新的是&#xff1a; 答案&#xff1a; Button("C").onClick(() > {this.nameList[0].name "Jim"})分析&#xff1a;直接更新非一级数据不会触发UI刷新 2、如果要实现Row组件内的子元素均匀…

wish怎么提升店铺流量?自养号测评防关联技术全解析

在电商领域&#xff0c;Wish作为一家知名的跨境电商平台&#xff0c;店铺流量的提升对于商家来说至关重要&#xff0c;如若店铺流量不够的话排名也会比较靠后&#xff0c;这时候卖家就需要做好相关运营政策去提升流量。 一、Wish怎么提升店铺流量&#xff1f; 1、优化商品信息…

C语言——结构体、共用体、枚举、位运算

C语言——结构体、共用体、枚举、位运算 结构体共用体枚举位运算 结构体 如果将复杂的复杂的数据类型组织成一个组合项&#xff0c;在一个组合项中包含若干个类型不同&#xff08;当然也可以相同&#xff09;的数据项。 C语言允许用户自己指定这样一种数据结构&#xff0c;它称…

Sentinel 滑动时间窗口源码分析

前言&#xff1a; Sentinel 的一个重要功能就是限流&#xff0c;对于限流来说有多种的限流算法&#xff0c;比如滑动时间窗口算法、漏桶算法、令牌桶算法等&#xff0c;Sentinel 对这几种算法都有具体的实现&#xff0c;如果我们对某一个资源设置了一个流控规则&#xff0c;并…