当前位置: 首页 > news >正文

PaddleOCR 图片文字提取

PaddleOCR 图片文字提取

  • 需求
  • 一.裁剪车牌号码区域
  • 二.对车牌小图进行处理
  • 三.填充边界
  • 四.识别步骤


需求

   工作上的一个需求,需要把图片中的车牌号码提取出来。如图,车牌在图片固定位置。开始使用pytesseract,对中文识别特别不友好,毕竟是外国人的东西。同事推荐使用PaddleOCR,国人开发的东西就是不一样,识别正确率居然可以达到90%以上。不过两者都存在共性问题,黑底白字无法识别/范围太小识别不准等。
在这里插入图片描述


一.裁剪车牌号码区域

# np.fromfil 从文本或二进制文件中的数据构造一个数组
# cv2.imdecode()把读取的数据转换(解码)成图像格式;主要用于从网络传输数据中恢复出图像
# cv2.IMREAD_UNCHANGED:读入完整图片,包括alpha通道,可以直接写-1
img = cv2.imdecode(np.fromfile(imgSrc, dtype=np.uint8), cv2.IMREAD_UNCHANGED)
cropImg = img[y1:y2, x1:x2] #顺序为上下 左右
(车牌裁剪出来的小图)

在这里插入图片描述

正常来说把上面裁剪出来的小图进行OCR,就可以识别出文字了,结果....

在这里插入图片描述
   于是百度找了张图,刚好是白底黑字 文字居中,结果神奇地识别结果100%识别正确。经过对比,我断定是白色字体无法识别,接着又把小图进行反相处理。

二.对车牌小图进行处理

height, width, deep = cropImg.shapegray = cv2.cvtColor(cropImg, cv2.COLOR_BGR2GRAY) # cv2.COLOR_BGR2GRAY 将BGR格式转换成灰度图片dst = np.zeros((height, width, 1), np.uint8) #生成一张纯黑色图for i in range(0, height):  # 反相 转白底黑字for j in range(0, width):grayPixel = gray[i, j]dst[i, j] = 255 - grayPixel#走完这一步,已经实现了 转白底黑字,但是白色低背景不是最亮的#再用cv2.threshold进行二值化,使黑色部分更黑,白的更白
ret, img = cv2.threshold(dst, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)

   对小图进行反相处理后的结果就是下面这样,仔细看发现白色底不是很白,再用cv.threshold进行二值化(非黑既白),通对比二值化的图片,层次感就出来了。

(反相后)

在这里插入图片描述

(二值化后)

在这里插入图片描述
   再次进行识别,识别结果终于出来了,但是发现最后一位7被识别成了2,按道理来说这么简单的文字不应该识别错。于是想到前面用来测试识别的图片边界很宽,文字居中,接着对小图进行了填充白底边界150个像素。

三.填充边界

# cv2.BORDER_CONSTANT 固定值填充方式
imgsrc = cv2.copyMakeBorder(img, 150, 150, 150, 150, cv2.BORDER_CONSTANT, value=[255, 255, 255])
(填充后)

在这里插入图片描述


四.识别步骤

ocr = PaddleOCR(use_angle_cls=True, use_gpu=False)  # 使用CPU预加载,不用GPU
text = ocr.ocr(img, cls=True)
result = str(text[0][1][0]).replace('车牌号码:', '').upper()
(最终识别效果)

在这里插入图片描述
在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Flask 异常处理
  • lvs、集群
  • 刷题DAY5
  • Openlayers6 图形绘制和修改功能(结合React)
  • 使用 MongoDB 构建 AI:Flagler Health 的 AI 旅程如何彻底改变患者护理
  • Canal单机部署
  • Python模拟退火算法
  • 一个Android下载网络图片显示并保存到系统相册的完整案例
  • 关于k8s的pvc存储卷
  • haproxy七层代理总结
  • SpringBoot参数校验详解
  • PyTorch 基础学习(6)- 自动微分
  • Android Studio设置 offline 模式
  • 解决 Windows 任务栏图标不更新问题:深入解析与解决方案
  • C++初阶_2:引用
  • JavaScript 如何正确处理 Unicode 编码问题!
  • 2017前端实习生面试总结
  • Docker: 容器互访的三种方式
  • JS字符串转数字方法总结
  • Spring声明式事务管理之一:五大属性分析
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • 阿里云购买磁盘后挂载
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 离散点最小(凸)包围边界查找
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 如何在 Tornado 中实现 Middleware
  • 为视图添加丝滑的水波纹
  • Mac 上flink的安装与启动
  • 交换综合实验一
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • ​第20课 在Android Native开发中加入新的C++类
  • (003)SlickEdit Unity的补全
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (Java)【深基9.例1】选举学生会
  • (poj1.3.2)1791(构造法模拟)
  • (附源码)ssm基于jsp高校选课系统 毕业设计 291627
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • (四)软件性能测试
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (转)fock函数详解
  • (转载)深入super,看Python如何解决钻石继承难题
  • (转载)微软数据挖掘算法:Microsoft 时序算法(5)
  • .bat批处理(十一):替换字符串中包含百分号%的子串
  • .net core 6 集成和使用 mongodb
  • .Net 应用中使用dot trace进行性能诊断
  • .NET 中 GetProcess 相关方法的性能
  • /*在DataTable中更新、删除数据*/
  • @staticmethod和@classmethod的作用与区别
  • [04]Web前端进阶—JS伪数组
  • [2016.7.Test1] T1 三进制异或
  • [240727] Qt Creator 14 发布 | AMD 推迟 Ryzen 9000芯片发布
  • [android] 练习PopupWindow实现对话框
  • [ARM]ldr 和 adr 伪指令的区别