dddocr介绍
- ddddocr 新的目标检测识别 1.3功能ddddocr基本使用和介绍 - 还没想好叫什么 - 博客园ddddocr 新的目标检测识别 1.3功能
- 安装
pip install ddddocr - star哲哥免费开源的识别项目https://github.com/sml2h3/ddddocr
本文介绍ddddocr类封装
初始化操作
class Ddddocr_obj():def __init__(self):self.ocr = ddddocr.DdddOcr(det=False)self.det = ddddocr.DdddOcr(det=True)
det = ddddocr.DdddOcr(det=True,) # 目标检测模型
ocr = ddddocr.DdddOcr(det=False) # 文字识别模型
1.识别图片
像这种模拟登录,过验证码怎么过

def identify_img(self,img=None,content = None):if content:return self.ocr.classification(content)if 'http' in img:img_content = requests.get(img).contentelse:base_code = img.split(',', 1)[-1]img_content = base64.b64decode(base_code)return self.ocr.classification(img_content)
对图片识别进行封装,可以传入三种不同类型
url,base64编码,字节流等等

以这个案例为主https://passport.crecgec.com/login

点击验证码刷新
可看出验证码图片响应的是base64编码
像这种base64编码,不规范,但是在封装函数已经处理好了,直接传入即可
对这个接口进行请求,获取base64编码图片

存入图片只是为了看出识别结果和图片差别

识别出来了。对于识别图片验证码,ddddocr还是非常厉害的。

像这个网站,非常简单,没有加密,登录接口携带识别验证码结果和验证码接口返回数据,即可返回cookies数据。

2.滑块
def process_slide_verification(self,slider_img, background_img, ocr_instance=None):"""处理滑块验证码识别:param slider_img: 滑块小图(URL 或 Base64 字符串):param background_img: 背景大图(URL 或 Base64 字符串):param ocr_instance: 可选,已初始化的 ddddocr 实例:return: 包含缺口位置信息的字典"""if 'http' in slider_img:slider_img_content = requests.get(slider_img).contentelse:base_code = slider_img.split(',', 1)[-1]slider_img_content = base64.b64decode(base_code)if 'http' in slider_img:background_img_content = requests.get(background_img).contentelse:background_base = background_img.split(',', 1)[-1]background_img_content = base64.b64decode(background_base)try:# 识别滑块位置result = self.ocr.slide_match(slider_img_content, background_img_content)# 解析结果if result.get('target'):x1, y1, x2, y2 = result['target']return {'success': True,'message': "识别成功",'data': {'x': x1, # 缺口左上角X坐标'y': y1, # 缺口左上角Y坐标'target': result['target'], # 完整矩形坐标 [x1,y1,x2,y2]'target_y': result['target_y'] # 垂直滑块使用}}else:return {'success': False, 'message': "未识别到缺口位置"}except requests.RequestException as e:raise e
也是可以传入三个不同类型参数,url,字节流,base64编码
返回类型
'x': x1, # 缺口左上角X坐标 'y': y1, # 缺口左上角Y坐标
x1就是长度
'target': result['target'], # 完整矩形坐标 [x1,y1,x2,y2] 'target_y':
result['target_y'] # 垂直滑块使用
核心代码
result = self.ocr.slide_match(slider_img_content, background_img_content)
传入的字节流
以这网站为例
统一身份认证网关系统

抓包还是响应两个base64编码图片

直接对这个接口请求
识别成功


验证

