前言
二值化顧名思義就是將數變成兩種值,一般非0即1。而在驗證碼處理中,如果直接使用灰度圖,那么每個像素的值會在0-255,這樣肯定會增加計算時間,而二值化后每個像素的值只是0和1。
在前面的簡單驗證碼識別中,我的二值化代碼是這樣寫的:a = (a > 180) * 255
,至于這里為什么不乘1而乘255,因為我要顯示圖片看看效果。如果只是用于算法識別的話,乘1會更好。但是,這里的180也就是二值化的閾值是如何得到的,開始是通過一個一個試然后看效果哪個好就選哪個,因為我們一般只識別某個網站的驗證碼,這樣只要測試幾次得到結果后便可用于這個網站其他的驗證碼。
這樣測試有點浪費時間,雖然是一次性的,但是你手動測出的驗證碼不一定是最合適的。所以我們需要算法去自動計算出驗證碼的閾值,算法有很多,這里我們使用迭代法和最大類間方差法,通過這兩個算法計算出來的閾值基本差不多。
迭代法
- 求出圖像中的最小灰度值和最大灰度值,分別記為Gmin和Gmax,則閾值初值T0=(Gmin+Gmax)/2;
- 根據閾值T0將圖像分割成前景和背景兩部分,求出兩部分的平均灰度值m1和m2,平均灰度值=總灰度值/像素個數
- 求出新閾值T1=(m1+m2)/2
- 如果T0=T1,則結束,否則將T1的值賦予T0,從第2步重新計算。
算法實現如下:
import numpy as np
from PIL import Image
def iteration(img_path):
img = Image.open(img_path).convert('L')
a = np.array(img)
a = a.ravel()
k = int((int(a.max()) + int(a.min()))/2) # 即初始閾值T0
m = -1
while k != m:
# C1和C2為前景和背景的像素
C1 = a[a >= k]
C2 = a[a < k]
k = m
m1 = np.sum(C1)/len(C1) if len(C1) else 0
m2 = np.sum(C2)/len(C2) if len(C2) else 0
m = int((m1 + m2)/2)
return k
最大類間方差法(OTSU)
存在閾值T將圖像所有像素分為前景和背景,則這兩類像素各自的均值就為m1、m2,圖像全局均值為mG。同時像素被分為前景和背景的概率分別為p1、p2。因此就有:p1*m1+p2*m2=mG
和 p1+p2=1
則類間方差表達式為:
使得上式值最大時的閾值T就是最佳的閾值。
算法實現如下:
import numpy as np
from PIL import Image
def otsu(img_path):
img = Image.open(img_path).convert('L')
a = np.array(img)
a = a.ravel()
L = []
for k in range(0, 256):
C1 = a[a >= k]
C2 = a[a < k]
if not(len(C1) and len(C2)):
L.append(0)
continue
m1 = np.sum(C1)/len(C1)
m2 = np.sum(C2)/len(C2)
p1 = len(C1)/len(a)
p2 = len(C2)/len(a)
x = p1 * p2 * (m1 - m2) * (m1 - m2)
L.append(x)
return L.index(max(L))
最后,我正在學習一些機器學習的算法,對于一些我需要記錄的內容我都會分享到博客和微信公眾號(python成長路),歡迎關注。平時的話一般分享一些爬蟲或者Python的內容。
審核編輯 黃昊宇
-
機器學習
+關注
關注
66文章
8382瀏覽量
132441 -
二值化
+關注
關注
0文章
13瀏覽量
4230
發布評論請先 登錄
相關推薦
評論