讓我介紹壹下我們的工具:
1.pytsesser它是壹個基於C語言的名為tesser的識別工具的python包。可惜它笨,只會做最簡單的識別,不認識漢字。
2.要求它是我們喜歡寫爬行動物的孩子的最愛。它提供了壹個用戶友好的界面,代價是損失了壹點效率(寫python的時候不要考慮效率)。
3.BeautifulSoup It和Requests是壹對好的機油,讓提取文檔中需要的內容成為壹件簡單的事情。
4.PIL是今天的主角。PIL是壹個專門用於圖像處理的庫,非常好,功能強大。熟練的人甚至可以用它來畫圖。
如何寫壹個爬蟲實現模擬登錄,這裏就不細說了。先說驗證碼識別怎麽解決。
解決方案如下:
1.首先,使用PIL增強圖像,因為原始圖像中的數字邊緣和背景中的噪聲不太清晰。在增強之後,它們可以被分離。如果不分開,去噪時可能會遺漏壹些數字。
im = image . open(" random image/random image 11 . jpg ")
Im =圖像增強。銳度(IM)。增強(3)參數為3,是實驗後的理想值。太強不好,太弱也不好。
2.預處理後,去除背景噪聲。背景噪聲是指背景中的各種色塊,肉眼可能註意不到。但是,它的存在會影響識別。我最初的做法是把圖像只轉換成黑白,這樣自然就把噪點轉換成了噪點。
效果如圖
但我希望擺脫噪音,變成這樣。
首先想到的是種子染色。什麽是種子染色?請看這個鏈接。
為了防止壞鏈,這裏做壹些轉載。
種子染色法的英文名是Flood Fill,但其實Flood Fill這個名字更貼切,因為它作用於壹個圖的節點時,會“淹沒”與之相連的其他節點,並以同樣的方式向外擴散。這種方法通常用於計算壹個圖的最大連通子圖(這裏的“圖”是圖論的概念)。想象壹個無向圖。我們從這個圖中的壹個無標簽(有標簽)的節點開始,給這個節點和從這個節點可以到達的所有節點分配相同的標簽(用相同的顏色染色)。然後我們得到壹個由這些標記節點組成的極大連通子圖。我們可以通過搜索下壹個未標記節點並重復上述過程來找到所有的最大連通子圖。“著色”的過程可以通過DFS或BFS來實現。如果節點數為V,邊數為E,由於我們在洪水填充過程中對每個節點“訪問”兩次,對每個邊“訪問”兩次,得到所有最大連通子圖的時間復雜度為o(V+E)。
維基百科的壹個例子:
假設每個白色方塊是圖中的壹個節點,相鄰的方塊(上、下、左、右)通過邊相連,那麽這個圖有三個最大連通子圖,演示了Flood Fill尋找其中壹個最大連通子圖的過程。
本文采用種子染色法計算每個塊的面積,然後將小塊作為噪聲去除。
這是代碼
定義檢查(j,I):
嘗試:
if pix
s =
如果pix[j,i] == 0:
如果檢查(j-1,I):
r[0],r[1],r[2] = im2.getpixel((j,I))
s[0],s[1],s[2] = im2.getpixel((j-1,I))
打印r
打印s
打印“-”* 55
如果juli(r,s)& lt;=l:
矩陣[j][i] =矩陣[j-1][i]
maps[str(matrix[j][I])]+= 1
elif檢查(j-1,i-1):
r[0],r[1],r[2] = im2.getpixel((j,I))
s[0],s[1],s[2] = im2.getpixel((j-1,i-1))
如果juli(r,s)& lt;=l:
矩陣[j][i] =矩陣[j-1][i-1]
maps[str(matrix[j][I])]+= 1
elif檢查(j,i-1):
r[0],r[1],r[2] = im2.getpixel((j,I))
s[0],s[1],s[2] = im2.getpixel((j-1,I))
如果juli(r,s)& lt;=l:
矩陣[j][i] =矩陣[j][i-1]
maps[str(matrix[j][I])]+= 1
elif檢查(j+1,i+1):
r[0],r[1],r[2] = im2.getpixel((j,I))
s[0],s[1],s[2] = im2.getpixel((j+1,i+1))
如果juli(r,s)& lt;=l:
matrix[j][I]= matrix[j+1][I+1]
maps[str(matrix[j][I])]+= 1
elif檢查(j,i+1):
r[0],r[1],r[2] = im2.getpixel((j,I))
s[0],s[1],s[2] = im2.getpixel((j,i+1))
如果juli(r,s)& lt;=l:
matrix[j][I]= matrix[j][I+1]
maps[str(matrix[j][I])]+= 1
elif檢查(j-1,i+1):
pr[0],r[1],r[2] = im2.getpixel((j,I))
s[0],s[1],s[2] = im2.getpixel((j-1,i+1))
如果juli(r,s)& lt;=l:
矩陣[j][i] =矩陣[j-1][i+1]
maps[str(matrix[j][I])]+= 1
elif檢查(j+1,i-1):
r[0],r[1],r[2] = im2.getpixel((j,I))
s[0],s[1],s[2] = im2.getpixel((j+1,i-1))
如果juli(r,s)& lt;=l:
矩陣[j][i] =矩陣[j+1][i-1]
maps[str(matrix[j][I])]+= 1
elif檢查(j+1,I):
r[0],r[1],r[2] = im2.getpixel((j,I))
s[0],s[1],s[2] = im2.getpixel((j+1,I))
如果juli(r,s)& lt;=l:
矩陣[j][i] =矩陣[j+1][i]
maps[str(matrix[j][I])]+= 1
否則:
n+=1
maps[str(n)]=1
矩陣[j][i] = n
對於範圍內的I(w):
對於範圍(h)中的j:
if矩陣[j][i]!=-1和maps[str(matrix[j][I])]& lt;=2:
im.putpixel((j,I),255)查看代碼
結果因為音量參數設置的小,噪音沒有清理幹凈,所以不理想。如果數量設置得很大,可能會移除壹小塊。最重要的是這裏噪聲的大小不是很有規律,很難找到壹個好的面積參數。
失敗只是暫時的。經過觀察發現,背景噪聲的顏色比數字的顏色要淺得多。這也意味著它的RGB值遠小於數字的RGB值。通過分析RGB值,可以去除大部分噪聲,剩下的噪聲可以用種子染色處理。也就是說,從兩張圖片(分別是黑白和彩色)中獲取信息,然後在壹張圖片上進行處理,最後進行識別。
核心代碼在這裏
r[0],r[1],r[2] = im2.getpixel((j,I))
如果r[0]+r[1]+r[2]& gt;=400或r[0]>=250或r[1]>=250或r[2]>=250 :
IM2。Putpixel ((j,I),(255,255,255))到目前為止,這次發現的問題已經解決,成功率在50%以上,基本滿足接口的要求。