OpenCV如何去除圖片中的陰影的實現
一、前言
如果你自己打印過東西,應該有過這種經歷。如果用自己拍的圖片,在手機上看感覺還是清晰可見,但是一打印出來就是漆黑一片。比如下面這兩張圖片:
因為左邊的圖片有大片陰影,所有打印出來的圖片不堪入目(因為打印要3毛錢,所以第二張圖片隻是我用程序模擬的效果)。
那有什麼辦法可以解決嗎?答案是肯定的,今天我們就來探討幾個去除陰影的方法。
二、如何去除陰影?
首先為瞭方便處理,我們通常會對圖片進行灰度轉換(即將圖片轉換成隻有一個圖層的灰色圖像)。
然後我們分析一下,在上面的圖片中有三個主色調,分別是字體顏色(黑色)、紙張顏色(偏白)、陰影顏色(灰色)。知道這點後我們就好辦瞭。我們隻需要把灰色和白色部分都處理為白色就好瞭。
那要我怎麼才知道白色和灰色區域呢?對於一個8位的灰度圖,黑色部分的像素大致在0-30左右。白色和灰色應該在31-255左右(這個范圍隻是大致估計,實際情況需要看圖片)。如圖:
左邊是原圖,右邊是處理後的圖片。我們將灰色和接近白色的部分都處理成瞭白色。
那下面我們就開始處理吧。
三、numpy的ndarray數組
可能有些讀者沒有接觸過numpy,這裡簡單說一下。
numpy是一個第三方的模塊,用它我們可以很方便的處理多維數組(ndarray數組)。而圖片在OpenCV中的存儲方式正好是ndarray,所以我們對數組的操作就是對圖片的操作。
在使用之前我們需要安裝一下OpenCV模塊:
pip install opencv-python
在安裝OpenCV時會自動安裝numpy。
下面我們主要是看看佈爾索引的操作,先看下面代碼:
import numpy as np # 創建一個元素為1, 0, 1, 1的ndarray數組 arr = np.array([1, 0, 1, 1]) # 判斷數組中有沒有0 res = arr == 0 # 將數組中為0的元素賦值為10 arr[res] = 10
如果沒有接觸過numpy會不太理解上面的語法。我們來詳細說一下:
創建ndarray數組:我們通過np.array可以將現有的列表裝換成一個ndarray對象,這個很好理解
判斷數組中有沒有0:我們可以直接用ndarray對象來判斷,比如:arr == 0,他會返回一個元素結構和數量一樣的ndarray對象。但是返回的對象原始類型式bool,我們來看看res的輸出:
[False True False False]
從結果可以看出,我們比較arr==0就是對數組中每個元素進行比較,並返回比較的佈爾值。
將數組中為0的元素賦值為10:而最難理解的arr[res]操作。它其實就是拿到res中為True的視圖,比如上面的結果是第二個為True則隻會返回第二個元素的視圖。我們執行下面的代碼:
arr[res] = 10
就是把對應res為True的部分賦值為10,也就是將arr中值為0的部分賦值為10。
下面是arr最後的結果:
[ 1 10 1 1]
可以看到原本的0處理為瞭1。
四、去除陰影
現在我們知道瞭佈爾索引,我們可以對圖片進行處理瞭。我們隻需要讀取圖片,然後將像素值大於30的部分處理為白色就好瞭。下面是我們的代碼:
import cv2 # 讀取圖片 img = cv2.imread('page.jpg', 0) # 將像素值大於30的部分修改為255(白色) img[img > 30] = 255 # 保存修改後的圖片 cv2.imwrite('res.jpg', img)
上面的代碼非常簡單,我們使用cv2.imread函數讀取圖片,第一個參數是圖片路徑,第二個參數表示讀取為灰度圖。我們來看看效果圖:
可以看到陰影部分被很好地去除瞭。有些字比較模糊,我們可以通過調節灰白色地范圍調整。比如:
img[img > 40] = 255
具體的值就要根據要處理的圖片來決定瞭。
五、改進
對於上面地處理,還可以做一個小小地改進。我們可以讓紙張顏色不那麼白,我們來看改進後的代碼:
import cv2 import numpy as np img = cv2.imread('page.jpg', 0) # 計算灰白色部分像素的均值 pixel = int(np.mean(img[img > 140])) # 把灰白色部分修改為與背景接近的顏色 img[img > 30] = pixel cv2.imwrite('res.jpg', img)
在上面的代碼中我們不再是將灰白色部分設置為255,而是事先計算瞭一個數值。
pixel = int(np.mean(img[img > 140]))
猜測陰影部分的顏色值小於140,因此先索引出圖像中大於140的部分。然後求平均值,這樣我們算出來的大致就是原圖的背景顏色,然後將圖片不是文字的部分處理為背景顏色,就是最終結果瞭。下面是我們的效果圖:
可以看到這次效果要更好瞭。但是因為背景都是一個顏色,所以看起來還是會有一些差別。
不過有一點需要說一下,上面的操作隻適用於比較簡單的圖片,比如試卷這種。
到此這篇關於OpenCV如何去除圖片中的陰影的實現的文章就介紹到這瞭,更多相關OpenCV 去除圖片陰影內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- None Found