若是你本身打印過東西,應該有過這種經歷。若是用本身拍的圖片,在手機上看感受仍是清晰可見,可是一打印出來就是漆黑一片。好比下面這兩張圖片:python
由於左邊的圖片有大片陰影,全部打印出來的圖片不堪入目(由於打印要3毛錢,因此第二張圖片只是我用程序模擬的效果)。數組
那有什麼辦法能夠解決嗎?答案是確定的,今天咱們就來探討幾個去除陰影的方法。markdown
首先爲了方便處理,咱們一般會對圖片進行灰度轉換(即將圖片轉換成只有一個圖層的灰色圖像)。函數
而後咱們分析一下,在上面的圖片中有三個主色調,分別是字體顏色(黑色)、紙張顏色(偏白)、陰影顏色(灰色)。知道這點後咱們就好辦了。咱們只須要把灰色和白色部分都處理爲白色就行了。字體
那要我怎麼才知道白色和灰色區域呢?對於一個8位的灰度圖,黑色部分的像素大體在0-30左右。白色和灰色應該在31-255左右(這個範圍只是大體估計,實際狀況須要看圖片)。如圖:ui
左邊是原圖,右邊是處理後的圖片。咱們將灰色和接近白色的部分都處理成了白色。spa
那下面咱們就開始處理吧。3d
可能有些讀者沒有接觸過numpy,這裏簡單說一下。code
numpy是一個第三方的模塊,用它咱們能夠很方便的處理多維數組(ndarray數組)。而圖片在OpenCV中的存儲方式正好是ndarray,因此咱們對數組的操做就是對圖片的操做。orm
在使用以前咱們須要安裝一下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的部分。而後求平均值,這樣咱們算出來的大體就是原圖的背景顏色,而後將圖片不是文字的部分處理爲背景顏色,就是最終結果了。下面是咱們的效果圖:
能夠看到此次效果要更好了。可是由於背景都是一個顏色,因此看起來仍是會有一些差異。
不過有一點須要說一下,上面的操做只適用於比較簡單的圖片,好比試卷這種。
今天的內容就到這裏了,感謝閱讀。感興趣的讀者能夠關注個人我的公衆號「新建文件夾X」。