opencv 增强 java_使用Numpy+OpenCV来增强灰度图像

本文介绍了一种使用Numpy和OpenCV手动去除灰度图像中阴影的方法。通过最大值和最小值滤波,结合背景减法规则,可以有效地增强图像并消除阴影。详细步骤包括最大值滤波、最小值滤波以及归一化的背景减法操作。提供的代码示例展示了如何实现这一过程。
摘要由CSDN通过智能技术生成

d3f836b68d1a256ad9ddc57776cbeefb.png

在日常生活中,我们经常会扫描纸张把它们转换成图像,但这些图像往往存在阴影,我们有各种各样的工具可以在线增强这些图像,使它们的亮度更亮,并消除这些图像中的阴影。那有没有方法可以手动去除阴影呢?比如我们可以将任何图像作为灰度图像加载到我们的代码中,并在几秒钟内获得输出,而无需任何应用程序的帮助。

这是可以通过使用基本的Numpy操作和一些openCV函数来实现。我们使用了下面的图片作为例子,它是用手机拍的。

384b865b8b4e6bed8709ab05809cd898.png

很明显,它有一个阴影需要删除。

将必要的软件包导入你的环境。为了易于显示图像,我们使用Jupyter Notebook。

import cv2

import numpy as np

import matplotlib.pyplot as plt

删除阴影时,有两件事要注意。(1)由于图像是灰度图像,如果图像背景较浅且对象较暗,则必须先执行最大值滤波,然后再执行最小值滤波;(2)如果图像背景较暗且物体较亮,我们可以先执行最小值滤波,然后再进行最大值滤波。

那么,最大值滤波和最小值滤波到底是什么呢?

3.最大值滤波:假设我们有一个特定大小的图像 I ,我们编写的算法应逐个遍历 I 的像素,并且对于每个像素(x,y)都必须找到该像素周围的邻域(大小为N x N的窗口)中的最大灰度值,并将该最大灰度值写入A中相应的像素位置(x,y),所得图像 A 称为输入图像 I 的最大值滤波图像。

让我们在代码中实现这个过程。

max_filtering()函数接受输入图像和窗口大小N。

它最初在输入数组周围创建一个“wall”(带有-1的填充),当我们遍历边缘像素时会使用这个数据。

然后,我们创建一个“ temp”变量,将计算出的最大值复制到该变量中。

然后,我们遍历数组,并围绕当前像素大小N x N创建一个窗口。

然后,我们使用“ amax()”函数在该窗口中计算最大值,并将该值写入temp数组。

我们将该临时数组复制到主数组A中,并将其作为输出返回。

A是输入I的最大值滤波图像。

def max_filtering(N, I_temp):

wall = np.full((I_temp.shape[0]+(N//2)*2, I_temp.shape[1]+(N//2)*2), -1)

wall[(N//2):wall.shape[0]-(N//2), (N//2):wall.shape[1]-(N//2)] = I_temp.copy()

temp = np.full((I_temp.shape[0]+(N//2)*2, I_temp.shape[1]+(N//2)*2), -1)

for y in range(0,wall.shape[0]):

for x in range(0,wall.shape[1]):

if wall[y,x]!=-1:

window = wall[y-(N//2):y+(N//2)+1,x-(N//2):x+(N//2)+1]

num = np.amax(window)

temp[y,x] = num

A = temp[(N//2):wall.shape[0]-(N//2), (N//2):wall.shape[1]-(N//2)].copy()

return A

4.最小值滤波:此算法与最大值滤波完全相同,区别在于我们不再去找邻近的最大灰度值,而是找该像素周围N x N邻近的最小值,并将该最小灰度值写入B中的(x,y),所得的图像 B 称为图像 I 的经过最小值滤波的图像。

让我们对该过程进行编码。

def min_filtering(N, A):

wall_min = np.full((A.shape[0]+(N//2)*2, A.shape[1]+(N//2)*2), 300)

wall_min[(N//2):wall_min.shape[0]-(N//2), (N//2):wall_min.shape[1]-(N//2)] = A.copy()

temp_min = np.full((A.shape[0]+(N//2)*2, A.shape[1]+(N//2)*2), 300)

for y in range(0,wall_min.shape[0]):

for x in range(0,wall_min.shape[1]):

if wall_min[y,x]!=300:

window_min = wall_min[y-(N//2):y+(N//2)+1,x-(N//2):x+(N//2)+1]

num_min = np.amin(window_min)

temp_min[y,x] = num_min

B = temp_min[(N//2):wall_min.shape[0]-(N//2), (N//2):wall_min.shape[1]-(N//2)].copy()

return B

5.因此,如果图像的背景较浅,我们要先执行最大值滤波,这会为我们提供增强的背景,并将该最大值滤波后的图像传递给最小值滤波函数,该函数将负责实际的内容增强。

6.执行最小-最大值滤波后,我们获得的值不在0-255的范围内,所以我们必须归一化使用背景减法获得的最终阵列,该方法是用原始图像减去最小最大值滤波后的图像,以获得去除了阴影的最终图像。

#B is the filtered image and I is the original image

def background_subtraction(I, B):

O = I - B

norm_img = cv2.normalize(O, None, 0,255, norm_type=cv2.NORM_MINMAX)

return norm_img

7.变量N(用于过滤的窗口大小)将根据图像中粒子或内容的大小进行更改。对于测试图像,选择大小N = 20。增强后的最终输出图像如下所示:

4e16110280a3a56a9548bb06a93a3ad7.png

输出图像是原始图像增强后的结果,所实现的代码是在openCV中手动实现一些库函数以增强图像的拙劣尝试,带有图像的整个notebook可以在下面的Github链接中找到。

https://github.com/kavyamusty/Shading-removal-of-images

参考链接:https://medium.com/swlh/enhancing-gray-scale-images-using-numpy-open-cv-9e6234a4d10d

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值