python 基於機器學習—深度學習識別驗證碼
阿新 • • 發佈:2018-12-13
一、前言
開發環境:Anaconda | python 3.5 —pycharm / jupyter notebook
專案的整個識別流程:
① 驗證碼清理並生成訓練集樣本 ② 驗證碼特徵提取 ③ 擬合識別模型 ④ 識別模型測試
關於資料集
二、驗證碼清理並生成訓練集樣本
2.1 獲取影象和標籤
"""
:param input_path: 影象輸入目錄
:return: image_array, image_label:獲取的影象,標籤
"""
def read_captcha(input_path):
image_array = []
image_label = []
file_list = os.listdir(input_path) # 獲取captcha檔案
for file in file_list:
image = Image.open(input_path+ '/' + file) # 開啟圖片
file_name = file.split(".")[0] # 獲取檔名,此為圖片標籤
image_array.append(image)
image_label.append(file_name)
return image_array, image_label
2.2 初步去除驗證碼的噪點
def image_transfer(image_arry):
"""
:param image_arry: 影象list,每個元素為一副影象
:return: image_clean:清理過後的影象list
"""
image_clean = []
for i, image in enumerate(image_arry):
image = image.convert('L') # 轉換為灰度影象,即RGB通道從3變為1
im2 = Image.new("L", image.size, 255)
for y in range(image.size[1]): # 遍歷所有畫素,將灰度超過閾值的畫素轉變為255(白)
for x in range(image.size[0]):
pix = image.getpixel((x, y))
if int(pix) > threshold_grey: # 灰度閾值
im2.putpixel((x, y), 255)
else:
im2.putpixel((x, y), pix)
image_clean.append(im2)
return image_clean
------------------------------------------------------------------
#或者
import cv2
def image_transfer(image_arry)
img_gray = cv2.cvtColor(image_arry, cv2.COLOR_BGR2GRAY)
# 設定閾值(閾值大小影響去噪效果) 二值化去除噪點
(_, thresh) = cv2.threshold(img_gray, 90, 255, cv2.THRESH_BINARY)
return thresh
2.3 影象細清理
通過粗清理的辦法,無法完全去除所有噪聲點。此處引入了更細粒度的清理方法。 主要有3大步驟: step 1:找出影象中所有的孤立點; step 2:計算黑色點近鄰9宮格中黑色點個數,若小於等於2個,那麼認為該點為噪聲點; step 3:去除所有噪聲點。
2.4 字元切割
去除孤立點後,我們還是沒法一下子就識別出這四個字元,需要對經過處理後的圖片進行切分。 切割方式主要有一下步驟: step 1:找出圖片中所有分離影象的開始結束位置。遍歷width&height,當每出現一個黑色點,記為該字元開始位置;當新的一列出現全白色點,那麼記為結束位置。[(8, 9), (14, 22), (29, 38), (42, 50), (57, 66)] step 2:儘管經過清理後,還是可能存在噪聲點。在找到所有切割開始結束位置後,計算並選出(結束值-開始值)最大的切割位置。[(14, 22), (29, 38), (42, 50), (57, 66)]
def image_split(image):
"""
:param image:單幅影象
:return: 單幅影象被切割後的影象list
"""
inletter = False #找出每個字母開始位置
foundletter = False #找出每個字母結束位置
start = 0
end = 0
letters = [] #儲存座標
for x in range(image.size[0]):
for y in range(image.size[1]):
pix = image.getpixel((x, y))
if pix != True:
inletter = True
if foundletter == False and inletter == True:
foundletter = True
start = x
if foundletter == True and inletter == False:
foundletter = False
end = x
letters.append((start, end))
inletter = False
# 因為切割出來的影象有可能是噪聲點
# 篩選可能切割出來的噪聲點,只保留開始結束位置差值最大的位置資訊
subtract_array = [] # 儲存 結束-開始 值
for each in letters:
subtract_array.append(each[1]-each[0])
reSet = sorted(subtract_array, key=lambda x:x, reverse=True)[0:image_character_num]
letter_chioce = [] # 儲存 最終選擇的點座標
for each in letters:
if int(each[1] - each[0]) in reSet:
letter_chioce.append(each)
image_split_array = [] #儲存切割後的影象
for letter in letter_chioce:
im_split = image.crop((letter[0], 0, letter[1], image.size[1])) # (切割的起始橫座標,起始縱座標,切割的寬度,切割的高度)
im_split = im_split.resize((image_width, image_height)) # 轉換格式
image_split_array.append(im_split)
return image_split_array[0:int(image_character_num)]
2.5 儲存到訓練集
將按上述方法切分後的單個數字、字母,儲存到新建的資料夾裡,專門用來作為模型的訓練集。
三、特徵提取
這裡我們先用HOG作為影象特徵,先提取字型的HOG特徵
list_hog_fd = []
for feature in image_split_array:
fd = hog(feature.reshape((28, 28)), # hog 特徵
orientations=9,
pixels_per_cell=(14, 14),
cells_per_block=(1, 1),
visualise=False)
list_hog_fd.append(fd)
hog_features = np.array(list_hog_fd, 'float64')
未完待續