Numpy 如何进行图像亮度增强且不溢出

Numpy 如何进行图像亮度增强且不溢出

在图像处理中,很多时候我们需要对图像进行一些调整,比如改变图片的亮度、对比度等。这篇文章主要介绍如何使用Numpy来实现图像亮度的增强,同时又不会在图像中引入溢出的问题。

阅读更多:Numpy 教程

图像的亮度增强

图像亮度增强是指在保持图像色调不变的情况下,增大图像亮度的过程。通常有两种实现方法:直方图均衡和对比度拉伸。这里我们主要介绍对比度拉伸的实现方式。

对比度拉伸是将灰度级别分布拉伸至较大的灰度范围内,以增强图像的对比度和亮度。下面我们来看一下如何使用numpy来实现对比度拉伸。

首先,我们加载所需的库和图像,并将图像转换为灰度图像:

import cv2
import numpy as np

img = cv2.imread('test.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
Python

将灰度图像转换为numpy数组:

gray_np = np.array(gray)
Python

然后,计算像素值的最小值和最大值:

min_val = gray_np.min()
max_val = gray_np.max()
Python

根据计算出的最小值和最大值,可以使用线性变换将任意值 x 映射到 [0, 255] 的值域内,具体公式如下:

x=255maxvalminval×(xminval)x’ = \frac{255}{max_val – min_val} \times (x – min_val)

其中,xx 是原始像素值,xx’ 是变换后的像素值。使用numpy可以简化上面的计算过程:

streched = np.uint8((gray_np - min_val) * (255.0 / (max_val - min_val)))
Python

对于某些图像,可能存在一些“失真”的情况,即一些像素的值被迫限制在 0 和 255 之间,因此需要进行一个剪裁操作:

streched_clip = np.clip(streched, 0, 255)
Python

最后再将numpy数组转换为图像:

streched_img = cv2.convertScaleAbs(streched_clip)
Python

现在我们已经成功地完成了图像对比度拉伸的操作,可以使用如下的代码查看结果:

cv2.imshow('Original', img)
cv2.imshow('Streched', streched_img)
cv2.waitKey(0)
Python

如何避免溢出问题

在上面的操作中,我们手动剪裁了拉伸后的数值,这种操作显然有些缺陷和不完美,对图像产生了一定的影响。为了避免这个问题,我们可以使用更为严谨的方式来处理。

当我们拉伸图像对比度时,我们需要保证每个像素的值都能在 [0,255] 的区间内。如果我们尝试直接将线性变换后的像素值进行归一化,就会产生溢出问题。比如我们有一个像素的原始值是 230,根据上面的公式可以得到:

x=255maxvalminval×(xminval)=2552550×(2300)=230x’ = \frac{255}{max_val – min_val} \times (x – min_val) = \frac{255}{255-0}\times(230-0)=230

如果我们不做限制,直接使用上面的值,则最终处理后的像素值会变成 230,这显然不是我们想要的结果。因此,我们需要在计算线性变换后的像素值时,进行特殊处理,以保证图像不会溢出。

具体来说,我们可以根据最小值和最大值差值的大小,确定一个缩放系数,来限制像素值的范围。比如,如果最大和最小值差值小于 255,就可以将像素值乘以一个缩放系数 α\alpha,使得映射后的像素值不会超过 [0,255] 的限制。若差值大于 255,我们只需要将所有值除以该差值,并再次缩放即可避免溢出问题。

以下是实现代码:

if max_val - min_val < 256:
    alpha = 255 / (max_val - min_val)
    streched = np.uint8((gray_np - min_val) * alpha)
else:
    alpha = 255 / (max_val - min_val)
    streched = np.uint8((gray_np - min_val) / (max_val - min_val) * 255)
    streched = np.uint8(streched * alpha)
Python

上述代码首先根据最大最小值差值是否大于 255,进行了不同的处理。首先计算出一个缩放系数 α\alpha,然后根据像素值与最小值之差的乘积,乘以缩放系数,得到映射后的像素值。如果差值大于 255,则我们先进行一次归一化,将所有像素值缩放到 [0,1] 的范围内,然后再将结果乘以缩放系数 α\alpha,得到最终的映射后像素值。

最后,我们再次对映射后的像素值进行一个剪裁操作,以确保所有像素值都在 [0,255] 的范围内:

streched_clip = np.clip(streched, 0, 255)
Python

至此,我们已经实现了使用numpy进行图像亮度增强且不溢出的操作。

总结

本文主要介绍了如何使用numpy进行图像亮度增强且不溢出的操作。通过计算像素值的最小值和最大值,然后使用线性变换将像素值映射到 [0,255] 的范围内,可以实现对比度拉伸的操作。为了避免溢出的问题,我们可以根据最大最小值差值的大小,确定一个缩放系数来限制像素值的范围。该方法在实际的图像处理中应用广泛,希望能够对您的工作带来帮助。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册