作者|Kavya Musty
編譯|Flin
來源|medium

我們經常掃描紙張把它們轉換成影像,我們有各種各樣的工具可以在線增強這些影像,使它們的亮度更亮,并消除這些影像中的陰影,如果我們可以手動去除陰影呢?我們可以將任何影像作為灰度影像加載到我們的代碼中,并在幾秒鐘內獲得輸出,而無需任何應用程式的幫助,
這可以通過使用基本的Numpy操作和一些open CV函式來實作,為了解釋這個程序,我們使用了下面的圖片,它是用手機拍的,

很明顯,有一個陰影需要洗掉,讓我們開始吧,
- 將必要的軟體包匯入你的環境,為了易于顯示影像,我們使用Jupyter Notebook,
import cv2
import numpy as np
import matplotlib.pyplot as plt
- 洗掉陰影時,有兩件事要注意,由于影像是灰度影像,如果影像背景較淺且物件較暗,則必須先執行最大值濾波,然后再執行最小值濾波,如果影像背景較暗且物體較亮,我們可以先執行最小值濾波,然后再進行最大值濾波,
那么,最大值濾波和最小值濾波到底是什么?
- 最大值濾波:讓我們假設我們有一個特定大小的影像 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
- 最小值濾波:此演算法與最大值濾波完全相同,但是我們不去找鄰近的最大灰度值,而是找到了該像素周圍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的范圍內,因此,我們必須歸一化使用背景減法獲得的最終陣列,該方法是用原始影像減去最小最大值濾波后的影像,以獲得去除了陰影的最終影像,
#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
- 變數N(用于過濾的視窗大小)將根據影像中粒子或內容的大小進行更改,對于測驗影像,選擇大小N = 20,增強后的最終輸出影像如下所示:

輸出影像是原始影像增強后的結果,所實作的代碼是在open CV中手動實作一些庫函式以增強影像的拙劣嘗試,帶有影像的整個notebook可以在下面的Github鏈接中找到,
- https://github.com/kavyamusty/Shading-removal-of-images
原文鏈接:https://medium.com/swlh/enhancing-gray-scale-images-using-numpy-open-cv-9e6234a4d10d
歡迎關注磐創AI博客站:
http://panchuang.net/
sklearn機器學習中文官方檔案:
http://sklearn123.com/
歡迎關注磐創博客資源匯總站:
http://docs.panchuang.net/
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/166812.html
標籤:其他
上一篇:復雜鏈表的復制
