用Numpy,Open-CV加強灰度圖像

做者|Kavya Musty
編譯|Flin
來源|mediumpython

咱們常常掃描紙張把它們轉換成圖像。咱們有各類各樣的工具能夠在線加強這些圖像,使它們的亮度更亮,並消除這些圖像中的陰影。若是咱們能夠手動去除陰影呢?咱們能夠將任何圖像做爲灰度圖像加載到咱們的代碼中,並在幾秒鐘內得到輸出,而無需任何應用程序的幫助。git

這能夠經過使用基本的Numpy操做和一些open CV函數來實現。爲了解釋這個過程,咱們使用了下面的圖片,它是用手機拍的。github

很明顯,有一個陰影須要刪除。讓咱們開始吧。算法

  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://medium.com/swlh/enhan...學習

歡迎關注磐創AI博客站:
http://panchuang.net/測試

sklearn機器學習中文官方文檔:
http://sklearn123.com/

歡迎關注磐創博客資源彙總站:
http://docs.panchuang.net/

相關文章
相關標籤/搜索