长度还是差不多的
3.点选识别
def wenzi(self,img=None,content = None):if content:img_content= contentelif 'http' in img:img_content = requests.get(img).contentelse:base_code = img.split(',', 1)[1]img_content = base64.b64decode(base_code)with open('test.jpg', 'wb') as f:f.write(img_content)# 执行目标检测poses = self.det.detection(img_content)print("检测到的坐标位置:", poses)# 将字节数据转换为OpenCV图像格式nparr = np.frombuffer(img_content, np.uint8)im = cv2.imdecode(nparr, cv2.IMREAD_COLOR)# 遍历所有检测到的位置并绘制矩形框for box in poses:x1, y1, x2, y2 = box# 绘制红色矩形框im = cv2.rectangle(im, (x1, y1), (x2, y2), color=(0, 0, 255), thickness=2)# 可选:在框上方添加标签label = f"({x1},{y1})-({x2},{y2})"cv2.putText(im, label, (x1, y1 - 10),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)# 保存结果cv2.imwrite("result.jpg", im)print("结果已保存到: result.jpg")# 可选:显示结果cv2.imshow("Detection Result", im)cv2.waitKey(0)cv2.destroyAllWindows()
点选识别可以获取各个文字的坐标位置。
核心代码解释
f.write(img_content) # 执行目标检测
poses = self.det.detection(img_content) print("检测到的坐标位置:", poses)
将字节数据转换为OpenCV图像格式
nparr = np.frombuffer(img_content, np.uint8) im = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
以这个验证码为例子,
# 遍历所有检测到的位置并绘制矩形框
for box in poses: x1, y1, x2, y2 = box # 绘制红色矩形框
im = cv2.rectangle(im, (x1, y1), (x2, y2), color=(0, 0, 255), thickness=2) # 可选:在框上方添加标签
label = f"({x1},{y1})-({x2},{y2})"
cv2.putText(im, label, (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
通过opencv绘制文字红色边框
以此网站为例
苏州市建筑市场综合查询平台
苏州市建筑市场综合查询平台
这个网站验证码可以弹出四种不同验证码,滑块,点选,旋转, 滑动验证,
通过接口请求,通过参数生成判断是不是点选验证

结果如下:


识别文字的位置还是很准确的,但是识别文字很 难受,基本误差很大,所以对于点选验证一般用打码平台去解决。甚至有些滑块也很难说,识别率基本很低。
完整代码
class Ddddocr_obj():def __init__(self):self.ocr = ddddocr.DdddOcr(det=False)self.det = ddddocr.DdddOcr(det=True)#文字点选def wenzi(self,img=None,content = None):if content:img_content= contentelif 'http' in img:img_content = requests.get(img).contentelse:base_code = img.split(',', 1)[1]img_content = base64.b64decode(base_code)with open('test.jpg', 'wb') as f:f.write(img_content)# 执行目标检测poses = self.det.detection(img_content)print("检测到的坐标位置:", poses)# 将字节数据转换为OpenCV图像格式nparr = np.frombuffer(img_content, np.uint8)im = cv2.imdecode(nparr, cv2.IMREAD_COLOR)# 遍历所有检测到的位置并绘制矩形框for box in poses:x1, y1, x2, y2 = box# 绘制红色矩形框im = cv2.rectangle(im, (x1, y1), (x2, y2), color=(0, 0, 255), thickness=2)# 可选:在框上方添加标签label = f"({x1},{y1})-({x2},{y2})"cv2.putText(im, label, (x1, y1 - 10),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)# 保存结果cv2.imwrite("result.jpg", im)print("结果已保存到: result.jpg")# 可选:显示结果cv2.imshow("Detection Result", im)cv2.waitKey(0)cv2.destroyAllWindows()#图片识别def identify_img(self,img=None,content = None):if content:return self.ocr.classification(content)if 'http' in img:img_content = requests.get(img).contentelse:base_code = img.split(',', 1)[-1]img_content = base64.b64decode(base_code)return self.ocr.classification(img_content)#滑块def process_slide_verification(self,slider_img, background_img, ocr_instance=None):"""处理滑块验证码识别:param slider_img: 滑块小图(URL 或 Base64 字符串):param background_img: 背景大图(URL 或 Base64 字符串):param ocr_instance: 可选,已初始化的 ddddocr 实例:return: 包含缺口位置信息的字典"""if 'http' in slider_img:slider_img_content = requests.get(slider_img).contentelse:base_code = slider_img.split(',', 1)[-1]slider_img_content = base64.b64decode(base_code)if 'http' in slider_img:background_img_content = requests.get(background_img).contentelse:background_base = background_img.split(',', 1)[-1]background_img_content = base64.b64decode(background_base)try:# 识别滑块位置result = self.ocr.slide_match(slider_img_content, background_img_content)# 解析结果if result.get('target'):x1, y1, x2, y2 = result['target']return {'success': True,'message': "识别成功",'data': {'x': x1, # 缺口左上角X坐标'y': y1, # 缺口左上角Y坐标'target': result['target'], # 完整矩形坐标 [x1,y1,x2,y2]'target_y': result['target_y'] # 垂直滑块使用}}else:return {'success': False, 'message': "未识别到缺口位置"}except requests.RequestException as e:raise e