使用Python,OpenCV应用EAST文本检测器检测自然场景图像中的文本

news/2024/9/21 16:43:43

使用Python,OpenCV应用EAST文本检测器检测自然场景图像中的文本

    • 1. 效果图
    • 2. 原理
      • 2.1 为什么自然场景文本检测如此具有挑战性?
      • 2.2 替代EAST文本检测实现
    • 3. 源码
      • 3.1 text_detection.py
      • 3.2 text_detection_video.py
    • 参考

这篇博客将介绍如何使用Python,OpenCV应用EAST文本检测器检测自然场景图像和视频流中的文本。

OpenCV的EAST文本检测器是一种深度学习模型,基于一种新颖的体系结构和训练模式。它能够(1)在720p图像上以13 FPS的速度近实时运行,(2)获得最先进的文本检测精度。
《EAST:高效准确的场景文本检测》称该算法为“EAST”,是一种高效、准确的场景文本检测管道。

文本检测器不仅准确,而且能够在720p图像上以大约13 FPS的速度近实时运行。

为了提供OpenCV的EAST文本检测器的实现,需要转换OpenCV的C++示例;然而遇到了许多挑战,如:

  • 无法使用OpenCV的NMSBox进行非最大值抑制,而必须使用imutils中的实现。
  • 由于缺少RotatedRect的Python绑定,无法计算真正的旋转边界框。
  • 尽最大可能使实现尽可能接近OpenCV,但注意:该版本与C++版本并非完全相同,随着时间的推移,可能需要解决一到两个小问题。

1. 效果图

成都玩的照片,检测效果图1如下:
可以看到文本被正确识别,EAST很快,每张照片耗时0.15s左右;
在这里插入图片描述

拉萨羊卓雍错湖路上拍的照片,效果图2如下:
可以看到大多数文本被正确识别;
在这里插入图片描述

侏罗纪世界电影开头,视频流中检测效果图如下:

在这里插入图片描述

2. 原理

opencv >=3.4.2或者4
什么是EAST文本检测器,为什么使用它,以及是什么使该算法如此新颖

在受约束的可控环境中检测文本通常可以通过使用基于启发式的方法来实现,例如利用梯度信息或文本通常分组为段落并且字符出现在直线上的事实。这种基于启发式的文本检测器的示例可以关于检测护照图像中的机器可读区域中看到。

自然场景文本检测是不同的,但更具挑战性。

2.1 为什么自然场景文本检测如此具有挑战性?

  • 图像/传感器噪声:手持式相机的传感器噪声通常高于传统扫描仪的噪声。此外,低价相机通常会对原始传感器的像素进行插值,以产生真实的颜色。
  • 视角:自然场景文本可以自然地具有与文本不平行的视角,从而使文本更难识别。
  • 模糊:不受控制的环境往往会产生模糊。
  • 照明条件:不能对自然场景图像中的照明条件做出任何假设。它可能接近黑暗,相机上的闪光灯可能亮着,或者太阳可能明亮地照耀着,使整个图像饱和。
  • 分辨率:并非所有相机分辨率一致,可能正在处理分辨率低于标准的相机。
  • 非纸张对象:大多数(但不是全部)纸张都不反射(至少在尝试扫描的纸张的上下文中)。自然场景中的文字可能是反射性的,包括徽标、标志等。
    非平面物体:考虑瓶子表面上的文字可能是扭曲和变形的。尽管人仍然能够轻松地“检测”和阅读文本,但算法很难处理。
    未知布局:不能使用任何先验信息为算法提供文本所在位置的“线索”。

OpenCV的EAST文本检测器实现非常健壮,即使文本模糊、反射或部分模糊,也能够定位文本

2.2 替代EAST文本检测实现

这里使用的EAST文本检测模型是与OpenCV兼容的TensorFlow实现,即可以使用TensorFlow或OpenCV使用该模型进行文本检测预测。也可以使用PyTorch实现。

Tesseract和EasyOCR都具有文本检测(检测文本在输入图像中的位置)和文本识别(OCR文本本身)

使用Python,OpenCV进行Tesseract-OCR绑定及文本检测识别
使用EasyOCR执行文本检测
这两个都使用基于深度学习的模型来执行文本检测和定位。

