2011-01-08 47 views
12

我通常的100%對比度調整方法和一些調整亮度以調整截止點的方法通常可以很好地清理小子電路的照片或E & R.SE上發表的公式,但有時候它並不是那麼棒,像這樣的圖像:我應該使用哪些處理步驟來清理線條圖的照片?

alt text

什麼其他的方法除了對比度(或代替),我可以用它來給我一個更穩定的輸出?我期待着一個相當普遍的答案,但我可能會使用ImageMagick和/或PIL(Python)將它實現在一個腳本中(我可以將文件轉儲到其中),所以如果你有任何特定的東西,將受到歡迎。

理想情況下,一個更好的源圖像會很好,但我偶爾會在其他人的圖像上使用它來添加一些波蘭語。

+1

怎麼樣的顏色?我對圖像處理並不熟悉,但似乎如果您刪除了一定範圍內的藍色,網格將被刪除。 – Mehrdad 2011-01-08 03:45:56

回答

15

第一步是在考慮到白平衡問題的同時均衡圖像中的照明差異。這裏的理論是,有限區域內最明亮的圖像部分代表白色。通過事先模糊圖像,我們消除了圖像中噪聲的影響。

from PIL import Image 
from PIL import ImageFilter 
im = Image.open(r'c:\temp\temp.png') 
white = im.filter(ImageFilter.BLUR).filter(ImageFilter.MaxFilter(15)) 

alt text 下一步是從RGB輸入創建的灰度圖像。通過縮放到白點我們糾正白平衡問題。通過取R,G,B的最大值,我們不再強調任何不是純灰色的顏色,例如網格的藍線。這裏介紹的第一行代碼是虛擬的,用於創建正確大小和格式的圖像。

grey = im.convert('L') 
width,height = im.size 
impix = im.load() 
whitepix = white.load() 
greypix = grey.load() 
for y in range(height): 
    for x in range(width): 
     greypix[x,y] = min(255, max(255 * impix[x,y][0]/whitepix[x,y][0], 255 * impix[x,y][2]/whitepix[x,y][3], 255 * impix[x,y][4]/whitepix[x,y][5])) 

這些操作的結果是具有大多一致的值,並且可以通過簡單的閾值被轉換成黑白圖像。 alt text


編輯:很高興看到一個小的競爭。 nikie已經提出了非常類似的方法,使用減法而不是縮放來消除白電平的變化。我的方法增加了照明不足的地區的對比度,而nikie的方法則不會 - 您選擇哪種方法將取決於您希望保留的照明不足區域是否有信息。

我試圖重現這種做法導致了這一點:

for y in range(height): 
    for x in range(width): 
     greypix[x,y] = min(255, max(255 + impix[x,y][0] - whitepix[x,y][0], 255 + impix[x,y][7] - whitepix[x,y][8], 255 + impix[x,y][9] - whitepix[x,y][10])) 

alt text

我對技術的組合合作,提供一個更好的結果,但它尚未完全就緒。

+0

只是來自「競爭」的評論:您的建議和我的主要區別在於,您使用了一個(高斯?)模糊濾鏡,然後是最大濾鏡(=擴展)。礦山使用形態開放,大規模梯度幾乎不變。問題是,PIL不包含形態過濾器(或者我沒有找到它們)。 – Niki 2011-01-10 15:53:03

3

detecting edges怎麼樣?這應該拿起線條圖。

這裏的Sobel邊緣檢測的圖像上的結果:

alt text

如果再閾值圖像(使用經驗確定的閾值,或者Ohtsu method),可以清理使用morphological operations圖像(如擴張和侵蝕)。這將幫助你擺脫破碎/雙重線。

正如Lambert指出的那樣,如果您不希望結果中出現網格線,您可以使用藍色通道預處理圖像以擺脫網格線。

如果您在對圖像進行圖像處理之前均勻地照亮頁面(或者只是使用掃描儀),那麼您也將獲得更好的效果,因此您不必擔心全局與本地閾值之間的差異。

15

去除不同背景照明的一種常見方法是從圖像中計算出「白色圖像」,圖像爲opening

在此示例八度代碼,我使用的圖像的藍色通道,因爲在背景中的線是在該信道(EDITED至少突出:使用圓形結構元素產生更少的視覺僞像不是一個簡單的箱):

src = imread('lines.png'); 
blue = src(:,:,3); 
mask = fspecial("disk",10); 
opened = imerode(imdilate(blue,mask),mask); 

結果:

background_subtracted = opened-blue; 
012: opened

然後從源圖像中減去該

background_subtracted (對比度增強版)

最後,我只是用二值化固定閾值的圖像:

binary = background_subtracted < 35; 

binary

相關問題