使用SCF快速部署验证码识别接口
Posted 乂乂又又
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用SCF快速部署验证码识别接口相关的知识,希望对你有一定的参考价值。
一、本文介绍
验证码识别是搞爬虫
实现自动化脚本避不开的一个问题,
通常验证码识别程序要么部署在本地,
要么部署在服务器端,
如果部署在服务器端就需要
自己去搭建配置网络环境并编写调用接口,
这是一个极其繁琐耗时的过程。
但是现在我们通过无服务器云函数(SCF),
就可以快速将本地验证码识别程序发布上线,
极大地提高了开发效率。
废话少说,上图 ↓
可以看到,识别效果还是蛮好的,
甚至超过了肉眼识别率。
二、操作步骤
传统的验证码识别流程是
图像预处理(灰化,去噪,切割,二值化,去干扰线等)
验证码字符特征提取(SVM,CNN等)
验证码识别
下面我就带大家一起来创建、编写
并发布上线一个验证识别云函数
第一步:新建python云函数
参见我之前的系列文章
《万物皆可Serverless之使用SCF+COS快速开发全栈应用》
第二步:编写验证识别云函数
Life is short, show me the code.
这里我就以一个
最简单的验证码识别程序为例,
直接上代码
import io
import os
import time
from PIL import Image as image
import json
#字符特征
chars = {
'1': [1, 1, 1, 0, 1, ...],
'2': [1, 0, 0, 1, 0, ...],
'3': [0, 1, 0, 0, 1, ...],
# 其他字符特征...
}
# 灰度处理
def covergrey(img):
return img.convert('L')
# 去除验证码边框
def clearedge(img):
for y in range(img.size[1]):
img.putpixel((0, y), 255)
img.putpixel((1, y), 255)
img.putpixel((2, y), 255)
img.putpixel((img.size[0]-1, y), 255)
img.putpixel((img.size[0]-2, y), 255)
img.putpixel((img.size[0]-3, y), 255)
for x in range(img.size[0]):
img.putpixel((x, 0), 255)
img.putpixel((x, 1), 255)
img.putpixel((x, 2), 255)
img.putpixel((x, img.size[1]-1), 255)
img.putpixel((x, img.size[1]-2), 255)
img.putpixel((x, img.size[1]-3), 255)
return img
# 去除干扰线并转换为黑白照片
def clearline(img):
for y in range(img.size[1]):
for x in range(img.size[0]):
if int(img.getpixel((x, y))) >= 110:
img.putpixel((x, y), 0xff)
else:
img.putpixel((x, y), 0x0)
return img
# 去噪/pnum-去噪效率
def del_noise(im, pnum=3):
w, h = im.size
white = 255
black = 0
for i in range(0, w):
im.putpixel((i, 0), white)
im.putpixel((i, h - 1), white)
for i in range(0, h):
im.putpixel((0, i), white)
im.putpixel((w - 1, i), white)
for i in range(1, w - 1):
for j in range(1, h - 1):
val = im.getpixel((i, j))
if val == black:
cnt = 0
for ii in range(-1, 2):
for jj in range(-1, 2):
if im.getpixel((i + ii, j + jj)) == black:
cnt += 1
if cnt < pnum:
im.putpixel((i, j), white)
else:
cnt = 0
for ii in range(-1, 2):
for jj in range(-1, 2):
if im.getpixel((i + ii, j + jj)) == black:
cnt += 1
if cnt >= 7:
im.putpixel((i, j), black)
return im
# 图片数据二值化
def two_value(code_data):
table = []
for i in code_data:
if i < 140: # 二值化分界线140
table.append(0)
else:
table.append(1)
return table
# 图片预处理
def pre_img(img):
img = covergrey(img) # 去色
img = clearedge(img) # 去边
img = clearline(img) # 去线
img = del_noise(img) # 去噪
return img
# 处理图片数据
def data_img(img):
code_data = [] # 验证码数据列表
for i in range(4): # 切割验证码
x = 5 + i * 18 # 可用PS确定图片切割位置
code_data.append(img.crop((x, 9, x + 18, 33)).getdata())
code_data[i] = two_value(code_data[i]) # 二值化数据
return code_data
# 验证码识别
def identify(data):
code = ['']*4 # 验证码字符列表
diff_min = [432]*4 # 初始化最小距离--不符合的数据点个数(共120数据点)
for char in chars: # 遍历验证码字符(每个字符比较一次4个验证码)
diff = [0]*4 # 各验证码差距值(每个字符判断前重置此距离)
for i in range(4): # 计算四个验证码
for j in range(432): # 逐个像素比较验证码特征
if data[i][j] != chars[char][j]:
diff[i] += 1 # 距离+1
for i in range(4):
if diff[i] < diff_min[i]: # 比已有距离还要小(更加符合)
diff_min[i] = diff[i] # 刷新最小距离
code[i] = char # 刷新最佳验证码
return ''.join(code) # 输出结果
def predict(imgs):
code = ''
img = imgs.read()
img = image.open(io.BytesIO(img))
img = pre_img(img) # 预处理图片
data = data_img(img) # 获取图片数据
code = identify(data) # 识别验证码
return code
def apiReply(reply, code=200):
return {
"isBase64Encoded": False,
"statusCode": code,
"headers": {'Content-Type': 'application/json', "Access-Control-Allow-Origin": "*"},
"body": json.dumps(reply, ensure_ascii=False)
}
def main_handler(event, context):
main_start = time.time()
flag = True if 'image' in event['queryString'] else False
code = predict(event['queryString']['image']) if 'image' in event['queryString'] else '无效的请求'
return apiReply({
'ok': flag,
'code': code,
'spendTime': str(time.time()-main_start)
})
以上是关于使用SCF快速部署验证码识别接口的主要内容,如果未能解决你的问题,请参考以下文章
验证码识别与生成类API调用的代码示例合集:六位图片验证码生成四位图片验证码生成简单验证码识别等