然而根据项目,可以使用基本的图像处理和计算机视觉技术来执行文本检测。
如使用Python,OpenCV+OCR检测护照图像中的机器可读区域(MRZ Machine-Readable Zones)
使用OpenCV和Python识别数字
https://blog.csdn.net/qq_40985985/article/details/113944141
使用Python,OpenCV进行卡类型及16位卡号数字的OCR
使用Python,OpenCV进行银行支票数字和符号的OCR
虽然传统的计算机视觉和图像处理技术可能没有基于深度学习的文本检测技术那么普遍,但它们在某些情况下可以工作得出奇地好。

3. 源码

3.1 text_detection.py

# text_detection.py 对图像进行文本检测
# text_detection_video 对视频流(实时视频/视频文件)进行文本检测
# frozen_east_text_detection.pb EAST自然场景文本检测序列化的模型
# USAGE
# python text_detection.py --image images/yh.jpg --east frozen_east_text_detection.pbimport argparse
import timeimport cv2
import imutils
import numpy as np
# 导入必要的包
from imutils.object_detection import non_max_suppression  # 从IMUTIL中导入了NumPy、OpenCV的非最大单位抑制实现# 构建命令行参数及解析
# --image 输入图像路径
# --east east场景文本检测器模型路径
# --min-confidence 可选 过滤弱检测的置信度值
# --width 可选 缩放图像宽度,必须是32的倍数
# --height 可选 缩放图像高度,必须是32的倍数
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", type=str,help="path to input image")
ap.add_argument("-east", "--east", type=str,help="path to input EAST text detector")
ap.add_argument("-c", "--min-confidence", type=float, default=0.5,help="minimum probability required to inspect a region")
ap.add_argument("-w", "--width", type=int, default=320,help="resized image width (should be multiple of 32)")
ap.add_argument("-e", "--height", type=int, default=320,help="resized image height (should be multiple of 32)")
args = vars(ap.parse_args())# 加载图像获取维度
image = cv2.imread(args["image"])
orig = image.copy()
(H, W) = image.shape[:2]# 计算宽度,高度及分别的比率值
(newW, newH) = (args["width"], args["height"])
rW = W / float(newW)
rH = H / float(newH)# 缩放图像获取新维度
image = cv2.resize(image, (newW, newH))
(H, W) = image.shape[:2]# 为了使用OpenCV和EAST深度学习模型执行文本检测,需要提取两层的输出特征图:
# 定义EAST探测器模型的两个输出层名称,感兴趣的是——第一层输出可能性,第二层用于提取文本边界框坐标
# 第一层是输出sigmoid激活,提供了一个区域是否包含文本的概率。
# 第二层是表示图像“几何体”的输出特征映射-将能够使用该几何体来推导输入图像中文本的边界框坐标
layerNames = ["feature_fusion/Conv_7/Sigmoid","feature_fusion/concat_3"]# cv2.dnn.readNet加载预训练的EAST text detector
print("[INFO] loading EAST text detector...")
net = cv2.dnn.readNet(args["east"])# 从图像构建一个blob,然后执行预测以获取俩层输出结果
# 将图像转换为blob来准备图像
blob = cv2.dnn.blobFromImage(image, 1.0, (W, H),(123.68, 116.78, 103.94), swapRB=True, crop=False)
start = time.time()
# 通过将层名称作为参数提供给网络以指示OpenCV返回感兴趣的两个特征图:
# 分数图,包含给定区域包含文本的概率
# 几何图:输入图像中文本的边界框坐标的输出几何图
net.setInput(blob)
(scores, geometry) = net.forward(layerNames)
end = time.time()# 展示文本预测耗时信息
print("[INFO] text detection took {:.6f} seconds".format(end - start))# 从分数卷中获取行数和列数,然后初始化边界框矩形集和对应的信心分数
(numRows, numCols) = scores.shape[2:4]
rects = []
confidences = []# 两个嵌套for循环用于在分数和几何体体积上循环,这将是一个很好的例子,说明可以利用Cython显著加快管道操作。
# 我已经用OpenCV和Python演示了Cython在快速、优化的“for”像素循环中的强大功能。
# 遍历预测结果
for y in range(0, numRows):# 提取分数(概率),然后是环绕文字的几何(用于推导潜在边界框坐标的数据)scoresData = scores[0, 0, y]xData0 = geometry[0, 0, y]xData1 = geometry[0, 1, y]xData2 = geometry[0, 2, y]xData3 = geometry[0, 3, y]anglesData = geometry[0, 4, y]# 遍历列for x in range(0, numCols):# 过滤弱检测if scoresData[x] < args["min_confidence"]:continue# 计算偏移因子,因为得到的特征图将比输入图像小4倍(offsetX, offsetY) = (x * 4.0, y * 4.0)# 提取用于预测的旋转角度,然后计算正弦和余弦angle = anglesData[x]cos = np.cos(angle)sin = np.sin(angle)# 使用几何体体积导出边界框h = xData0[x] + xData2[x]w = xData1[x] + xData3[x]# 计算文本边界框的开始,结束x,y坐标endX = int(offsetX + (cos * xData1[x]) + (sin * xData2[x]))endY = int(offsetY - (sin * xData1[x]) + (cos * xData2[x]))startX = int(endX - w)startY = int(endY - h)# 将边界框坐标和概率分数添加到各自的列表rects.append((startX, startY, endX, endY))confidences.append(scoresData[x])# 对边界框应用非最大值抑制(non-maxima suppression),以抑制弱重叠边界框,然后显示结果文本预测
# apply overlapping to suppress weak, overlapping bounding boxes
boxes = non_max_suppression(np.array(rects), probs=confidences)# 遍历边界框
for i, (startX, startY, endX, endY) in enumerate(boxes):# 根据相对比率缩放边界框坐标startX = int(startX * rW)startY = int(startY * rH)endX = int(endX * rW)endY = int(endY * rH)# cv2.putText(orig, str(confidences[i]), (startX, startY - 10),#             cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)# 在图像上绘制边界框cv2.rectangle(orig, (startX, startY), (endX, endY), (0, 255, 0), 2)# 展示输出图像
cv2.imshow("Text Detection", imutils.resize(orig,width=500))
cv2.waitKey(0)

