一、调用识图平台API
这种平台有很多,如果只是简单的测试,推荐《 快识图片文字识别免费识别平台》,地址为:http://fast.95man.com/。
注册之后查看平台API文档调用,每日有100免费次数,调试阶段是足够了,而且效率和准确率还是可以的。
我这边的调用函数供大家参考
from requestsimport post
import base64
def get_code_for_api(img_path=r'D:\auto_project\v_code.png'):
f =open(img_path, "rb")
img = base64.b64encode(f.read())
url ="http://api.95man.com:8888/api/Http/Recog?Taken=token值&imgtype=1&len=4"
data = {"ImgBase64": img}
req = post(url, data)
req_list = req.text.split("|")
return req_list[1]
一般为了提高图片的准确率,都会对图片进行相应的处理,具体代码为下。
from PILimport Image
from PILimport ImageOps
def get_code_img(driver):
"""
获取验证码图片截图
:paramdriver:
:return:
"""
# 整个页面截图
driver.save_img(r'D:\auto_project\v_code.png')
# 定位验证码元素
element = driver.find_element(('id', 'img_valid'), is_return=True)
left = element.location['x']
top = element.location['y']
right = element.location['x'] + element.size['width']
bottom = element.location['y'] + element.size['height']
# 截取,并将得到的图片保存在本地
im = Image.open(r'D:\auto_project\v_code.png')
im = im.crop((left, top, right, bottom))
im.save(r'D:\auto_project\v_code.png')
def remove_color():
"""
处理图上的每个像素点,使图上每个点“非黑即白”
:return:
"""
# 打开图片
image = Image.open(r'D:\auto_project\v_code.png')
# 处理图上的每个像素点,使图上每个点“非黑即白”
image = image.point(lambda x:0 if x <143 else 255)
border_image = ImageOps.expand(image, border=20, fill='white')
border_image.save(r'D:\auto_project\v_code.png')
二、使用ORC工具进行验证码识别
from PIL import Image
from pytesseract import pytesseract
from collections import defaultdict
def get_threshold(image):
# 获取图片中像素点数量最多的像素
pixel_dict = defaultdict(int)
# 像素及该像素出现次数的字典
rows, cols = image.size
for i in range(rows):
for j in range(cols):
pixel = image.getpixel((i, j))
pixel_dict[pixel] +=1
count_max =max(pixel_dict.values())# 获取像素出现出多的次数
pixel_dict_reverse = {v:kfor k,vin pixel_dict.items()}
threshold = pixel_dict_reverse[count_max]# 获取出现次数最多的像素点
return threshold
def get_bin_table(threshold):
# 按照阈值进行二值化处理
# 获取灰度转二值的映射table
table = []
for i in range(256):
rate =0.1 # 在threshold的适当范围内进行处理
if threshold*(1-rate) <= i <= threshold*(1+rate):
table.append(1)
else:
table.append(0)
return table
def cut_noise(image):
# 去掉二值化处理后的图片中的噪声点
rows, cols = image.size# 图片的宽度和高度
change_pos = []# 记录噪声点位置
# 遍历图片中的每个点,除掉边缘
for i in range(1, rows-1):
for j in range(1, cols-1):
# pixel_set用来记录该店附近的黑色像素的数量
pixel_set = []
# 取该点的邻域为以该点为中心的九宫格
for m in range(i-1, i+2):
for n in range(j-1, j+2):
if image.getpixel((m, n)) !=1:# 1为白色,0位黑色
pixel_set.append(image.getpixel((m, n)))
# 如果该位置的九宫内的黑色数量小于等于4,则判断为噪声
if len(pixel_set) <=4:
change_pos.append((i,j))
# 对相应位置进行像素修改,将噪声处的像素置为1(白色)
for pos in change_pos:
image.putpixel(pos, 1)
return image
def OCR_lmj(img_path):
# 识别图片中的数字加字母
image = Image.open(img_path)# 打开图片文件
imgry = image.convert('L')# 转化为灰度图
# 获取图片中的出现次数最多的像素,即为该图片的背景
max_pixel = get_threshold(imgry)
# 将图片进行二值化处理
table = get_bin_table(threshold=max_pixel)
out = imgry.point(table, '1')
# 去掉图片中的噪声(孤立点)
out = cut_noise(out)
# 仅识别图片中的数字
# text = pytesseract.image_to_string(out, config='digits')
# 识别图片中的数字和字母
text = pytesseract.image_to_string(out)
# 去掉识别结果中的特殊字符
exclude_char_list =' .:\\|\'\"?![],()~@#$%^&*_+-={};<>/¥'
text =''.join([xfor xin textif xnot in exclude_char_list])
return text
建议直接使用第一种方式,毕竟成熟的产品准确率还是很客观的,现在验证码越来越复杂,但靠自己简单的封装和调用已经很难准确的识别出来了。
网友评论