返回顶部

[学习经验] CV系列之用魔法去除图像阴影

[复制链接]
dongguaziLv.1 显示全部楼层 发表于 2023-9-8 14:13:31 |阅读模式 打印 上一主题 下一主题

马上注册,享用更多功能,让你轻松玩转AIHIA梦工厂!

您需要 登录 才可以下载或查看,没有账号?立即注册

x

    大家有事为了省事,经常会拿手机去拍摄文件,如果拍摄角度没有掌握好,那么一定会被你的手机或者手挡住光线,照片上会留下许多阴影,影响图片的美观。我们如何通过使用最简单的图像处理技术去除掉图像中的阴影呢?这似乎是一个非常好玩的事。



第一步:环境中安装Numpy和OpenCV,并导入需要的Numpy和OpenCV包。
import cv2
import numpy as np
import matplotlib.pyplot as plt


第二步:如何使用最大滤波和最小滤波的组合实现阴影去除?
原理分析:删除阴影时,由于图像是灰度图像,如果图像背景较浅且对象较暗,则必须先执行最大滤波,然后再执行最小滤波;如果图像背景较暗且物体较亮,我们可以先执行最小滤波,然后再进行最大滤波。那么,最大过滤和最小过滤到底是什么?

最大滤波:
     假设我们有一定大小的图像l。我们编写的算法应该逐个遍历I的像素,并且对于每个像素 (x,y),它必须找到该像素周围的邻域 (大小为NxN的窗)中的最大灰度值,并进行写入A中相应像素位置 (x,y)的最大灰度值。所得图像A称为输入图像l的最大滤波图像。现在让我们通过代码来实现这个概念。
     (1)max filtering ()函数接受输入图像和窗口大小N。
     (2)它最初在输入数组周围创建一个“墙”(带有-1的填充),当我们遍历边缘像素时会有所帮助。
     (3)然后,我们创建一个”temp”变量,将计算出的最大值复制到其中。
     (4)然后,我们遍历该数组并围绕大小为NXN的当前像素创建一个窗口。
     (5)然后,我们使用”amax 0)“函数在该窗口中计算最大值,并将该值写入temp数组。
     (6)我们将该临时数组复制到主数组A中,并将其作为输出返回。A就是我们最大滤波后的图像。


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



最小滤波:
此算法与最大滤波完全相同,我们找出该像素周围的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



因此,我们图像的背景较浅,我们要先执行最大过滤,这将为我们提供增强的背景,并将该最大过滤后的图像传递给最小过滤功能,该功能将负责实际的内容增强。

第三步:归一化图像
执行最小-最大滤波后,我们获得的值不在0-255的范围内。因此,我们必须归一化使用背景减法获得的最终阵列,该方法是将原始图像减去最小-最大滤波图像,以获得去除阴影的最终图像。
I为原图,B为滤波后图像。我们将得到最终去除阴影的图片。

def background_subtraction(I, B):
    O = I - B
    norm_img = cv2.normalize(O, None, 0,255, norm_type=cv2.NORM_MINMAX)
    return norm_img



最终结果展示


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




AIHIA梦工厂,共建AI人脉圈,共享AI时代美好生活!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

AIHIA梦工厂旨在建立涵盖广泛人工智能行业,包括AI芯片、AI工业应用、AI电商、AI自动驾驶、AI智慧城市、智慧农业等人工智能应用领域。梦工厂为每位AI人提供技术交流、需求对接、行业资源、招聘求职、人脉拓展等多个方面交流学习平台促进人工智能的发展和应用。
  • 官方手机版

  • 联盟公众号

  • 商务合作

  • Powered by Discuz! X3.5 | Copyright © 2023, AIHIA梦工厂
  • 苏ICP备2023025400号-1 | 苏公网安备32021402002407 | 电信增值许可证:苏B2-20231396 | 无锡腾云驾数技术服务有限公司 QQ