由於上面的驗證碼是24位的jpeg影象,並且包含了噪點,所以我們要做的就是去噪和去色,我拿ps找了張驗證碼試了試,使用ps濾鏡中的去噪效果還行, 但是沒有在pil找到去噪的函式,後來發現中值過濾後可以去掉大部分的噪點,而且pil裡有現成的函式,接下來我試著直接把影象轉換為單色,結果發現還是 會有不過的噪點留了下來,因為中值過濾時把不少噪點淡化了,但轉換為音色時這些噪點又被強化顯示了,於是在中值過濾後對影象亮度進行加強處理,然後再轉換 為單色,這樣驗證碼就變得比較容易識別了:
上面這些處理使用python才幾行:
im = image.open(image_name)
im = im.filter(imagefilter.medianfilter())
enhancer = imageenhance.contrast(im)
im = enhancer.enhance(2)
im = im.convert('1')
im.show()
#!/usr/bin/env python
#encoding=utf-8
import image,imageenhance,imagefilter
import sys
image_name = "./images/81.jpeg"
im = image.open(image_name)
im = im.filter(imagefilter.medianfilter())
enhancer = imageenhance.contrast(im)
im = enhancer.enhance(2)
im = im.convert('1')
#im.show()
#all by pixel
s = 12 #start postion of first number
w = 10 #width of each number
h = 15 #end postion from top
t = 2 #start postion of top
im_new =
#split four numbers in the picture
for i in range(4):
im1 = im.crop((s+w*i+i*2,t,s+w*(i+1)+i*2,h))
f = file("data.txt","a")
for k in range(4):
l =
#im_new[k].show()
for i in range(13):
for j in range(10):
if (im_new[k].getpixel((j,i)) == 255):
else:
f.write("l=[")
n = 0
for i in l:
if (n%10==0):
f.write("/n")
f.write(str(i)+",")
n+=1
f.write("]/n")
把字模儲存為list,用於接下來的匹配;
提取完字模後剩下來的就是對需要處理的進行與資料庫中的字模進行匹配了,基本的思路就是看相應點的重合率,但是由於噪點的影響在對(6,8) (8,3)(5,9)的匹配時容易出錯,俺自己針對已有的100幅資料採集進行分析,採用了雙向匹配(與字模分別作為基點),做了半天的測試終於 可以實現100%的識別率。
#!/usr/bin/env python
#encoding=utf-8
import image,imageenhance,imagefilter
import data
debug = false
def d_print(*msg):
global debug
if debug:
for i in msg:
print i,
print
else:
pass
def get_num(l=):
min1 =
min2 =
for n in data.n:
count1=count2=count3=count4=0
if (len(l) != len(n)):
print "wrong pic"
exit()
for i in range(len(l)):
if (l[i] == 1):
count1+=1
if (n[i] == 1):
count2+=1
for i in range(len(l)):
if (n[i] == 1):
count3+=1
if (l[i] == 1):
count4+=1
d_print(count1,count2,count3,count4)
d_print(min1,"/n",min2)
for i in range(10):
if (min1[i] <= 2 or min2[i] <= 2):
if ((abs(min1[i] - min2[i])) <10):
return i
for i in range(10):
if (min1[i] <= 4 or min2[i] <= 4):
if (abs(min1[i] - min2[i]) <= 2):
return i
for i in range(10):
flag = false
if (min1[i] <= 3 or min2[i] <= 3):
for j in range(10):
if (j != i and (min1[j] <5 or min2[j] <5)):
flag = true
else:
pass
if (not flag):
return i
for i in range(10):
if (min1[i] <= 5 or min2[i] <= 5):
if (abs(min1[i] - min2[i]) <= 10):
return i
for i in range(10):
if (min1[i] <= 10 or min2[i] <= 10):
if (abs(min1[i] - min2[i]) <= 3):
return i
#end of function get_num
def pic_reg(image_name=none):
im = image.open(image_name)
im = im.filter(imagefilter.medianfilter())
enhancer = imageenhance.contrast(im)
im = enhancer.enhance(2)
im = im.convert('1')
im.show()
#all by pixel
s = 12 #start postion of first number
w = 10 #width of each number
h = 15 #end postion from top
t = 2 #start postion of top
im_new =
#split four numbers in the picture
for i in range(4):
im1 = im.crop((s+w*i+i*2,t,s+w*(i+1)+i*2,h))
s = ""
for k in range(4):
l =
#im_new[k].show()
for i in range(13):
for j in range(10):
if (im_new[k].getpixel((j,i)) == 255):
else:
s+=str(get_num(l))
return s
print pic_reg("./images/22.jpeg")
這裡再提一下驗證碼識別的基本方法:截圖,二值化、中值濾波去噪、分割、緊縮重排(讓高矮統一)、字型檔特徵匹配識別。 驗證碼 字元的特徵提取
字元的特徵提取 從被切割和歸一處理後的字元中,提取最能體現這個字元特點的特徵向量 方法 逐畫素特徵提取法,骨架特徵提取法,垂直方向資料統計特徵提取法,13點特徵提取法,弧度梯度特徵提取法 逐畫素特徵提取法 對影象進行逐行逐列的掃瞄,黑色畫素特徵值取1,白色畫素特徵值取0,最後形成乙個維數與影象中畫素...
PHP建立驗證碼字符集 初級
header content type text html charset utf 8 寫乙個陣列裡面有小寫a z 大寫a z 以及數字,把所有相似的數字和字母都剔除,無論大小寫 如 大寫i 與 1 或者 大寫z 與 2 或者 小寫z 與2 0與o.arr1 range 0,9 arr2 range...
生成四位驗證碼(字串)
一 用字串輸出四位驗證碼 1.先輸出定義的字串 str abcdefghjklmnopqrstuvwxyz0123456789 思路是從上邊的字串中隨機抽取四個數 運用函式substr a echo substr str,5 輸出56789 b echo substr str,5,3 輸出567a是...