3.2 text_detection_video.py

# text_detection.py 对图像进行文本检测
# text_detection_video 对视频流(实时视频/视频文件)进行文本检测
# frozen_east_text_detection.pb EAST自然场景文本检测序列化的模型
# USAGE
# python text_detection_video.py --east frozen_east_text_detection.pb
# python text_detection_video.py --east frozen_east_text_detection.pb --video images/jurassic_park_trailer.mp4import argparse
import timeimport cv2
import imutils
import numpy as np
from imutils.object_detection import non_max_suppression  # 从IMUTIL中导入了NumPy、OpenCV的非最大单位抑制实现
from imutils.video import FPS
# 导入必要的包
from imutils.video import VideoStream  # 使用VideoStream访问网络摄像机和FPS,以对该脚本每秒的帧进行基准测试# 定义一个新函数来解码预测函数-它将被重新用于每个帧,并使循环代码更简洁
def decode_predictions(scores, geometry):# 获取分数集中的行列,初始化边界框坐标和分数list(numRows, numCols) = scores.shape[2:4]rects = []confidences = []# 遍历行for y in range(0, numRows):# 提取分数,潜在的包围文本的边界框坐标scoresData = scores[0, 0, y]xData0 = geometry[0, 0, y]xData1 = geometry[0, 1, y]xData2 = geometry[0, 2, y]xData3 = geometry[0, 3, y]anglesData = geometry[0, 4, y]# 遍历列for x in range(0, numCols):# 过滤弱检测if scoresData[x] < args["min_confidence"]:continue# 计算偏移量因子,由于结果特征图比原始图像小4倍(offsetX, offsetY) = (x * 4.0, y * 4.0)# 提取预测结果的旋转角度,和正弦余弦函数angle = anglesData[x]cos = np.cos(angle)sin = np.sin(angle)# 使用几何体计算边界框的宽高h = xData0[x] + xData2[x]w = xData1[x] + xData3[x]# 计算文本边界框的开始,结束坐标endX = int(offsetX + (cos * xData1[x]) + (sin * xData2[x]))endY = int(offsetY - (sin * xData1[x]) + (cos * xData2[x]))startX = int(endX - w)startY = int(endY - h)# 添加边界框坐标和相应的分数到list中rects.append((startX, startY, endX, endY))confidences.append(scoresData[x])# 返回一系列边界框坐标和对应的分数return (rects, confidences)# 构建命令行参数及解析
# --video 可选的,输入视频文件路径
# --east east场景文本检测器模型路径
# --min-confidence 可选 过滤弱检测的置信度值
# --width 可选 缩放图像宽度,必须是32的倍数
# --height 可选 缩放图像高度,必须是32的倍数
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video", type=str,help="path to optinal input video file")
ap.add_argument("-east", "--east", type=str,help="path to input EAST text detector")
ap.add_argument("-c", "--min-confidence", type=float, default=0.5,help="minimum probability required to inspect a region")
ap.add_argument("-w", "--width", type=int, default=320,help="resized image width (should be multiple of 32)")
ap.add_argument("-e", "--height", type=int, default=320,help="resized image height (should be multiple of 32)")
args = vars(ap.parse_args())# 初始化原始帧的维度,新维度及比率
(W, H) = (None, None)
(newW, newH) = (args["width"], args["height"])
(rW, rH) = (None, None)# 为了使用OpenCV和EAST深度学习模型执行文本检测,需要提取两层的输出特征图:
# 定义EAST探测器模型的两个输出层名称,感兴趣的是——第一层输出可能性,第二层用于提取文本边界框坐标
# 第一层是输出sigmoid激活,提供了一个区域是否包含文本的概率。
# 第二层是表示图像“几何体”的输出特征映射-将能够使用该几何体来推导输入图像中文本的边界框坐标
layerNames = ["feature_fusion/Conv_7/Sigmoid","feature_fusion/concat_3"]# cv2.dnn.readNet加载预训练的EAST text detector
print("[INFO] loading EAST text detector...")
net = cv2.dnn.readNet(args["east"])# 如果未提供视频文件,则获取摄像头指针
if not args.get("video", False):print("[INFO] starting video stream...")vs = VideoStream(src=0).start()time.sleep(1.0)# 否则,获取文件指针
else:vs = cv2.VideoCapture(args["video"])# 开始帧吞吐量计数器
fps = FPS().start()num = 0
# 遍历视频流的帧
while True:# 获取当前帧,兼容 VideoStream or VideoCapture对象frame = vs.read()frame = frame[1] if args.get("video", False) else frame# 检查是否到达文件末尾if frame is None:break# 保持比率的缩放帧frame = imutils.resize(frame, width=1000)orig = frame.copy()# 如果宽度,高度为None,则计算原始帧到新帧的比率if W is None or H is None:(H, W) = frame.shape[:2]rW = W / float(newW)rH = H / float(newH)# 缩放帧,忽略比率frame = cv2.resize(frame, (newW, newH))# 从帧构建一个blob,执行net.forward获取俩层输出结果blob = cv2.dnn.blobFromImage(frame, 1.0, (newW, newH),(123.68, 116.78, 103.94), swapRB=True, crop=False)net.setInput(blob)# 通过将层名称作为参数提供给网络以指示OpenCV返回感兴趣的两个特征图:# 分数图,包含给定区域包含文本的概率# 几何图:输入图像中文本的边界框坐标的输出几何图(scores, geometry) = net.forward(layerNames)# 解码预测结果,然后应用非最大值抑制以抑制重叠边界框# 解码预测并应用NMS(non-maxima suppression)(rects, confidences) = decode_predictions(scores, geometry)boxes = non_max_suppression(np.array(rects), probs=confidences)# 遍历边界框for (startX, startY, endX, endY) in boxes:# 按相对比率缩放边界框startX = int(startX * rW)startY = int(startY * rH)endX = int(endX * rW)endY = int(endY * rH)# cv2.putText(orig, str(confidences[i]), (startX, startY - 10),#             cv2.FONT_HERSHEY_SIMPLEX, 0.45, (0, 0, 255), 2)# 在帧上绘制边界框cv2.rectangle(orig, (startX, startY), (endX, endY), (0, 255, 0), 2)# 更新fps计数器fps.update()num = num + 1cv2.imwrite("imgs/" + str(num) + ".jpg", imutils.resize(orig, width=500))# 展示输出帧cv2.imshow("Text Detection", orig)key = cv2.waitKey(1) & 0xFF# 按下‘q’键,退出循环if key == ord("q"):break# 停止计数器,展示fps信息
fps.stop()
print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))# 如果使用的摄像头流,释放指针
if not args.get("video", False):vs.stop()# 否则,释放文件指针
else:vs.release()# 关闭所有窗口
cv2.destroyAllWindows()

