用docker在云上部署一个图片解析接口
公司的应用为了加强安全性,在登陆时增加了验证码。这对自动化来说,增加了不少难度。 曾经尝试用各种方法来解析验证码,识别率都不高。 后面我找到了一个新出的解析验证码包,叫muggle_ocr, 是基于人工智能的,解析效果还不错。 首先安装模块
pip install muggle_ocr
# 因模块过新,阿里/清华等第三方源可能尚未更新镜像,因此手动指定使用境外源,为了提高依赖的安装速度,可预先自行安装依赖:tensorflow/numpy/opencv-python/pillow/pyyaml
因为考虑到需要给大家都用,所以打算在云服务器上做一个接口。 首先写图片解析的代码
import requests
import time
import muggle_ocr
import os
from PIL import Image
import shutil
sdk = muggle_ocr.SDK(model_type=muggle_ocr.ModelType.OCR)
root_dir = r"./imgs"
new_dir = r"./imgs2"
def check_folder(folder):
if os.path.exists(folder):
shutil.rmtree(folder)
os.major(folder)
def binaryzation(threshold=145): # 降噪,图片二值化
table = []
for i in range(256):
if i < threshold:
table.append(0)
else:
table.append(1)
return table
def change_size(source,destination):
directorys = [os.path.join(source, f) for f in os.listdir(source)]
for directory in directorys:
# 不是图片文件就跳过
print(directory)
if directory.endswith(('.jpg','png','jpeg','.bmp')):
img = Image.open(directory)
img = img.convert('L') # 转化为灰度图
img = img.point(binaryzation(), '1') # 二值化
s = "/"
# 获取文件名(含后缀)
oimage_name = directory[directory.rfind(s) + 1:]
(oimage_width, oimage_height) = img.size
new_width = oimage_width * 3
new_height = oimage_height * 3
out = img.resize((new_width, new_height), Image.ANTIALIAS)
out.save(os.path.join(destination,"%s" % oimage_name))
def get_muggule(root_dir):
for i in os.listdir(root_dir):
n = os.path.join(root_dir, i)
with open(n, "rb") as f:
b = f.read()
st = time.time()
text = sdk.predict(image_bytes=b)
print(i, text)
return text
为了提高识别率,我将图片进行了处理,进行了降噪,以及放大。 然后需要写一个接口,这里用的是flask.
from flask import request
from flask import Flask, jsonify, abort
from PIL import Image
from testpicture import change_size, get_muggule, root_dir, new_dir, check_folder
import os
app = Flask(__name__)
@app.route("/photo", methods=['POST'])
def get_frame():
# 接收图片
upload_file = request.files['file']
# 获取图片名
file_name = upload_file.filename
if upload_file:
# 计算图片大小
img = Image.open(upload_file)
check_folder(root_dir)
img.save(os.path.join(root_dir, file_name))
check_folder(new_dir)
change_size(root_dir, new_dir)
text = get_muggule(new_dir)
data = {'text': text, 'filename': file_name, 'format': img.format, 'size': img.size}
return jsonify(data)
abort(400) # 若没有图片传递返回400
if __name__ == '__main__':
# app.run(host='127.0.0.1',port=5000)
# 将host设置为0.0.0.0,则外网用户也可以访问到这个服务
app.run(host="0.0.0.0", port=6000, debug=True)
写完以后,本地运行没啥问题,如果需要部署到云服务器上去,得写一个Dockerfile 我得拿到requirement.txt 这里推荐一个工具叫pipreqs,可以通过一条命令直接生成项目所有依赖包清单requirements.txt,方便部署。 生成项目所有依赖清单 方法1: 安装pipreqs pip install pipreqs
装好之后切换到项目根目录下,执行下面命令: pipreqs ./
正常的话应该会在项目根目录下生成一个requirements.txt文件 如果出现unicode问题,通过下面命令解决: pipreqs ./ --encoding=utf-8
当项目里存在requirements .txt文件时,执行命令会提示警告,这时需要在执行命令中增加"--force"参数。执行以下语句: pipreqs ./ --encoding=utf-8 --force
如果生成的requirements.txt文件有个别包漏掉,这时可以检查一下缺失的包名,将包名手工加到文件中。 方法2: 省心方式:导出所有的第三方包 pip freeze >requirements.txt
会生成当前python环境安装的所有安装包,生成的文件名可以任意命名,安装的时候也要用这个名字 pip freeze 会附带上一些不需要的包,以及某些包依赖的包~ 好了,奉献上Dockerfile
FROM python:3.8
ENV PYTHONUNBUFFERED 1
WORKDIR /code/captcha
ADD . /code/captcha
RUN pip3 install -i http://pypi.douban.com/simple --trusted-host pypi.douban.com -r requirements.txt
CMD python3 app.py 0.0.0.0:6000
Build 这个镜像,启动容器就可以了。 如何调用? 写段代码就可以了
if __name__ == '__main__':
# API地址
url = "http://127.0.0.1:6000/photo"
# 图片地址
file_path = r'C:Usersming.xieshDownloadskibana.jpg'
# 图片名
file_name = file_path.split('/')[-1]
# 二进制打开图片
file = open(file_path, 'rb')
# 拼接参数
files = {'file': (file_name, file, 'image/jpg')}
# 发送post请求到服务器端
r = requests.post(url, files=files)
print(r.json())
这样,调用起来就很方便。测试了一下,没加灰度和放大图片,七成的识别率,处理了一下,达到了八成,这样就很方便测试了,如果偶尔没识别出来,可以多点一次验证码,多识别一次就可以了。 感觉docker用起来很爽,一直用一直爽。
- Codeforces 626B Cards(模拟+规律)
- Android 5.0屏幕录制漏洞(CVE-2015-3878)威胁预警
- Codeforces 626A Robot Sequence(模拟)
- BZOJ 2038: [2009国家集训队]小Z的袜子(hose)【莫队算法裸题&&学习笔记】
- [接口测试 - 基础篇] 01 你应该了解的协议基础
- Uva - 12050 Palindrome Numbers【数论】
- [接口测试 - http.client篇] 14 源码初探及其工作机制分析
- 51Nod 1277 字符串中的最大值(KMP,裸题)
- Codeforces Round #345 (Div. 2)【A.模拟,B,暴力,C,STL,容斥原理】
- 07.移动先行之谁主沉浮----控件之轮流轰炸——布局类控件
- BZOJ 1411&&Vijos 1544 : [ZJOI2009]硬币游戏【递推,快速幂】
- UVa 10341 - Solve It【经典二分,单调性求解】
- UVa 11461 - Square Numbers【数学,暴力】
- BZOJ 3097: Hash Killer I【构造题,思维题】
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 树莓派的cpu与gpu通信设计浅析
- Python全栈(七)Flask框架之5.视图高级--类视图和蓝图
- Python全栈(六)项目前导之5.使用GitHub进行多人协同开发
- 附002.Nginx代理相关模块解析
- ApiBoot v2.3.x分支第一个版本发布,重构源码架构设计
- Python全栈(七)Flask框架之1.Flask简介与URL和视图介绍
- 两个CSS知识点:BFC和选择器权重
- C语言入门系列之9.预处理
- Python爬虫常见异常及解决办法
- 理解nodejs中js和c++的通信原理
- 如何使用FFmpeg将互联网直播点播平台内直播视频流转化为HLS流?
- 记一次nodejs问题排查
- 使用Go语言编译互联网视频直播点播平台EasyDSS出现ld returned 1 exit status错误
- c/c++补完计划(四): 字节对齐和虚继承
- Python 不用selenium 带你高效爬取京东商品评论