乐趣区

关于人工智能:用NumpyOpenCV增强灰度图像

作者 |Kavya Musty
编译 |Flin
起源 |medium

咱们常常扫描纸张把它们转换成图像。咱们有各种各样的工具能够在线加强这些图像,使它们的亮度更亮,并打消这些图像中的暗影。如果咱们能够手动去除暗影呢?咱们能够将任何图像作为灰度图像加载到咱们的代码中,并在几秒钟内取得输入,而无需任何应用程序的帮忙。

这能够通过应用根本的 Numpy 操作和一些 open CV 函数来实现。为了解释这个过程,咱们应用了上面的图片,它是用手机拍的。

很显著,有一个暗影须要删除。让咱们开始吧。

  1. 将必要的软件包导入你的环境。为了易于显示图像,咱们应用 Jupyter Notebook。
import cv2
import numpy as np
import matplotlib.pyplot as plt
  1. 删除暗影时,有两件事要留神。因为图像是灰度图像,如果图像背景较浅且对象较暗,则必须先执行最大值滤波,而后再执行最小值滤波。如果图像背景较暗且物体较亮,咱们能够先执行最小值滤波,而后再进行最大值滤波。

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

  1. 最大值滤波 :让咱们假如咱们有一个特定大小的图像 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
  1. 最小值滤波:此算法与最大值滤波完全相同,然而咱们不去找邻近的最大灰度值,而是找到了该像素四周 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
  1. 因而,如果图像的背景较浅,咱们要先执行最大值滤波,这将为咱们提供加强的背景,并将该最大值滤波后的图像传递给最小值滤波函数,该函数将负责理论的内容加强。
  2. 因而,执行最小 - 最大值滤波后,咱们取得的值不在 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
  1. 变量 N(用于过滤的窗口大小)将依据图像中粒子或内容的大小进行更改。对于测试图像,抉择大小 N = 20。加强后的最终输入图像如下所示:

输入图像是原始图像增强后的后果。所实现的代码是在 open CV 中手动实现一些库函数以加强图像的高明尝试。带有图像的整个 notebook 能够在上面的 Github 链接中找到。

  • https://github.com/kavyamusty…

原文链接:https://medium.com/swlh/enhan…

欢送关注磐创 AI 博客站:
http://panchuang.net/

sklearn 机器学习中文官网文档:
http://sklearn123.com/

欢送关注磐创博客资源汇总站:
http://docs.panchuang.net/

退出移动版