机器学习之初探验证码识别-Scikit learn
2017-4-9 小屿 Scikit-learn
最近尝试初探了一下验证码识别相关技术,发现这个也是蛮复杂的,涉及到图像处理,机器学习,卷积神经什么的,只探索了一点皮毛技术,后面会尝试尽可能的深入,不过英文数学水平是硬伤。
验证码识别常规思路是对图像进行处理,将彩色验证码二值化,去除噪点干扰,切割验证码,作为模型进行训练,然后进行测试
图像处理用到PIL库

def contrast(img): """ 增强图像的对比度 """ # 增加对比度 enhancer = ImageEnhance.Contrast(img) img = enhancer.enhance(5) # 锐化 enhancer = ImageEnhance.Sharpness(img) img = enhancer.enhance(1) return img
灰度化并增强对比度后字符已经很明显了
def binaryzation(img): """ 图像二值化, 并返回黑点位置 """ black_point = [] for x in xrange(img.width): for y in xrange(img.height): if img.getpixel((x,y)) > 60: img.putpixel((x, y), 255) else: img.putpixel((x, y), 0) black_point.append((x,y)) return black_point
二值化需要找到一个阙值,将偏向白的像素变白黑的变黑
def black_pixel_num(x, y, img): """ 爬行连续黑点数量 """ check = [(1, 0), (0, 1), (-1, 0), (0, -1)] for x_change,y_change in check: if (0 <= x+x_change < img.width) and (0 <= y+y_change < img.height): if img.getpixel((x+x_change,y+y_change)) == 0: black_is_checked.append((x+x_change,y+y_change)) if (x+x_change,y+y_change) not in black_del: black_del.append((x+x_change,y+y_change)) def del_img_denoising(img): """ 去除噪点 """ global black_is_checked black_is_checked = [] for x,y in black_point: global black_del black_del = [] # 减少检测次数,提升效率 if (x,y) not in black_is_checked: black_is_checked.append((x,y)) black_pixel_num(x,y,img) for x,y in black_del: black_pixel_num(x,y,img) if len(black_del) < 20: img.putpixel((x, y), 255) for x,y in black_del: img.putpixel((x, y), 255)
通过爬行黑像素面积判断噪点实现去噪
按照常规思路,接下来要做的就是切割字符,对于位置固定的可以进行固定切割,对于不固定的字符不相连的可以通过判断字符边缘来进行切割,还可以按颜切割色,以及滴水切割等等
通过判断字符边缘来进行切割:
def split_yzm_y(img): """ 沿y轴分割验证码 """ black_pixel_get = [] pixel_y = [] for lenth in xrange(img.size[1]): pixel_y.append(0) for x in xrange(img.size[0]): for y in xrange(img.size[1]): if x in black_pixel_get: continue elif img.getpixel((x,y)) == 0: pixel_y[y] = 1 black_pixel_get.append(y) split_y = [] lenth = 0 for i in xrange(len(pixel_y)): if pixel_y[i] == 1: split_y.append(i) break for i in xrange(len(pixel_y)): if pixel_y[i] == 1: lenth += 1 split_y.append(lenth) return split_y
可见字符已经被切割为单独一个
机器学习用到sklearn库
将每个字符的图片用数组表示,字符用肉眼识别结果保存另一个结果,然后导入生成模型文件
model_file = 'model/SVC.pkl' def train(data, target, model_save): classifier = svm.LinearSVC() classifier.fit(data, target) joblib.dump(classifier, model_save)
建立一个空数组长度为字符图片的个数,每个坑和图片高宽一致 np.empty((length, 19 * 28), dtype="float32") 然后读取每个字符图片数组表示导入 np.asarray(img, dtype="float32").flatten() 每个字符的结果也转入个数组然后用 train(data, target, model_save) data为字符图片数组表示的数组集,target为数组的肉眼识别结果,model_save为保存路径
生成模型文件后导入模型文件就可以识别了 clf = joblib.load('model/SVC.pkl') result = clf.predict(yzm) result_yzm = '' for char in result: result_yzm += chr(int(char)) print result_yzm
用园长表哥公司验证码试了下,训练了100张验证码,400个字符,就达到了大约%90正确率。后续会继续学习,尝试挑战BAT验证码。
标签: 机器学习 Scikit-learn
评论:
你是衣冠楚楚的人 而我只是一个打满补丁的猴子
-
小博客一个,没必要伤害她
热门文章
存档
标签
最新评论
- yz
想想你喜欢什么,想做什么,找好一个自己的... - 小屿
@Jahan:testfun1024#p... - Jahan
Hello dear Xia0 i a... - brave
@万:你的手机应该是anroid7.0以... - jhsy
新版的cookie机制应该又变了. 而且... - 小屿
@janto:无兴趣 - janto
新版的这些好像不起作用了,deviceI... - hunk
正在研究,可否发一份新源码?todz$1... - miffy
请问可以加个好友咨询下吗? - vegetableChicken
@Snkrs:我也遇到和你一样的问题了,...
2017-06-10 08:04