目次
序文
このプロジェクトでは、Python クローラー技術を使用してネットワーク経由で検証コード画像をクロールし、ノイズ除去やセグメンテーションなどの一連の処理ステップを通じて、検証コードの識別と精度検証を実現します。
まず、Python クローラー テクノロジーを使用して、ターゲット Web サイトからキャプチャ画像を自動的に取得します。これらのキャプチャは通常、ボットが自動的にフォームにアクセスしたり、フォームを送信したりするのを防ぐように設計されています。クローラー技術を通じて、後続の処理のためにこれらの検証コード画像を取得できます。
次に、取得した検証コード画像のノイズ除去とセグメント化を行います。ノイズ除去操作は、画像内のノイズ情報を除去するのに役立ち、検証コードがより鮮明で読みやすくなります。セグメント化操作では、後の認識のために検証コード内の各文字が個別に抽出されます。
次に、KNN アルゴリズム (K 最近傍法) を使用してモデルをトレーニングします。KNN アルゴリズムは、一般的に使用される教師あり学習アルゴリズムであり、サンプルの特性とラベルに従って分類できます。KNN アルゴリズムを使用してセグメント化されたキャプチャ文字をトレーニングし、モデルがさまざまな文字を認識できるようにします。
最後に、トレーニングされたモデルの精度を検証します。既知のラベルを持つ検証コード画像の一部をモデルに入力することで、モデルの予測結果を得ることができます。予測結果を実際のラベルと比較することで、モデルの精度を計算してモデルのパフォーマンスを評価できます。
本プロジェクトの目的は、クローラ技術と画像処理アルゴリズムにより、認証コード画像の自動識別と精度検証を実現することです。自動テストやデータ収集など、大量の検証コードを処理する必要があるシナリオに適用できます。モデルのトレーニングと検証のプロセスを通じて、検証コード認識の精度と安定性を継続的に向上させ、検証コード処理の効率を向上させることができます。
全体的なデザイン
システムの全体構成図とシステムフローチャートを記載します。
システム全体構成図
システムの全体構成を図に示します。
システムフローチャート
システムフローを図に示します。
動作環境
この部分は主に Python 環境用です
Python環境
Python 2.7 構成が必要です。Windows 環境で Anaconda をダウンロードして、Python に必要な構成を完了します。ダウンロード アドレスはhttps://www.anaconda.com/です。仮想マシンをダウンロードして Linux 環境でコードを実行することもできます。
モジュールの実装
このプロジェクトにはデータクローリング、ノイズ除去とセグメンテーション、モデルのトレーニングと保存、精度検証の 4 つのモジュールが含まれており、各モジュールの機能と関連コードを以下に紹介します。
1. データクローリング
この部分では、リクエスト ライブラリ クローラーを使用して 1200 個の検証コードを取得し、マークを付けます。関連するコードは次のとおりです。
from __future__ import unicode_literals
import requests
import time
if __name__ == "__main__":
#获取图片总数设置number
number = 100
for num in range(number):
img_url='http://run.hbut.edu.cn/Account/LogOn?ReturnUrl=%2f '
data={
'timestamp':unicode(long(time.time()*1000))}
#print (img_url)
res = requests.get(img_url,params=data)
#这是一个get请求,获取图片资源
with open("./download_image/%d.jpg" % num, "wb") as f:
#将图片保存在本地
f.write(res.content)
print("%d.jpg" % num + "获取成功")
2. ノイズ除去とセグメンテーション
画像が正常にクロールされた後、ノイズ除去とセグメンテーションが実行されます。
1) 背景ノイズを除去する
グレースケール画像に変換した後、画像をセグメント化し、境界線とノイズの一部を削除して 4 つの画像に分割し、各画像のグレースケール ヒストグラム (自分で設定) をカウントし、2 番目に大きい対応するピクセル範囲 (つまりbins
、 、特定の - ピクセル範囲内のピクセル数は、ピクセル範囲に対応する 2 番目に大きいです。ほとんどのピクセルは白、空白である必要があります)、ピクセル範囲の中央モードを取得し、保持します (モード バイアス土
)ピクセルを調整して、ほとんどのノイズを除去します。
def del_noise(im_cut):
bins = 16
num_gray = math.ceil(256 / bins)
#函数返回大于或等于一个给定数字的最小整数
hist = cv2.calcHist([im_cut], [0], None, [bins], [0, 256])
lists = []
for i in range(len(hist)):
#print hist[i][0]
lists.append(hist[i][0])
second_max = sorted(lists)[-2]
#查找第二多像素,最多的是验证码空白
bins_second_max = lists.index(second_max)
#取像素范围中位数mode,保留(mode±biases)的像素
mode = (bins_second_max + 0.5) * num_gray
for i in range(len(im_cut)):
for j in range(len(im_cut[0])):
#print im_cut[i][j]
if im_cut[i][j] < mode - 15 or im_cut[i][j] > mode + 15:]
#不在中位数附近的设为白(255)
im_cut[i][j] = 255
return im_cut
2) 画像のセグメンテーション
マークされた 1200 枚の画像をセグメント化して、4800 枚のサブ画像を取得します。関連するコードは次のとおりです。
def cut_image(image, num, img_name):
#image = cv2.imread('./img/8.jpg')
#将BGR格式图片转换成灰度图片
im = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#im_cut_real = im[8:47, 28:128]
im_cut_1 = im[8:47, 27:52]
im_cut_2 = im[8:47, 52:77]
im_cut_3 = im[8:47, 77:102]
im_cut_4 = im[8:47, 102:127]
im_cut = [im_cut_1, im_cut_2, im_cut_3, im_cut_4]
for i in range(4):
im_temp = del_noise(im_cut[i])
#将图片分割为4个
cv2.imwrite('./img_train_cut/'+str(num)+ '_' + str(i)+'_'+img_name[i]+'.jpg', im_temp)
if __name__ == '__main__':
img_dir = './img'
img_name = os.listdir(img_dir) #列出文件夹下所有的目录与文件
for i in range(len(img_name)):
path = os.path.join(img_dir, img_name[i])
image = cv2.imread(path)
name_list = list(img_name[i])[:4]
#name = ''.join(name_list)
cut_image(image, i, name_list)
print '图片%s分割完成' % (i)
print u'*****图片分割预处理完成!*****'
次の図に示すように、画像は正常にセグメント化されました。
3. モデルのトレーニングと保存
データを処理した後、トレーニング セットとテスト セットを分割し、トレーニングして保存します。関連するコードは次のとおりです。
_image(image, num, img_name):
#image = cv2.imread('./img/8.jpg')
#将BGR格式图片转换成灰度图片
im = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#im_cut_real = im[8:47, 28:128]
im_cut_1 = im[8:47, 27:52]
im_cut_2 = im[8:47, 52:77]
im_cut_3 = im[8:47, 77:102]
im_cut_4 = im[8:47, 102:127]
im_cut = [im_cut_1, im_cut_2, im_cut_3, im_cut_4]
for i in range(4):
im_temp = del_noise(im_cut[i])
#将图片分割为4个
cv2.imwrite('./img_train_cut/'+str(num)+ '_' + str(i)+'_'+img_name[i]+'.jpg', im_temp)
if __name__ == '__main__':
img_dir = './img'
img_name = os.listdir(img_dir) #列出文件夹下所有的目录与文件
for i in range(len(img_name)):
path = os.path.join(img_dir, img_name[i])
image = cv2.imread(path)
name_list = list(img_name[i])[:4]
#name = ''.join(name_list)
cut_image(image, i, name_list)
print '图片%s分割完成' % (i)
print u'*****图片分割预处理完成!*****'
8.3.3 模型训练及保存
import numpy as np
from sklearn import neighbors
import os
from sklearn.preprocessing import LabelBinarizer
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.externals import joblib
import cv2
if __name__ == '__main__':
#读入数据
data = []
labels = []
img_dir = './img_train_cut'
img_name = os.listdir(img_dir)
#number = ['0','1', '2','3','4','5','6','7','8','9']
for i in range(len(img_name)):
path = os.path.join(img_dir, img_name[i])
#cv2读进来的图片是RGB3维的,转成灰度图,将图片转化成1维
image = cv2.imread(path)
im = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = im.reshape(-1)
data.append(image)
y_temp = img_name[i][-5]
labels.append(y_temp)
#标签规范化
y = LabelBinarizer().fit_transform(labels)
x = np.array(data)
y = np.array(y)
#拆分训练数据与测试数据
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
#训练KNN分类器
clf = neighbors.KNeighborsClassifier()
clf.fit(x_train, y_train)
#保存分类器模型
joblib.dump(clf, './knn.pkl')
#测试结果打印
pre_y_train = clf.predict(x_train)
pre_y_test = clf.predict(x_test)
class_name = ['class0', 'class1', 'class2', 'class3', 'class4', 'class5', 'class6', 'class7', 'class8', 'class9']
print classification_report(y_train, pre_y_train, target_names=class_name)
print classification_report(y_test, pre_y_test, target_names=class_name)
#clf = joblib.load('knn.pkl')
#pre_y_test = clf.predict(x)
#print pre_y_test
#print classification_report(y, pre_y_test, target_names=class_name)
モデルを保存した後、再利用したり、他の環境に移植したりできます。
4. 精度検証
検証コード (4 つの数字) の元の画像を使用して精度をテストします。関連するコードは次のとおりです。
from __future__ import division
import cv2
import math
import numpy as np
import os
from sklearn.externals import joblib
def del_noise(im_cut):
'''
变量bins:灰度直方图bin的数目
num_gray:像素间隔
方法:1.找到灰度直方图中像素第二多对应的像素,即second_max,因为图像空白处比较多,所以第一多的应该是空白,第二多的是想要的内容。2.计算mode。3.除了mode附近,全部变为空白。
'''
bins = 16
num_gray = math.ceil(256 / bins)
hist = cv2.calcHist([im_cut], [0], None, [bins], [0, 256])
lists = []
for i in range(len(hist)):
#print hist[i][0]
lists.append(hist[i][0])
#将 hist 列表添加到 lists
second_max = sorted(lists)[-2]
#查找第二多像素,最多的是验证码的空白
bins_second_max = lists.index(second_max)
#取像素范围中位数mode,然后保留(mode±biases)的像素
mode = (bins_second_max + 0.5) * num_gray
for i in range(len(im_cut)):
for j in range(len(im_cut[0])):
if im_cut[i][j]<mode - 15 or im_cut[i][j] > mode + 15:
# print im_cut[i][j]
im_cut[i][j] = 255
#不在中位数附近的设为白(255)
return im_cut
def predict(image, img_name):
#image = cv2.imread('./img/8.jpg')
im = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#将BGR格式转换成灰度图片
#im_cut_real = im[8:47, 28:128]
im_cut_1 = im[8:47, 27:52]
im_cut_2 = im[8:47, 52:77]
im_cut_3 = im[8:47, 77:102]
im_cut_4 = im[8:47, 102:127]
im_cut = [im_cut_1, im_cut_2, im_cut_3, im_cut_4]
pre_text = []
for i in range(4):
#图片转换成1维后,再转换成2维的输入变量x
im_temp = del_noise(im_cut[i])
#print type(im_temp)
image = im_temp.reshape(-1)
#print image.shape
tmp = []
tmp.append(list(image))
x = np.array(tmp)
pre_y = clf.predict(x)
pre_y = np.argmax(pre_y[0])
pre_text.append(str(pre_y))
#print pre_text
pre_text = ''.join(pre_text)
if pre_text != img_name:
print'label:%s'%(img_name),'predict:%s'%(pre_text),'\t','false'
return 0
else:
print 'label:%s'%(img_name),'predict:%s'%(pre_text)
return 1
if __name__ == '__main__':
img_dir = './img_test'
img_name = os.listdir(img_dir) #列出文件夹下所有的目录与文件
right = 0
global clf
clf = joblib.load('knn.pkl')
for i in range(len(img_name)):
path = os.path.join(img_dir, img_name[i])
image = cv2.imread(path)
name_list = list(img_name[i])[:4]
name = ''.join(name_list)
pre = predict(image, name)
right += pre
accuracy = (right/len(img_name))*100
print u'准确率为:%s%%,一共%s张验证码,正确:%s,错误:%s'%(accuracy,len(img_name),right,len(img_name)-right)
システムテスト
以下の図に示すように、テスト結果の精度は 99% 以上です。
プロジェクトのソースコードのダウンロード
詳細については、ブログ リソースのダウンロード ページをご覧ください。
その他の情報ダウンロード
人工知能関連の学習ルートと知識システムについて学び続けたい場合は、私の他のブログ「重い| 完全な人工知能 AI 学習 - 基本知識学習ルート」を読んでください。すべての資料は、料金を支払わずにネットワーク ディスクから直接ダウンロードできます。このブログでは、
Github の有名なオープン ソース プラットフォーム、AI テクノロジー プラットフォーム、および関連分野の専門家 (Datawhale、ApacheCN、AI Youdao、Huang Haiguang 博士など) について言及しています。関連資料は約 100G あります。友達全員を助けてください。