【图像处理】使用 Python 进行图像增强

news2024/10/6 14:36:49

一、说明

        图像增强技术的深度和复杂性往往在一系列捕获和共享中被忽视。从傅里叶变换到白平衡和直方图处理,各种方法都可以将普通照片转换为引人注目的图像。这篇博文旨在解开这些技术。

        我在节日期间拍了一张照片,在夜间庆祝活动中。遗憾的是,图像中央有一束破坏性的光束。通过应用一系列增强技术,我们对消除这种光线持乐观态度,以实现更平衡和吸引人的构图。

二、傅里叶变换的魔力

        如果图像可以说一种语言,那就是数学,傅里叶变换就是语法。该数学工具将图像从空间域转换为频域。它将图像分解为正弦和余弦分量,表示图像中像素亮度变化的频率。

        为什么这很重要?好吧,许多图像增强技术,例如滤波和压缩,在频域中执行得更好。这些技术可以消除噪声,增强边缘,甚至压缩图像以实现更高效的存储和传输。完成所需的增强后,可以应用逆傅里叶变换将图像转换回空间域,使其再次可见。

        不幸的是,傅里叶变换技术对我的特定图像无效,尽管它确实证明对月球轨道这一不同的图像有益。

import numpy as np
import matplotlib.pyplot as plt
from skimage.io import imread, imshow
from skimage.color import rgb2gray

# Load and transform image
orbiter = rgb2gray(imread('lunar_orbiter.jpg'))
orbiter_fft = np.fft.fftshift(np.fft.fft2(orbiter))

orbiter_fft2 = orbiter_fft.copy()