参考

  • https://www.pyimagesearch.com/2018/08/20/opencv-text-detection-east-text-detector/
  • 模型下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pgtn.cn/news/17610.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

数据结构--搜索BFS

文章目录广度优先搜索典型例题广度优先搜索 广度优先搜索类似于树的层次遍历过程。它需要借助一个队列来实现。如图2-1-1所示&#xff0c;要想遍历从v0到v6的每一个顶点&#xff0c;我们可以设v0为第一层&#xff0c;v1、v2、v3为第二层&#xff0c;v4、v5为第三层&#xff0c;…

使用Tesseract和Python进行OCR和语言翻译

使用Tesseract和Python进行OCR和语言翻译 这篇博客将介绍如何使用Tesseract、Python自动进行OCR和文本翻译。使用textblob&#xff0c;翻译文本就像单个函数调用一样简单。&#xff08;textblob翻译底层调用translate.google.com会报超时等&#xff0c;用translators库实现翻译…

[转]后期-快速消除痘痘,完美修复MM肌肤

是面对美景&#xff0c;即使皮肤不好也得露个脸啊!那MM的面子问题怎么办呢?简单&#xff0c;咱就通过Photoshop后期处理来<?xml:namespace prefix o />给MM打造完美水嫩的肌肤!远景照片 简单还原MM容颜日常拍摄的照片&#xff0c;很多时候是远景的拍摄&#xff0c;人物…

