基于OpenCV的图像阴影去除

重磅干货,第一时间送达

我们经常需要通过扫描将纸上的全部内容转换为图像。有很多在线工具可以提高图像的亮度,或者消除图像中的阴影。但是我们可以手动删除阴影吗?当然可以,我们只需要将图像加载到相应的代码中,无需任何应用程序即可在几秒钟内获得输出。这个代码可以通过Numpy和OpenCV基本函数来实现。为了说明该过程,使用了以下图像进行操作。

Test_image

1.图像中有一个非常明显的阴影需要删除。首先当然是将必要的软件包导入环境。

import cv2import numpy as npimport matplotlib.pyplot as plt

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

那么,最大过滤和最小过滤到底是什么?

3.最大滤波:让我们假设我们有一定大小的图像I。我们编写的算法应该逐个遍历I的像素,并且对于每个像素(x,y),它必须找到该像素周围的邻域(大小为N x N的窗口)中的最大灰度值,并进行写入A中相应像素位置(x,y)的最大灰度值。所得图像A称为输入图像I的最大滤波图像。现在让我们通过代码来实现这个概念。

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

  • 它最初在输入数组周围创建一个“墙”(带有-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 imagedef 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。增强后的最终输出图像如下所示:

Test_image_output

输出图像相较于原始图像已经没有任何的阴影啦。

代码链接:https://github.com/kavyamusty/Shading-removal-of-images

交流群

(0)

相关推荐

  • python+opencv图像处理(四十二)

    Kirsch算子 1.Kirsch算子 Kirsch算子是R.Kirsch提出来一种边缘检测新算法,它采用8个模板对图像上的每一个像素点进行卷积求导数,这8个模板代表8个方向,对图像上的8个特定边缘方 ...

  • python 中 numpy array 中的维度

    简介 numpy 创建的数组都有一个shape属性,它是一个元组,返回各个维度的维数.有时候我们可能需要知道某一维的特定维数. 二维情况 >>> import numpy as np ...

  • 基于Opencv的图像单应性转换实战

    重磅干货,第一时间送达 同形转换 我们所常见的都是以这样的方式来处理图像:检测斑点,分割感兴趣的对象等.我们如何将它们从一种形式转换为另一种形式来处理这些图像呢?通过单应矩阵快速转换图像可以实现这个需 ...

  • 基于OpenCV的图像翻转和镜像

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本期,我们将解释如何在Python中实现图像的镜像或翻转.大家只需 ...

  • 基于OpenCV的图像强度操作

    重磅干货,第一时间送达 01. 什么是图像强度操作 更改任何通道中的像素值 对图像的数学运算 亮度变化 对比度变化 伽玛操纵 直方图均衡 图像预处理中的滤波等增强 使用OpenCV加载图像 impor ...

  • 基于OpenCV的图像融合

    重磅干货,第一时间送达 本期我们将一起学习如何使用OpenCV的进行图像拼接. 01. 目录 python 入门 步骤1 -图像导入 步骤2-调整图像大小 步骤3-融合图像 步骤4-导出结果 02. ...

  • 基于OpenCV的图像卡通化

    重磅干货,第一时间送达 本期将创建一个类似于Adobe Lightroom的Web应用程序,使用OpenCV和Streamlit实现图像的卡通化 作为一个狂热的街头摄影爱好者,几乎每个周末都要在城市中 ...

  • 基于OpenCV实战:绘制图像轮廓(附代码)

    重磅干货,第一时间送达 山区和地形图中海拔高的区域划出的线称为地形轮廓,它们提供了地形的高程图.这些线条可以手动绘制,也可以由计算机生成.在本文中,我们将看到如何使用OpenCV在简单图像上绘制轮廓线 ...

  • 如何使用OpenCV实现图像均衡???

    重磅干货,第一时间送达 我们已经练习了很多图像处理--操作图像(精确地说是图像矩阵).为此,我们探索了图像的均衡方法,以便在一定程度上增强对比度,以使被处理的图像看起来比原始图像更好,这种技术称为直方 ...

  • 基于OpenCV实战:车牌检测

    重磅干货,第一时间送达 拥有思维导图或流程将引导我们朝着探索和寻找实现目标的正确道路的方向发展.如果要给我一张图片,我们如何找到车牌并提取文字? 一般思维步骤: 识别输入数据是图像. 扫描图像以查看由 ...

  • 基于OpenCV实战的图像处理:色度分割

    重磅干货,第一时间送达 通过HSV色阶使用彩色图像可以分割来分割图像中的对象,但这并不是分割图像的唯一方法.为什么大多数人偏爱色度而不是RGB / HSV分割? 可以获得RGB / HSV通道之间的比 ...