# mask vertical component (scan lines)
orbiter_fft2[:280,orbiter_fft.shape[1]//2] = 1 
orbiter_fft2[-280:,orbiter_fft.shape[1]//2] = 1 

# Create 2 x 2 grid for plots
fig, axs = plt.subplots(2, 2, figsize=(12, 12))

# Original Image
axs[0, 0].imshow(orbiter, cmap='gray')
axs[0, 0].set_title('Original Image')
axs[0, 0].axis('off')

# Transformed Image (FFT)
axs[0, 1].imshow(np.log(abs(orbiter_fft)), cmap='gray')
axs[0, 1].set_title('Transformed Image (FFT)')
axs[0, 1].axis('off')

# FFT with Masked Vertical Component
axs[1, 0].imshow(np.log(abs(orbiter_fft2)), cmap='gray')
axs[1, 0].set_title('FFT with Masked Vertical Component')
axs[1, 0].axis('off')

# Inverse FFT of Masked Image
axs[1, 1].imshow(abs(np.fft.ifft2(orbiter_fft2)), cmap='gray')
axs[1, 1].set_title('Inverse FFT of Masked Image')
axs[1, 1].axis('off')

plt.tight_layout()
plt.show()

三、白色平衡:增强本色

        白平衡是一种有影响力的技术,能够显着改变图像的美感。这个过程的本质在于调整照片中的颜色,以便现实中的白色物品在图片中也被描绘成白色。这是一个至关重要的步骤,因为光源的颜色可能会有很大差异,从而影响照片中颜色的感知方式。

        通过确保图像中的颜色准确一致,白平衡可为照片带来更大的真实性,无论拍摄照片时的照明条件如何。大多数现代相机都配备了自动白平衡设置,但对此过程的更深入理解使摄影师能够手动进行调整以获得出色的效果。这可以显着提高照片的美学质量,使其与肉眼看到的场景更紧密地对齐。

        但是,并非所有图像都能从白平衡的使用中受益。在某些情况下,就像我拥有的特定图像一样,这些技术可能不会带来显着的增强。为了说明白平衡的力量,我将分享另一个例子,它大大提高了图像质量,展示了它的潜在有效性。

import matplotlib.pyplot as plt
import numpy as np
from skimage import util

def plot_channel_histogram(ax, image, percentile):
    for channel, color in enumerate('rgb'):
        channel_values = image[:, :, channel]
        ax.step(np.arange(256),
                np.bincount(channel_values.flatten(),
                 minlength=256) / channel_values.size,
                c=color, label=color)
        ax.axvline(np.percentile(channel_values, percentile),
                ls='--', c=color)

    ax.set_xlim(0, 255)
    ax.set_title(f'Color Channel with {percentile}th Percentile')
    ax.set_xlabel('Channel Value')
    ax.set_ylabel('Fraction of Pixels')
    ax.legend()

def apply_white_patch(image, percentile):
    # Convert and normalize the image
    wp = util.img_as_ubyte((image * 1.0 / np.percentile(image,
              percentile, axis=(0, 1))).clip(0, 1))
    
    # Create subplots
    fig, axs = plt.subplots(1, 3, figsize=(15, 5))
    
    axs[0].imshow(image)
    axs[0].set_title('Original Image')
    
    axs[1].imshow(wp)
    axs[1].set_title(f'Image with {percentile}th Percentile Normalization')
    
    plot_channel_histogram(axs[2], image, percentile)
    
    plt.show()

def main():
    percentiles = [99, 90]
    for percentile in percentiles:
        apply_white_patch(image, percentile)

四、直方图操作:平衡对比度和亮度的艺术

        直方图用作图像中色调分布的图形说明。它们提供了对图片中每个亮度水平的像素数的见解,从而帮助摄影师理解照片的曝光和对比度。

        通过利用直方图处理技术,摄影师可以大大增强最初显示对比度差的图像。这些方法使他们能够微调亮度和对比度,从而提高照片的整体质量。

        但是,请务必记住,直方图操作的有效性可能因图像而异。在我的特定情况下,即使我采用了直方图操作,该技术也没有为我的图像产生所需的增强效果。尽管如此,为了展示直方图操作的潜力,我将举一个例子,说明这种方法在提高图像质量方面非常成功。

from skimage import color, exposure
import numpy as np
import matplotlib.pyplot as plt


# Original image
image = dark_image.copy()

# Convert the image to grayscale
gray_image = color.rgb2gray(image)

# Compute the histogram and cumulative distribution function
# (CDF) of the gray image
hist, bin_centers = exposure.histogram(gray_image)
cdf = np.cumsum(hist) / np.sum(hist)

# Split the color image into separate RGB channels
red_channel = image[:, :, 0]
green_channel = image[:, :, 1]
blue_channel = image[:, :, 2]

# Compute color multipliers from CDF for each channel
multipliers = 0.5 + 0.5 * np.concatenate([cdf]*3)
red_mult = multipliers[0]
green_mult = multipliers[1]
blue_mult = multipliers[2]

# Apply global histogram equalization to each channel
red_eq = exposure.equalize_hist(red_channel)
green_eq = exposure.equalize_hist(green_channel)
blue_eq = exposure.equalize_hist(blue_channel)

# Adjust channels by corresponding multipliers
red_final = red_eq * red_mult
green_final = green_eq * green_mult
blue_final = blue_eq * blue_mult

# Recombine the channels into a color image
adjusted_image = np.stack((red_final, green_final, blue_final), axis=-1)

# Create a 4x2 subplot for original and adjusted channels and images
fig, axs = plt.subplots(4, 2, figsize=(10, 20))

channels = [
    ('Red', red_channel, red_eq), 
    ('Green', green_channel, green_eq),
    ('Blue', blue_channel, blue_eq)
]

for i, (color_name, original, adjusted) in enumerate(channels):
    axs[i, 0].set_title(f'Original {color_name} Channel')
    axs[i, 0].imshow(original, cmap=f'{color_name}s')
    axs[i, 1].set_title(f'Adjusted {color_name} Channel')
    axs[i, 1].imshow(adjusted, cmap=f'{color_name}s')

# Plot the original and final combined images
axs[3, 0].set_title('Original Image')
axs[3, 0].imshow(image)
axs[3, 1].set_title('Adjusted Image')
axs[3, 1].imshow(adjusted_image)

# Show the subplots
plt.show()

五、结论

        图像增强技术,包括傅里叶变换、白平衡和直方图操作,是可以将摄影提升到新高度的强大工具。这些技术中的每一种都有其独特的优势和应用,使图像增强成为一个迷人但复杂的过程。例如,我在圣诞节假期拍摄的一张照片具有破坏性的光线,这些技术都无法单独消除。这凸显了图像增强的复杂性和对定制方法的需求。

        对这些技术的实验揭示了它们各自的潜力。虽然傅里叶变换和白平衡没有为我的圣诞图像提供预期的结果,但它们在增强其他照片方面发挥了重要作用。同样,直方图操作并没有显着改善我的图像,但对另一张图像非常有效。这种经验强调了了解这些方法的独特功能并知道何时应用每种方法的重要性。

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

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

相关文章

OpenCV中掩膜(Mask)、setTo()、copyTo()、clone()、inRange()的定义与使用

文章目录 1、掩膜(Mask)是什么(1)从物理的角度来看:(2)图像处理中的掩膜Mask(3)掩膜的用法:(4)掩膜Mask 的运算: 2、setTo()函数:将图…

【动手学习深度学习--逐行代码解析合集】17使用块的网络(VGG)

【动手学习深度学习】逐行代码解析合集 17使用块的网络(VGG) 视频链接:动手学习深度学习–使用块的网络(VGG) 课程主页:https://courses.d2l.ai/zh-v2/ 教材:https://zh-v2.d2l.ai/ 1、VGG网络…

【UniApp开发小程序】顶部导航栏和底部导航栏设置+iconfont图标引入

文章目录 顶部导航栏和底部导航栏设置创建几个需要底部导航栏切换的页面使用阿里巴巴矢量图标库完成底部导航栏tabBar设置页面顶部导航栏标题 样式优化 顶部导航栏和底部导航栏设置 在正式开发小程序的功能之前,首先需要确定小程序的主要框架。 创建几个需要底部导…

组件的创建,引用,样式隔离以及methods,data,properties和数据事件监听

组件的创建,引用,样式隔离以及methods,data,properties和数据事件监听 1. 组件的创建2. 组件的引用2.1. 局部引用2.2. 全局引用2.3. 组件和页面的区别 3. 组件的样式隔离3.1. 默认情况,组件样式隔离性3.2. 修改组件的样式隔离选项 4. 组件的d…

短视频抖音seo矩阵系统源码开发者思路(一)

一套优秀的短视频获客系统,支持短视频智能剪辑、短视频定时发布,短视频排名查询及优化,短视频智能客服等,那么短视频seo系统具体开发应该具备哪些功能呢?今天小编就跟大家分享一下我们的技术开发思路。 抖音矩阵系统源…

go-zero微服务实战——etcd服务注册与发现

etcd简介 浅谈etcd服务注册与发现 etcd官网 etcd中文文档 apt安装etcd,启动命令十分简单etcd。 etcd分为v2版本和v3版本,命令有所不一样,使用命令etcdctl h查看 如上图所示并没有出现API的版本,此时是使用默认的v2版本&#x…

android editText获取不到数据

问题分析:在onActivityCreated一开始就创建了findViewById,这时获取的是默认值,需要在点击按钮时重新加载才能获取到输入数据。 需要在点击按钮时重新加载数据:

Android Studio中java编程时禁止生成警告

1、打开Android Studio,进入主界面 2、进入软件后,点击菜单栏的File 3、在File选项中选择Settings 4、进入Settings选择Version Control -> Subversion -> Presentation 5、去掉勾选 Show merge source in history and anotations 6、最后点击确定…

在vite创建的vue3项目中使用Cesium加载czml路径信息和无人机模型

在vite创建的vue3项目中使用Cesium加载czml路径信息和无人机模型 用到的区域文件、地图标记文件、路径信息文件、模型文件 提取码:99jq 使用vite创建vue3项目 npm create vitelatestcd到创建的项目文件夹中 npm install安装Cesium npm i cesium vite-plugin-cesium…

一文详解常见标准化组织

从事软件研发工作多年,在工作中有时会查阅一些通信相关的国际标准。然而,对于制定这些标准的组织,一直缺乏一个系统的了解。本文将对几个常见的标准化组织进行介绍,其中包括ITU、3GPP、GSMA和CCSA,了解它们的背景、成立…

零基础学习C#编程的步骤和建议

如果你是零基础,希望学习C#编程语言,以下是一些建议的学习步骤: 基础概念和语法:开始学习C#之前,了解基本的编程概念和语法是很重要的。可以通过在线教程、编程书籍或视频教程来学习C#的基础知识,包括变量…

JVM中类加载的过程

文章目录 一、类加载是什么二、类加载过程1.加载2.验证3.准备4.解析5.初始化 三、什么时候进行类加载四、双亲委派模型1.三大类加载器2.加载过程 总 一、类加载是什么 把.class文件加载到内存中,得到类对象的过程。 二、类加载过程 1.加载 找到.class文件&#xff…

数据预处理matlab

matlab数据的获取、预处理、统计、可视化、降维 数据的预处理 - MATLAB & Simulink - MathWorks 中国https://ww2.mathworks.cn/help/matlab/preprocessing-data.html 一、数据的获取 1.1 从Excel中获取 使用readtable() 例1: 使用spreadsheetImportOption…

给大家推荐几款好用的格式转换工具

在数字化时代,我们经常需要处理各种不同的文件格式。有时我们可能需要将视频转换为适用于特定设备的格式,有时又需要将音频文件转换为可编辑的格式,或者将文档转换为更通用的类型。这就是格式转换工具的重要性所在。然而,在众多的…

纯css3实现小鸡从鸡蛋破壳而出动画特效

实现一个使用纯css3实现小鸡破壳的效果 示例效果如下所示 示例代码 <template><div><div class"eggWrapper"><div class"chickHead"><div class"eyeDiv"></div><div class"eyeDiv"></di…

一文详解 Okio 输入输出流

在 OkHttp 的源码中&#xff0c;我们经常能看到 Okio 的身影&#xff0c;这篇文章&#xff0c;我们把Okio拿出来进行一个详细的介绍学习。 输入输出的概念简述Okio 简介工程中引入 OkioAPI 简介及使用介绍 一、输入输出 在正式介绍 Okio 之前&#xff0c;让我们先回忆一下输…

STM32自学笔记14-步进电机驱动项目-TB67H450驱动

目前的项目是一种2相4线步进电机的闭环驱动电路&#xff0c;使用的电机驱动芯片是TB67H450&#xff0c;再使用磁编码器MT6816&#xff0c;使用FOC算法&#xff0c;基于STM32F1单片机。 这一节是步进电机的驱动芯片驱动研究 首先研究驱动芯片TB67H450的datasheet 这是一个PWM斩…

11_SPI_Flash 读数据实验

11_SPI_Flash 读数据实验 1. 实验目标2. 操作时序2.1 数据读操作指令2.2 数据读操作时序 3. 流程框图3.1 顶层模块3.2 数据读模块 4. 波形图绘制5. RTL5.1 flash_read_ctrl5.2 spi_flash_read 6. testbench 1. 实验目标 使用页写或连续写操作向 Flash 芯片写入数据&#xff0c…

火山引擎 DataLeap 构建Data Catalog系统的实践(三):关键技术与总结

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 关键技术 构建一个好的Data Catalog系统&#xff0c;需要考虑的核心产品设计和技术设计有很多。篇幅所限&#xff0c;本文只概要介绍技术设计中最核心重要的部分&a…

工作日志2 input 的事件优先级 字符串.trim() this.$set()的应用 获取jq的自定义属性

input 的事件优先级 1.input输入框的事件 字符串.trim() 除去前后空格的方法 undefind不可以使用 this.$set()的应用