opencv-3

文章目录图像平滑图像金字塔开闭运算形态学操作掩膜模板匹配与霍夫变换灰度直方图边缘检测Canny边缘检测图像平滑 # 图像噪声 ################### # ##椒盐噪声 >>>>>>>>>>>>>>>>>>>>随机出现的白点或黑点# …

使用拼写检查提高Tesseract OCR准确性

使用拼写检查提高Tesseract OCR准确性 上一篇博客介绍了如何使用textblob库和Tesseract自动进行OCR文本&#xff0c;然后将其翻译为其他语言。这篇博客还将通过textblob应用自动拼写检查OCR文本来提高OCR准确性 &#xff08;能够使用textblob纠正拼写错误&#xff0c;纠正单词…

使用Python进行名片OCR(识别姓名,职务,电话,Email邮箱)

上一篇博客介绍了如何通过以下方式自动OCR和扫描收据&#xff1a; 检测输入图像中的接收应用透视变换以获得收据的自顶向下视图利用Tesseract对收据上的文本进行OCR使用正则表达式提取价格数据 这篇博客将介绍如何使用Python对名片进行OCR&#xff0c;从名片中提取姓名、职务…

使用Tesseract和OpenCV构建自动收据扫描仪

使用Tesseract和OpenCV构建自动收据扫描仪 这篇博客将介绍如何使用Tesseract和OpenCV构建自动收据扫描仪。将使用OpenCV构建系统的实际图像处理组件&#xff0c;包括&#xff1a; 检测图像中的收据&#xff08;边缘检测、轮廓检测、基于弧长和近似的轮廓滤波&#xff09;找到…

opencv_角点算法

文章目录harris检测原理Shi_Tomasi算法SIFTFastharris检测原理 import numpy as np import cv2 as cv import matplotlib.pyplot as plt img cv.imread("opencv_3.png") gray cv.cvtColor(img,cv.COLOR_RGB2GRAY) graynp.float32(gray) dstcv.cornerHarris(gray,2,…