精华内容
下载资源
问答
  • 在本教程中,您将学习如何使用 OpenCV 使用 EAST 文本检测器检测图像中的文本。 EAST 文本检测器要求我们在我们的系统上运行 OpenCV 3.4.2 或 OpenCV 4 。 论文原文:https://arxiv.org/abs/1704.03155 代码地址...

    在本教程中,您将学习如何使用 OpenCV 使用 EAST 文本检测器检测图像中的文本。

    EAST 文本检测器要求我们在我们的系统上运行 OpenCV 3.4.2 或 OpenCV 4 。

    • 论文原文:https://arxiv.org/abs/1704.03155

    • 代码地址:https://github.com/argman/EAST
      原文:
      https://www.pyimagesearch.com/2018/08/20/opencv-text-detection-east-text-detector/

    在今天教程的第一部分中,我将讨论为什么在自然场景图像中检测文本会如此具有挑战性。 从那里我将简要讨论 EAST 文本检测器,我们为什么使用它,以及是什么让算法如此新颖——我还将提供原始论文的链接,以便您可以阅读详细信息,如果您愿意的话。

    最后,我将提供我的 Python + OpenCV 文本检测实现,以便您可以开始在自己的应用程序中应用文本检测。

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

    img

    在受约束的受控环境中检测文本通常可以通过使用基于启发式的方法来完成,例如利用梯度信息或文本通常被分组为段落并且字符出现在一条直线上的事实。

    然而,自然场景文本检测是不同的——而且更具挑战性。 由于廉价数码相机的普及,更不用说现在几乎每部智能手机都配备了相机这一事实,我们需要高度关注拍摄图像的条件——此外,我们可以做出哪些假设,哪些不可行。 我在 Celine Mancas-Thillou 和 Bernard Gosselin 的 2017 年优秀论文《自然场景文本理解》中描述了自然场景文本检测挑战的总结版本,如下所示:

    • 图像/传感器噪声:手持相机的传感器噪声通常高于传统扫描仪的噪声。此外,低价相机通常会插入原始传感器的像素以产生真实的颜色。
    • 视角:自然场景文本自然会有与文本不平行的视角,使文本更难识别。
    • 模糊:不受控制的环境往往会模糊,特别是如果最终用户使用的智能手机没有某种形式的稳定性。
    • 光照条件:我们无法对自然场景图像中的光照条件做出任何假设。可能接近黑暗,相机上的闪光灯可能打开,或者太阳可能很耀眼,使整个图像饱和。
    • 分辨率:并非所有相机都是一样的——我们可能会处理分辨率低于标准的相机。
    • 非纸质物体:大多数(但不是全部)纸张不具有反射性(至少在您尝试扫描的纸张环境中)。自然场景中的文本可能具有反射性,包括徽标、标志等。
    • 非平面对象:考虑将文本环绕在瓶子周围时会发生什么 - 表面上的文本会扭曲变形。虽然人类可能仍然能够轻松“检测”和阅读文本,但我们的算法将面临困难。我们需要能够处理这样的用例。
    • 未知布局:我们不能使用任何先验信息来为我们的算法提供有关文本所在位置的“线索”。

    EAST 深度学习文本检测器

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XXPKId7V-1637126841247)(https://pyimagesearch.com/wp-content/uploads/2018/08/opencv_text_detection_east.jpg)]

    随着 OpenCV 3.4.2 和 OpenCV 4 的发布,我们现在可以使用名为 EAST 的基于深度学习的文本检测器,该检测器基于 Zhou 等人 2017 年的论文 EAST: An Efficient and Accurate Scene Text Detector。

    我们称该算法为“EAST”,因为它是一个:高效且准确的场景文本检测管道。

    这组作者说,EAST 管道能够预测 720p 图像上任意方向的单词和文本行,而且可以以 13 FPS 的速度运行。 也许最重要的是,由于深度学习模型是端到端的,因此可以避开其他文本检测器通常应用的计算成本高的子算法,包括候选聚合和单词分区。

    为了构建和训练这样一个深度学习模型,EAST 方法利用了新颖、精心设计的损失函数。 有关 EAST 的更多详细信息,包括架构设计和训练方法,请务必参阅作者的出版物。

    项目结构

    $ tree --dirsfirst
    .
    ├── images
    │   ├── car_wash.png
    │   ├── lebron_james.jpg
    │   └── sign.jpg
    ├── frozen_east_text_detection.pb
    ├── text_detection.py
    └── text_detection_video.py
    

    请注意,我在 images/ 目录中提供了三张示例图片。 您可能希望添加自己的智能手机收集的图像或您在网上找到的图像。 我们今天将审查两个 .py 文件:

    • text_detection.py :检测静态图像中的文本。
    • text_detection_video.py :通过网络摄像头或输入视频文件检测文本。

    实施说明

    我今天包含的文本检测实现基于 OpenCV 的官方 C++ 示例;但是,我必须承认,将其转换为 Python 时遇到了一些麻烦。

    首先,Python 中没有 Point2f 和 RotatedRect 函数,因此,我无法 100% 模仿 C++ 实现。 C++ 实现可以生成旋转的边界框,但不幸的是,我今天与您分享的那个不能。

    其次,NMSBoxes 函数不返回 Python 绑定的任何值(至少对于我的 OpenCV 4 预发布安装),最终导致 OpenCV 抛出错误。 NMSBoxes 函数可以在 OpenCV 3.4.2 中工作,但我无法对其进行详尽的测试。

    我在 imutils 中使用我自己的非最大值抑制实现解决了这个问题,但同样,我不相信这两个是 100% 可互换的,因为看起来 NMSBoxes 接受额外的参数。

    鉴于所有这些,我已尽最大努力为您提供最好的 OpenCV 文本检测实现,使用我拥有的工作功能和资源。如果您对该方法有任何改进,请随时在下面的评论中分享。

    使用 OpenCV 实现我们的文本检测器

    在开始之前,我想指出您的系统上至少需要安装 OpenCV 3.4.2(或 OpenCV 4)才能使用 OpenCV 的 EAST 文本检测器,接下来,确保您的系统上也安装/升级了 imutils:

     pip install --upgrade imutils
    

    此时您的系统已经配置完毕,因此打开 text_detection.py 并插入以下代码:

    # import the necessary packages
    from imutils.object_detection import non_max_suppression
    import numpy as np
    import argparse
    import time
    import cv2
    # construct the argument parser and parse the arguments
    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())
    

    首先,导入所需的包和模块。 值得注意的是,我们从 imutils.object_detection 导入了 NumPy、OpenCV 和我对 non_max_suppression 的实现。 然后我们继续解析五个命令行参数:

    –image :我们输入图像的路径。

    –east : EAST 场景文本检测器模型文件路径。

    –min-confidence :确定文本的概率阈值。 可选, default=0.5 。

    –width :调整后的图像宽度 - 必须是 32 的倍数。默认值为 320 时可选。

    –height :调整后的图像高度 - 必须是 32 的倍数。默认值为 320 时可选。

    重要提示:EAST 文本要求您的输入图像尺寸是 32 的倍数,因此如果您选择调整 --width 和 --height 值,请确保它们是 32 的倍数! 从那里,让我们加载我们的图像并调整它的大小:

    # load the input image and grab the image dimensions
    image = cv2.imread(args["image"])
    orig = image.copy()
    (H, W) = image.shape[:2]
    # set the new width and height and then determine the ratio in change
    # for both the width and height
    (newW, newH) = (args["width"], args["height"])
    rW = W / float(newW)
    rH = H / float(newH)
    # resize the image and grab the new image dimensions
    image = cv2.resize(image, (newW, newH))
    (H, W) = image.shape[:2]
    

    我们加载并复制我们的输入图像。 确定原始图像尺寸与新图像尺寸的比率(基于为 --width 和 --height 提供的命令行参数)。 然后我们调整图像大小,忽略纵横比。 为了使用 OpenCV 和 EAST 深度学习模型进行文本检测,我们需要提取两层的输出特征图:

    # define the two output layer names for the EAST detector model that
    # we are interested -- the first is the output probabilities and the
    # second can be used to derive the bounding box coordinates of text
    layerNames = [
    	"feature_fusion/Conv_7/Sigmoid",
    	"feature_fusion/concat_3"]
    

    我们构建了一个 layerNames 列表:

    第一层是我们的输出 sigmoid 激活,它为我们提供了一个区域是否包含文本的概率。

    第二层是输出特征图,表示图像的“几何”——我们将能够使用这个几何来推导出输入图像中文本的边界框坐标

    让我们加载 OpenCV 的 EAST 文本检测器:

    # load the pre-trained EAST text detector
    print("[INFO] loading EAST text detector...")
    net = cv2.dnn.readNet(args["east"])
    # construct a blob from the image and then perform a forward pass of
    # the model to obtain the two output layer sets
    blob = cv2.dnn.blobFromImage(image, 1.0, (W, H),
    	(123.68, 116.78, 103.94), swapRB=True, crop=False)
    start = time.time()
    net.setInput(blob)
    (scores, geometry) = net.forward(layerNames)
    end = time.time()
    # show timing information on text prediction
    print("[INFO] text detection took {:.6f} seconds".format(end - start))
    

    我们使用 cv2.dnn.readNet 将神经网络加载到内存中,方法是将路径传递给 EAST 检测器。

    然后,我们通过将其转换为 blob 来准备我们的图像。要阅读有关此步骤的更多信息,请参阅深度学习:OpenCV 的 blobFromImage 工作原理。 为了预测文本,我们可以简单地将 blob 设置为输入并调用 net.forward。 这些行被抓取时间戳包围,以便我们可以打印经过的时间。 通过将 layerNames 作为参数提供给 net.forward,我们指示 OpenCV 返回我们感兴趣的两个特征图:

    • 用于导出输入图像中文本的边界框坐标的输出几何图

    • 同样,分数图,包含给定区域包含文本的概率

    我们需要一个一个地循环这些值中的每一个:

    # grab the number of rows and columns from the scores volume, then
    # initialize our set of bounding box rectangles and corresponding
    # confidence scores
    (numRows, numCols) = scores.shape[2:4]
    rects = []
    confidences = []
    # loop over the number of rows
    for y in range(0, numRows):
    	# extract the scores (probabilities), followed by the geometrical
    	# data used to derive potential bounding box coordinates that
    	# surround text
    	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]
    

    我们首先获取分数卷的维度(,然后初始化两个列表:

    • rects :存储文本区域的边界框 (x, y) 坐标
    • 置信度:将与每个边界框关联的概率存储在 rects 中

    我们稍后将对这些区域应用非极大值抑制。 循环遍历行。提取当前行 y 的分数和几何数据。 接下来,我们遍历当前选定行的每个列索引:

        # loop over the number of columns
    	for x in range(0, numCols):
    		# if our score does not have sufficient probability, ignore it
    		if scoresData[x] < args["min_confidence"]:
    			continue
    		# compute the offset factor as our resulting feature maps will
    		# be 4x smaller than the input image
    		(offsetX, offsetY) = (x * 4.0, y * 4.0)
    		# extract the rotation angle for the prediction and then
    		# compute the sin and cosine
    		angle = anglesData[x]
    		cos = np.cos(angle)
    		sin = np.sin(angle)
    		# use the geometry volume to derive the width and height of
    		# the bounding box
    		h = xData0[x] + xData2[x]
    		w = xData1[x] + xData3[x]
    		# compute both the starting and ending (x, y)-coordinates for
    		# the text prediction bounding box
    		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)
    		# add the bounding box coordinates and probability score to
    		# our respective lists
    		rects.append((startX, startY, endX, endY))
    		confidences.append(scoresData[x])
    

    对于每一行,我们开始遍历列。 我们需要通过忽略概率不够高的区域来过滤掉弱文本检测。

    当图像通过网络时,EAST 文本检测器自然会减小体积大小——我们的体积大小实际上比我们的输入图像小 4 倍,因此我们乘以 4 以将坐标带回原始图像。

    提取角度数据。 然后我们分别更新我们的矩形和置信度列表。 我们快完成了! 最后一步是对我们的边界框应用非极大值抑制来抑制弱重叠边界框,然后显示结果文本预测:

    # apply non-maxima suppression to suppress weak, overlapping bounding
    # boxes
    boxes = non_max_suppression(np.array(rects), probs=confidences)
    # loop over the bounding boxes
    for (startX, startY, endX, endY) in boxes:
    	# scale the bounding box coordinates based on the respective
    	# ratios
    	startX = int(startX * rW)
    	startY = int(startY * rH)
    	endX = int(endX * rW)
    	endY = int(endY * rH)
    	# draw the bounding box on the image
    	cv2.rectangle(orig, (startX, startY), (endX, endY), (0, 255, 0), 2)
    # show the output image
    cv2.imshow("Text Detection", orig)
    cv2.waitKey(0)
    

    正如我在上一节中提到的,我无法在我的 OpenCV 4 安装 (cv2.dnn.NMSBoxes) 中使用非最大值抑制,因为 Python 绑定没有返回值,最终导致 OpenCV 出错。我无法完全在 OpenCV 3.4.2 中进行测试,因此它可以在 v3.4.2 中运行。

    相反,我使用了 imutils 包(第 114 行)中提供的非最大值抑制实现。结果看起来还是不错的;但是,我无法将我的输出与 NMSBoxes 函数进行比较以查看它们是否相同。 循环我们的边界框,将坐标缩放回原始图像尺寸,并将输出绘制到我们的原始图像。原始图像会一直显示,直到按下某个键。

    作为最后的实现说明,我想提一下,我们用于循环分数和几何体的两个嵌套 for 循环将是一个很好的例子,说明您可以利用 Cython 显着加速您的管道。我已经使用 OpenCV 和 Python 在快速优化的“for”像素循环中展示了 Cython 的强大功能。

    OpenCV 文本检测结果

    您准备好将文本检测应用于图像了吗?

    下载frozen_east_text_detection,地址:

    oyyd/frozen_east_text_detection.pb (github.com)

    。 从那里,您可以在终端中执行以下命令(注意两个命令行参数):

    $ python text_detection.py --image images/lebron_james.jpg \
    	--east frozen_east_text_detection.pb
    

    您的结果应类似于下图:

    在这里插入图片描述

    在勒布朗·詹姆斯身上标识了三个文本区域。 现在让我们尝试检测商业标志的文本:

    $ python text_detection.py --image images/car_wash.png \
    	--east frozen_east_text_detection.pb
    

    使用 OpenCV 检测视频中的文本

    现在我们已经了解了如何检测图像中的文本,让我们继续使用 OpenCV 检测视频中的文本。 这个解释将非常简短; 请根据需要参阅上一节了解详细信息。 打开 text_detection_video.py 并插入以下代码:

    # import the necessary packages
    from imutils.video import VideoStream
    from imutils.video import FPS
    from imutils.object_detection import non_max_suppression
    import numpy as np
    import argparse
    import imutils
    import time
    import cv2
    

    我们首先导入我们的包。 我们将使用 VideoStream 访问网络摄像头和 FPS 来对这个脚本的每秒帧数进行基准测试。 其他一切都与上一节相同。

    为方便起见,让我们定义一个新函数来解码我们的预测函数——它将在每一帧中重复使用,并使我们的循环更清晰:

    def decode_predictions(scores, geometry):
    	# grab the number of rows and columns from the scores volume, then
    	# initialize our set of bounding box rectangles and corresponding
    	# confidence scores
    	(numRows, numCols) = scores.shape[2:4]
    	rects = []
    	confidences = []
    	# loop over the number of rows
    	for y in range(0, numRows):
    		# extract the scores (probabilities), followed by the
    		# geometrical data used to derive potential bounding box
    		# coordinates that surround text
    		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]
    		# loop over the number of columns
    		for x in range(0, numCols):
    			# if our score does not have sufficient probability,
    			# ignore it
    			if scoresData[x] < args["min_confidence"]:
    				continue
    			# compute the offset factor as our resulting feature
    			# maps will be 4x smaller than the input image
    			(offsetX, offsetY) = (x * 4.0, y * 4.0)
    			# extract the rotation angle for the prediction and
    			# then compute the sin and cosine
    			angle = anglesData[x]
    			cos = np.cos(angle)
    			sin = np.sin(angle)
    			# use the geometry volume to derive the width and height
    			# of the bounding box
    			h = xData0[x] + xData2[x]
    			w = xData1[x] + xData3[x]
    			# compute both the starting and ending (x, y)-coordinates
    			# for the text prediction bounding box
    			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)
    			# add the bounding box coordinates and probability score
    			# to our respective lists
    			rects.append((startX, startY, endX, endY))
    			confidences.append(scoresData[x])
    	# return a tuple of the bounding boxes and associated confidences
    	return (rects, confidences)
    

    定义了 decode_predictions 函数。

    该函数用于提取: 文本区域的边界框坐标 和一个文本区域检测的概率 此专用函数将使代码在此脚本中稍后更易于阅读和管理。 让我们解析我们的命令行参数:

    # construct the argument parser and parse the arguments
    ap = argparse.ArgumentParser()
    ap.add_argument("-east", "--east", type=str, required=True,
    	help="path to input EAST text detector")
    ap.add_argument("-v", "--video", type=str,
    	help="path to optinal input video file")
    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())
    

    命令行参数解析:

    –east : EAST 场景文本检测器模型文件路径。

    –video :我们输入视频的路径。 可选 — 如果提供了视频路径,则不会使用网络摄像头。

    –min-confidence :确定文本的概率阈值。 可选, default=0.5 。

    –width :调整后的图像宽度(必须是 32 的倍数)。 可选的 default=320 。

    –height :调整后的图像高度(必须是 32 的倍数)。 可选的 default=320 。

    与上一节中的纯图像脚本相比(在命令行参数方面)的主要变化是我用 --video 替换了 --image 参数。 重要提示:EAST 文本要求您的输入图像尺寸是 32 的倍数,因此如果您选择调整 --width 和 --height 值,请确保它们是 32 的倍数! 接下来,我们将执行模仿前一个脚本的重要初始化:

    # initialize the original frame dimensions, new frame dimensions,
    # and ratio between the dimensions
    (W, H) = (None, None)
    (newW, newH) = (args["width"], args["height"])
    (rW, rH) = (None, None)
    # define the two output layer names for the EAST detector model that
    # we are interested -- the first is the output probabilities and the
    # second can be used to derive the bounding box coordinates of text
    layerNames = [
    	"feature_fusion/Conv_7/Sigmoid",
    	"feature_fusion/concat_3"]
    # load the pre-trained EAST text detector
    print("[INFO] loading EAST text detector...")
    net = cv2.dnn.readNet(args["east"])
    

    高度/宽度和比率初始化将允许我们稍后正确缩放边界框。 我们的输出层名称已定义,加载我们预先训练的 EAST 文本检测器。 以下块设置我们的视频流和每秒帧数计数器:

    # if a video path was not supplied, grab the reference to the web cam
    if not args.get("video", False):
    	print("[INFO] starting video stream...")
    	vs = VideoStream(src=0).start()
    	time.sleep(1.0)
    # otherwise, grab a reference to the video file
    else:
    	vs = cv2.VideoCapture(args["video"])
    # start the FPS throughput estimator
    fps = FPS().start()
    

    我们的视频流设置为: 网络摄像头 或视频文件

    初始化每秒帧数计数器并开始循环传入帧:

    # loop over frames from the video stream
    while True:
    	# grab the current frame, then handle if we are using a
    	# VideoStream or VideoCapture object
    	frame = vs.read()
    	frame = frame[1] if args.get("video", False) else frame
    	# check to see if we have reached the end of the stream
    	if frame is None:
    		break
    	# resize the frame, maintaining the aspect ratio
    	frame = imutils.resize(frame, width=1000)
    	orig = frame.copy()
    	# if our frame dimensions are None, we still need to compute the
    	# ratio of old frame dimensions to new frame dimensions
    	if W is None or H is None:
    		(H, W) = frame.shape[:2]
    		rW = W / float(newW)
    		rH = H / float(newH)
    	# resize the frame, this time ignoring aspect ratio
    	frame = cv2.resize(frame, (newW, newH))
    

    遍历视频/网络摄像头帧。 我们的框架被调整大小,保持纵横比。 从那里,我们获取维度并计算缩放比例。 然后我们再次调整框架的大小(必须是 32 的倍数),这次忽略纵横比,因为我们已经存储了安全保存的比率。 推理和绘制文本区域边界框发生在以下几行:

    # construct a blob from the frame and then perform a forward pass
    	# of the model to obtain the two output layer sets
    	blob = cv2.dnn.blobFromImage(frame, 1.0, (newW, newH),
    		(123.68, 116.78, 103.94), swapRB=True, crop=False)
    	net.setInput(blob)
    	(scores, geometry) = net.forward(layerNames)
    	# decode the predictions, then  apply non-maxima suppression to
    	# suppress weak, overlapping bounding boxes
    	(rects, confidences) = decode_predictions(scores, geometry)
    	boxes = non_max_suppression(np.array(rects), probs=confidences)
    	# loop over the bounding boxes
    	for (startX, startY, endX, endY) in boxes:
    		# scale the bounding box coordinates based on the respective
    		# ratios
    		startX = int(startX * rW)
    		startY = int(startY * rH)
    		endX = int(endX * rW)
    		endY = int(endY * rH)
    		# draw the bounding box on the frame
    		cv2.rectangle(orig, (startX, startY), (endX, endY), (0, 255, 0), 2)
    

    在这个区块中,我们:

    通过创建 blob 并将其传递到网络,使用 EAST 检测文本区域 。

    解码预测并应用 NMS。 我们使用之前在此脚本中定义的 decode_predictions 函数和我的 imutils non_max_suppression 便利函数。

    循环边界框并将它们绘制在框架上。 这涉及按之前收集的比率缩放框。

    从那里我们将关闭帧处理循环以及脚本本身:

    # update the FPS counter
    	fps.update()
    	# show the output frame
    	cv2.imshow("Text Detection", orig)
    	key = cv2.waitKey(1) & 0xFF
    	# if the `q` key was pressed, break from the loop
    	if key == ord("q"):
    		break
    # stop the timer and display FPS information
    fps.stop()
    print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
    print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))
    # if we are using a webcam, release the pointer
    if not args.get("video", False):
    	vs.stop()
    # otherwise, release the file pointer
    else:
    	vs.release()
    # close all windows
    cv2.destroyAllWindows()
    

    我们在循环的每次迭代中更新我们的 fps 计数器,以便在我们跳出循环时可以计算和显示计时。 我们在第 165 行显示 EAST 文本检测的输出并处理按键。 如果“q”被按下以“退出”,我们就会跳出循环并继续清理和释放指针。

    视频文字检测结果

    打开一个终端并执行以下命令(这将启动您的网络摄像头,因为我们没有通过命令行参数提供 --video):

    python text_detection_video.py --east frozen_east_text_detection.pb 
    

    总结

    在今天的博文中,我们学习了如何使用 OpenCV 的新 EAST 文本检测器来自动检测自然场景图像中文本的存在。

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

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

    • 无法使用 OpenCV 的 NMSBoxes 进行非最大值抑制,而必须使用 imutils 中的实现。
    • 由于缺少 RotatedRect 的 Python 绑定,无法计算真正的旋转边界框。

    跳出循环时可以计算和显示计时。 我们在第 165 行显示 EAST 文本检测的输出并处理按键。 如果“q”被按下以“退出”,我们就会跳出循环并继续清理和释放指针。

    视频文字检测结果

    打开一个终端并执行以下命令(这将启动您的网络摄像头,因为我们没有通过命令行参数提供 --video):

    python text_detection_video.py --east frozen_east_text_detection.pb 
    

    总结

    在今天的博文中,我们学习了如何使用 OpenCV 的新 EAST 文本检测器来自动检测自然场景图像中文本的存在。

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

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

    • 无法使用 OpenCV 的 NMSBoxes 进行非最大值抑制,而必须使用 imutils 中的实现。
    • 由于缺少 RotatedRect 的 Python 绑定,无法计算真正的旋转边界框。

    我试图让我的实现尽可能接近 OpenCV,但请记住,我的版本与 C++ 版本并非 100% 相同,并且随着时间的推移可能会有一两个小问题需要解决。 无论如何,我希望你喜欢今天的 OpenCV 文本检测教程!
    完整代码:
    https://download.csdn.net/download/hhhhhhhhhhwwwwwwwwww/43592497

    展开全文
  • 文本检测数据集标注

    千次阅读 2021-11-20 00:34:28
    ​ 本文介绍的标注方式和标注工具均为2017年华南理工大学刘禹良提出的弯曲文本标注方式和工具,可以对弯曲文本进行弯曲标注,具体数据集可以查看论文作者提出的SCUT-CTW1500。 ​

    工具链接:Curve-Text-Detector/data at master · Yuliang-Liu/Curve-Text-Detector · GitHub

    目录

    前言

    一、工具介绍

    1.标注格式

    2.工具使用

    二、标注步骤

    1.数据准备

    2.数据标注

    3.数据集label可视化

    总结


    前言

    本次介绍的标注方式和标注工具均为2017年华南理工大学刘禹良提出的弯曲文本标注方式和工具(原文链接:https://arxiv.org/abs/1712.02170),可以对弯曲文本进行弯曲标注,具体数据集可以查看论文作者提出的SCUT-CTW1500。


    提示:以下是本篇文章正文内容,下面为工具使用经验总结(论文作者也在工具链接中提供了工具使用手册)







    一、工具介绍

    1.标注格式

    1)对矩形或者四边形文本区域,使用4个顶点就可以确定;

    2)而对弯曲文本,作者发现使用14个点就可以进行确定,具体的标注方式如图1所示,先确定4个顶点位置(紫色点),然后根据辅助线在上下边界分别确定5个点(绿色点),并且可以标注文本内容,用于扩充为文本识别数据集。(对于过于弯曲的文本区域标注效果并不利用,建议按单词级别标注,避免过于弯曲文本区域)

    图1 标注过程

    2.工具使用

    "b"和"f":分别为移动至上一张和下一张,并保存当前状态;

    "r":切换标注方式(矩形或者多边形);

    "d":先在右侧文本标注框实例栏中选择需要删除的实例,再按下"d"进行实例删除;

    鼠标右击:保存当前状态并删除当前操作;

    鼠标左击:在标注矩形区域时,先左击确定左上角,然后拖动鼠标至右下角左击即可确定矩形区域;而确定四边形区域,则分别在四边形区域分别左击鼠标确定四个点即可;而对于弯曲文本区域的标注是在四边形区域标注基础上进行操作,需要借助"k"和空格进行辅助标注;

    "k"和空格:主要使用在标注弯曲文本区域,先确定弯曲文本的四个顶点位置(参考标注四边形区域),然后在右侧文本标注框实例栏“鼠标左击”刚才确定的四边形区域,再点击"k"就会出现十条辅助线(5条红色和5条蓝色),移动鼠标,鼠标的水平线和辅助线相交的点如果在合适的位置再敲击“空格”即确定了一个点,依次红色辅助线的5个点再依次确定蓝色辅助线的5个点就完成了弯曲文本的标注;

    鼠标左双击:在右侧实例列表中对实例左双击,会出现一个框,其中可以填入文本内容,用于扩充标注文本识别数据集,敲击"Esc"可以退出,填好文本内容并敲击"Enter"可以保存并退出;

    鼠标滚轮:对图像放缩,同时可以结合"Ctrl"+滚轮或者"Ctrl"+"Shift"+滚轮加快放缩速度。当出现标注框出现偏移的情况,通过切换图片可以恢复;(在使用过程中,在对某些放缩过的图像进行标注时,有时标注框会出现偏移,出现这种情况时对该张图像进行原尺寸标注,这种情况很少发生,可以在全部标注工作完成后进行可视化标注框进行检查)

    滚动栏:在图像尺寸过大,会出现滚动栏,可以通过滚动栏进行移动画布;

    "t":在右侧实例栏选择实例,敲击"t"可以辅助找到标注框,但是提示不明显,基本不会使用到,一般情况通过颜色就能找到相应的标注框。

    具体的工具界面如图2所示:

    图2 标注工具界面







    二、标注步骤






    1.数据准备

    1)先对准备好需要标注的图片,并将其进行重命名,同时也可以进行对数据集打乱操作;

    # 对图像进行重命名
    def change_name(root):
        # 读取文件路径下所有的图像
        res = os.listdir(root)
        # 将列表打乱,防止同类型图像堆积在一起,可以随机分布
        random.shuffle(res)
        # 设立index,用于给文件进行行动命名
        index = 1
        for i in res:
            # 对于jpg和png格式图片图片进行换名
            if ".jpg" in i or ".png" in i:
                os.rename(os.path.join(root, i), os.path.join(root, str(index) + '.' + i.split('.', 1)[1]))
                index += 1
            else:
                print('您输入的图片必须是以jpg或者png格式的')

    2)建议所有的图片名格式一致并且长度一致,如果你重命名是从1开始,并按照数字命名,建议进行补零操作,因为该工具的读入方式为将按照字符串,这样文件顺序将得以保持;

    # 给文件名添加添加前置0
    def add_zeros(root):
        res = os.listdir(root)
        # 统一长度为4位
        for i in res:
            if len(i.split('.', 1)[0]) == 1:
                os.rename(os.path.join(root, i), os.path.join(root, '000' + i))
            elif len(i.split('.', 1)[0]) == 2:
                os.rename(os.path.join(root, i), os.path.join(root, '00' + i))
            elif len(i.split('.', 1)[0]) == 3:
                os.rename(os.path.join(root, i), os.path.join(root, '0' + i))

    3)将命名好的图片放入image文件夹下,标注好的txt会生成在label文件夹下,并且名字和图片名字一致。






    2.数据标注

    1)双击运行windows_label_tool.exe;

    2)当需要到达上次标注的图片位置,通过输入序号,然后点击“go”,如图3;

    图3 工具底部

    3)对图片中文本的区域标注参考工具使用中的操作即可,四边形和弯曲文本区域标注操作示意如4所示,矩形区域标注较为简单,简单尝试即会;

    图4 标注示意图

    4)如果标注文本检测数据集,无需填入文本内容,label文件如图5(a)所示,文本识别数据集label如图5(b)所示,第一行有一个文本框数字代表文本框实例个数,可以用于统计自己数据集一共标注了多少个文本实例(如果不需要,在标注工作完成之后对其删除即可);

    图5 label示意图

    5)特殊情况说明1:弯曲文本区域过于弯曲,会出现图6左侧效果不佳的情况,建议按单词级进行标注,得到图7右侧效果;

    图7 过度弯度标注效果对比

    6)在Windows下使用时,对于较为竖直的弯曲文本标注出现困难,生成的辅助线较为水平,而移动无法细微,造成标注框确定困难(未尝试在Ubuntu下是否会出现这种情况),提供两种解决方案,如图8(a):延伸文本区域,使得有一定斜度,但是造成区域贴合度下降;或者图8(b):顶点不确定在四个角,不知对后期训练是否会产生影响;可以尝试更好的解决方案。

    图8 过度弯曲标注解决方案示意

    3.数据集label可视化

    主要是将标注好的文本框还原在原图上,查看标注的文本框是否精准。

    # 将标注的图像进行可视化展示
    def visualize(image_root, gt_root, out_root, name):
        # 根据路径和文件名将图像读出,本示例采用了jpg格式
        image = cv2.imread(os.path.join(image_root, name+'.jpg'), 3)
        # 根据路径和文件名将标注文件读取,文件格式为txt
        gt_txt = open(os.path.join(gt_root, name+'.txt'))
        height, width, _ = image.shape
        lines = 0
        index = 0
        while 1:
            line = gt_txt.readline()
            if not line:
                break
            # 首行为文本框个数
            if lines == 0:
                lines = int(line)
                continue
            line = line.replace("\n", "")
            line = line.split(',')
            # print(line)
            now = np.empty(shape=[0, 1, 2])
            for i in range(0, len(line), 2):
                temp = np.empty(shape=[0, 2])
                temp = np.append(temp, [[line[i], line[i + 1]]], axis=0)
                now = np.append(now, [temp], axis=0)
            now = now.astype(np.int32)
            # 根据标注文件的坐标点绘制多边形文本框
            image = cv2.polylines(image, [now], True, (0, 0, 255), thickness=2)
            # cv2.imshow('image'+str(index), image)
            index = index + 1
        # 保存可视化图片到输出路径中
        cv2.imwrite(out_root + '\\' + name + '.jpg', image)
        print(name + '.jpg')
        cv2.waitKey(0)
        cv2.destroyAllWindows()

    效果如图9所示:

    图9 数据集可视化示意图







    总结

    以上为本次文本检测数据集标注工具的使用经验介绍,主要通过使用论文作者提供的工具完成数据集的标注工作,如果大家遇到更好的文本标注软件可以一起分享讨论。

    展开全文
  • 摘要:文本检测是文本读取识别的第一步,对后续的文本识别有着重大的影响。一般场景下,可以通过对通用目标检测算法进行配置修改,来实现对文本行的检测定位。本文主要介绍基于像素分割的文本检测算法。
    摘要:文本检测是文本读取识别的第一步,对后续的文本识别有着重大的影响。一般场景下,可以通过对通用目标检测算法进行配置修改,来实现对文本行的检测定位。本文主要介绍基于像素分割的文本检测算法。

    本文分享自华为云社区《技术综述十四:弯曲文本检测算法(二)》,作者: 我想静静 。

    背景介绍

    文本检测是文本读取识别的第一步,对后续的文本识别有着重大的影响。一般场景下,可以通过对通用目标检测算法进行配置修改,来实现对文本行的检测定位。然而在弯曲文字场景,通用目标检测算法无法实现对文字边框的精准表述。因此,近年来很多学术论文都提出了新颖的解决场景文字检测的算法,主要包括两种思路:1. 基于区域重组的文本检测;2. 基于像素分割的文本检测。本文主要介绍基于像素分割的文本检测算法。

    PSENet

    PSENet 是一个纯分割的文本检测方法,该方法的初衷是为了有效地分离任意形状的相邻文本。它通过预测多个尺度的文本分割图来实现这个目的。具体如图1所示,这里以预测3个尺度的分割图为例,即(a),(e),(f)。后处理的流程如下:首先从最小尺度的分割图(a)给各个连接组件分配标签,然后将(a)向四周扩张从而合并(e)中的被预测为文本的像素。同理,合并(f)中的文本像素。

    图1. PSENet 渐进式扩展过程

    这种渐进地、从小到大合并相邻文本像素的方法能有效地分离相邻文本实例,但是付出的代价就是速度很慢,通过C++能缓解速度慢的问题。

    PAN

    PAN主要是针对现有的文本检测方法速度太慢,不能实现工业化应用而设计的。该方法从两方面来提升文本检测的速度。第一,从网络结构上,该方法使用了轻量级的ResNet18作为backbone。但ResNet18的特征提取能力不够强,并且得到的感受野不够大。因此,进一步提出了轻量级的特征增强模块和特征融合模块,该特征增强模块类似于FPN,且可以多个级联在一起。特征增强模块在只增加少量的计算量的前提下有效地增强了模型的特征提取能力,并增大了感受野。第二,从后处理上提升速度。该方法通过预测文本区域,文本中心区域(kernel),以及像素间的相似度来检测文本。使用聚类的思想,kernel是聚类中心,文本像素是需要聚类的样本。为了聚类,属于同一个文本实例的kernel和对应的像素的相似度向量之间的距离应该尽可能小,不同kernels的相似度向量的距离应该远。在推理阶段,首先根据kernel得到连接组件,然后沿着四周合并与kernel的距离小于阈值d的像素。该方法在实现高精度的同时还取得了实时的文本检测速度.

    图2. PAN网络结构

    MSR

    MSR是为了解决多尺度文本检测困难而提出来的。与别的文本检测方法不同,该方法使用了多个一样的backbone,并将输入图像下采样到多个尺度之后连同原图一起输入到这些backbone,最后不同的backbone的特征经过上采样之后进行融合,从而捕获了丰富的多尺度特征。网络最后预测文本中心区域、文本中心区域每个点到最近的边界点的x坐标偏移和y坐标偏移。在推理阶段,文本中心区域的每个点根据预测的x/y坐标偏移得到对应的边界点,最终的文本轮廓是包围所有边界点的轮廓。

    图3. MSR算法框架

    图4:MSR网络结构

    该方法的优点是对于多尺度文本有较强的检测能力,但是由于该方法定义的文本中心区域只是文本区域在上下方向上进行了缩小,而左右方向没有缩小,因此无法有效分离水平上相邻的文本。

    DB

    DB主要是针对现有的基于分割的方法需要使用阈值进行二值化处理而导致后处理耗时且性能不够好而提出的。该方法很巧妙地设计了一个近似于阶跃函数的二值化函数,使得分割网络在训练的时候能学习文本分割的阈值。此外,在推理阶段,该方法根据文本中心区域的面积和周长直接扩张一定的比例得到最终的文本轮廓,这也进一步提升了该方法的推理速度。整体上而言,DB对基于像素分割的文本检测方法提供了一个很好的算法框架,解决了此类算法阈值配置的难题,同时又有较好的兼容性--开发者可以针对场景难点对backbone进行改造优化,达到一个较好的性能和精度的平衡。

    图5. DB网络结构

    基于像素分割的算法能精准地预测出任意形状的文本实例,然后对于重叠文本区域,很难能将不同实例区分开来。要真正将该系列算法落地,满足业务需求,未来需解决重叠文本的问题。

    Reference

    [1]. Wang W, Xie E, Li X, et al. Shape robust text detection with progressive scale expansion network[C]//Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition. 2019: 9336-9345.

    [2]. Wang W, Xie E, Song X, et al. Efficient and accurate arbitrary-shaped text detection with pixel aggregation network[C]//Proceedings of the IEEE/CVF International Conference on Computer Vision. 2019: 8440-8449.

    [3]. Xue C, Lu S, Zhang W. Msr: Multi-scale shape regression for scene text detection[J]. arXiv preprint arXiv:1901.02596, 2019.

    [4]. Liao M, Wan Z, Yao C, et al. Real-time scene text detection with differentiable binarization[C]//Proceedings of the AAAI Conference on Artificial Intelligence. 2020, 34(07): 11474-11481.

    想了解更多的AI技术干货,欢迎上华为云的AI专区,目前有AI编程Python等六大实战营(http://su.modelarts.club/qQB9)供大家免费学习。

    点击关注,第一时间了解华为云新鲜技术~

    展开全文
  • 基于可辨识二值化的实时场景文本检测 ​ 图1: 在 msra-td500数据集上对几种最近的场景文本检测方法的准确性和速度进行了比较。我们的方法在有效性和效率之间达到了理想的平衡。 备注: CRAFT:...

    基于可辨识二值化的实时场景文本检测

    文献原文
    image-20211126214149257

    ​ 图1: 在 msra-td500数据集上对几种最近的场景文本检测方法的准确性和速度进行了比较。我们的方法在有效性和效率之间达到了理想的平衡。

    备注:

    • CRAFT:https://blog.csdn.net/qq_39707285/article/details/109037366
    • TextSnake:https://blog.csdn.net/attitude_yu/article/details/86678255
    • Corner:https://blog.csdn.net/qq_34199326/article/details/85273871

    摘要

    基于分割的方法在场景文本检测中非常流行,因为分割结果可以更准确地描述各种形状的场景文本,例如曲线文本。二值化的后处理对于基于分割的检测至关重要,该检测将通过分割方法生成的概率图转换为文本的边界框/区域。本文提出了一个名为微分二值化(DB)的模块,该模块可以在分割网络中执行二值化过程。与DB模块一起进行了优化,分段网络可以自适应地设置二值化的阈值,这不仅简化了后处理,而且还增强了文本检测的性能。基于一个简单的细分网络,我们在五个基准数据集上验证了DB的性能改进,这些数据在检测准确性和速度方面均始终达到最先进的结果。在轻量级的主干网络上,DB的性能改进非常显著。我们可以在检测精度和效率之间寻求理想的折衷方案。具体而言,使用ResNet-18的主干网络,检测器在MSRA-TD500数据集上以62 FPS的速度达到了82.8的F值。

    介绍

    近年来,阅读场景图像中的文本已成为一个活跃的研究领域,在图像、视频理解、视觉搜索、自动驾驶等领域有广泛的实际应用。

    作为场景文本读取的关键组成部分,定位每个文本实例的边界框或区域的场景文本检测仍然是一项艰巨的任务,因为场景文本通常具有各种比例和形状,包括水平、多方向和弯曲文本。基于分割的场景文本检测最近吸引了很多关注,因为它可以描述各种形状的文本,这得益于其在像素级别的预测结果。但是,大多数基于分割的方法都需要复杂的后处理,才能将像素级预测结果分组为检测到的文本实例,从而导致推理过程中花费大量时间。以最近两种最先进的场景文本检测方法为例:PSENet提出了逐步扩展的后处理以提高检测精度;Pixel embedding用于基于分割结果对像素进行聚类,分割结果必须计算像素之间的特征距离。

    现有的大多数检测方法都使用类似于图2所示的后处理流程 :首先,它们设置了固定的阈值,用于将分割网络生成的概率图转换为二进制图像;然后,一些启发式技术(例如像素聚类)用于将像素分组为文本实例。我们的流程旨在将二值化操作插入到分割网络中以进行联合优化。以这种方式,可以自适应地预测图像的每个位置处的阈值,这可以将像素与前景和背景完全区分开。但是,标准的二值化函数不可微,因此,我们提出了一种二值化的近似函数,称为可微分二值化(DB),当与分段网络一起训练时,该函数完全可微化。

    本文的主要贡献是提出了DB可微化的模块,这使得CNN中的二值化过程端到端可训练。通过将用于语义分割的简单网络与所提出的DB模块相结合,提出了一种鲁棒且快速的场景文本检测器。从使用DB模块的性能评估中,发现新的检测器比以前的基于最新分割的方法具有几个突出的优势。

    image-20211126214409205

    ​ 图2: 传统管道(蓝色流)和(红色流)。虚线箭头是仅用于推理的运算符; 实线箭头表示训练和推理中的可导运算符。

    • 新方法在五个场景文本基准数据集(包括水平、多向和弯曲文本)上获得更好了的性能。
    • 新方法比以前的领先方法执行得快得多,因为DB可以提供高度鲁棒的二值化图,从而大大简化了后处理。
    • 使用轻型骨干网络时,DB可以很好地工作,这大大提高了ResNet-18主干网络的检测性能。
    • 由于可以在推理阶段删除DB而不牺牲性能,因此在测试时无需花费额外的内存和时间。

    相关工作

    现有的场景文本检测方法大致可分为两大类: 基于回归的方法和基于分割的方法。

    基于回归的方法是直接回归文本实例的包围盒的一系列模型。文本框(Liao et al. 2017)修改了基于 SSD 的卷积核的锚点和尺度(Liu et al. 2016)用于文本检测。TextBoxes + + (Liao,Shi,and Bai 2018)和 DMPNet (Liu and Jin 2017)应用四边形回归检测多方向文本。SSTD (He et al. 2017a)提出了一种大致识别文本区域的注意机制。RRD (Liao 等人,2018)通过使用旋转不变特征进行分类和旋转敏感特征进行回归,从而将分类和回归分离开来,以更好地处理面向多方向和长文本的内容。EAST (Zhou 等人,2017年)和 DeepReg (He 等人,2017b)是无锚方法,它应用像素级回归为多面向的文本实例。SegLink(Shi、Bai 和 Belongie 2017)回归段边界框并预测它们的链接,以处理长文本实例。DeRPN (Xie et al. 2019b)为了解决场景文本检测中的尺度问题,提出了一种维度分解区域网络。基于回归的方法通常使用简单的后处理算法(例如非最大值抑制)。然而,它们中的大多数仅限于表示不规则形状(如曲线形状)的精确边界框。

    基于分割的方法通常结合像素级预测和后处理算法得到边界框。(Zhang et al. 2016) 通过语义分割和基于 MSER 的算法检测多向文本。(Xue, Lu, and Zhan 2018) 中使用文本边框来分割文本实例,Mask TextSpotter (Lyu et al. 2018a; Liao et al. 2019) 基于 Mask R 以实例分割方式检测任意形状的文本实例 -CNN。PSENet (Wang et al. 2019a) 提出了通过使用不同尺度内核分割文本实例的渐进式尺度扩展。 (Tian et al. 2019) 中提出了像素嵌入来从分割结果中对像素进行聚类。PSENet (Wang et al. 2019a) 和 SAE (Tian et al. 2019) 为分割结果提出了新的后处理算法,导致推理速度较低。相反,我们的方法专注于通过将二值化过程包含在训练阶段来提高分割结果,而不会损失推理速度。

    快速场景文本检测方法侧重于准确性和推理速度。 TextBoxes(Liao et al. 2017)、TextBoxes++(Liao、Shi 和 Bai 2018)、SegLink(Shi、Bai 和 Belongie 2017)和 RRD(Liao et al. 2018)通过遵循以下检测架构实现了快速文本检测 SSD(Liu 等人,2016 年)。EAST (Zhou et al. 2017) 提议应用 PVANet (Kim et al. 2016) 来提高其速度。 它们中的大多数无法处理不规则形状的文本实例,例如弯曲形状。与之前的快速场景文本检测器相比,我们的方法不仅运行速度更快,而且可以检测任意形状的文本实例。

    主要方法

    image-20211128154316690

    图3:我们提出的方法的架构,其中“pred”由一个 3×3 卷积算子和两个步长为 2 的反卷积算子组成。“1/2”、“1/4”、……和“1/32” 表示与输入图像相比的比例。

    备注:

    1. up*2(二倍上采样)怎么实现的?一个简单的邻近插值算法,通过简单的插值进行实现的。

    我们提出的方法的网络结构如图3所示。首先,将输入图像输入到特征金字塔主干网络中。 然后将金字塔特征按相同比例上采样并级联以生成特征F。然后,将特征F用于预测概率图(P)和阈值图(T)。 之后,通过P和F计算近似二值图(B)。在训练期间,对概率图、阈值图和近似二值图进行监督,其中概率图和近似二值图共享相同的监督。 在推断期间,可以通过框公式模块从近似二值图或概率图轻松获得边界框。

    二值化
    标准二值化

    给定一个分割网络生成的概率图image-20211129192036087 ,其中H和W表示图的高度和宽度,必须将其转换为二进制图,其中像素值为 1被视为有效的文本区域。 通常,此二值化过程可以描述如下:

    image-20211128154908206

    其中t是预定义的阈值,(i,j)表示特征图中的坐标点。

    可微分二值化

    等式1中描述的标准二值化是不可微的。 因此,在训练期间无法与分割网络一起对其进行优化。 为了解决这个问题,建议使用近似阶跃函数执行二值化:

    image-20211128155229978

    image-20211128155320235

    ​ 图 4:可微二值化及其导数的图示。 (a) 标准二值化 (SB) 和可微二值化 (DB) 的数值比较。 (b) l+ 的导数。 © l- 的导数。

    其中B^是近似二值图; T是从网络获知的自适应阈值图; k表示放大因子。 k根据经验设置为50。这个近似二值化函数与标准二值化函数相似(见图4) ,但是它是可微的,因此可以在训练期内随着分割网络进行优化。 具有自适应阈值的可微分二值化不仅可以帮助区分文本区域和背景,还可以分离紧密连接的文本实例。一些例子如图7所示。

    DB改进性能的原因可以通过梯度的反向传播来解释。 以二元交叉熵损失为例。定义[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hHTbTOwM-1638185857275)(https://i.loli.net/2021/11/29/puFOLd6vaUrxnQg.png)]作为DB函数,其中 image-20211129192221234 ,那么正标签的损失为l +和负标签的为l−:

    image-20211129192305394

    我们可以很容易地使用链式规则轻松计算损失的微分:

    image-20211129192329282

    l+和l-的导数如图4的(b) © 所示。我们可以从微分中看出:

    (1)梯度由放大因子 k 增加;

    (2)对于大多数错误预测的区域(对于 L+,x < 0;对于 L-,x > 0),梯度的放大是显着的,从而促进优化并有助于产生更独特的预测。

    此外,由于image-20211129192430788,P 的梯度受到 T 的影响并在前景和背景之间重新缩放。

    自适应阈值

    图 1 中的阈值图从外观上类似于 (Xue, Lu, and Zhan 2018) 中的文本边界图。然而,阈值图的动机和用途与文本边界图不同。在图6中显示了有监督和无监督的阈值图。即使没有监督阈值图,阈值图也会突出显示文本边框区域。这表明类似边界的阈值图有利于最终结果。 因此,我们在阈值图上应用了类似边界的监督,以提供更好的监督。 之前的文本边界图用于拆分文本实例,而我们的阈值图用作二值化的阈值。实验部分讨论了有关监督的消融研究。对于用法,(Xue, Lu, and Zhan 2018) 中的文本边界图用于分割文本实例,而我们的阈值图用作二值化的阈值。

    可变形的卷积

    可变形卷积(Dai et al. 2017; Zhu et al. 2019)可以为模型提供一个灵活的接受域,这对于极端纵横比的文本实例尤其有用。继 (Zhu et al. 2019) 之后,调制的可变形卷积应用于 ResNet-18 或 ResNet-50 主干 (He et al. 2016a) 的 conv3、conv4 和 conv5 阶段的所有 3 × 3 卷积层。

    概率图的标签生成

    image-20211128165151010

    ​ 图5:标签生成。 文本多边形的标注以红线显示。 收缩和膨胀的多边形是分别以蓝线和绿线显示。

    概率图的标签生成是受到 PSENet (Wang 等人,2019a)的启发。给定一个文本图像,其文本区域的每个多边形由一组片段描述:

    image-20211129192543506

    n是顶点数,在不同的数据集中可能不同,例如ICDAR 2015数据集为4个,CTW1500数据集为16个。 然后,通过使用Vatti裁剪算法将多边形G缩小为Gs来生成正区域。 收缩的偏移量D是根据原始多边形的周长L和面积A计算得出的:

    image-20211129192558834

    其中r是收缩率,根据经验设置为0.4。

    通过类似的过程,我们可以为阈值图生成标签。 首先,以相同的偏移量D从多边形G收缩到Gd。 我们将Gs和Gd之间的间隙视为文本区域的边界,可以通过计算间隙区域到G中最接近的线段的距离来生成阈值图的标签。

    优化

    损失函数L可以表示为概率图Ls的损失,二进制图Lb的损失和阈值图Lt的损失的加权和:
    在这里插入图片描述
    其中Ls是概率图的损失,Lb是二进制图的损失。 根据各个损失的数值大小,将α和β分别设置为1.0和10。

    image-20211129160637022

    ​ 图 6:有/无监督的阈值图。 (a) 输入图像。 (b) 概率图。 © 没有监督的阈值图。 (d) 有监督的阈值图。

    我们对Ls和Lb采用交叉熵损失。 为了克服正负例的不平衡,在BCE损失中使用了难负例挖掘。在BCE损失中使用了难例挖掘。

    备注:难例挖掘是指,针对模型训练过程中导致损失值很大的一些样本(即使模型很大概率分类错误的样本),重新训练它们.
    维护一个错误分类样本池, 把每个batch训练数据中的出错率很大的样本放入该样本池中,当积累到一个batch以后,将这些样本放回网络重新训练.
    在这里插入图片描述

    Sl 是样本集,其中正负比为1: 3。

    Lt计算为空洞文本多边形Gd中预测与标签之间的L1距离之和:
    在这里插入图片描述

    其中 Rd 是膨胀的 polygon Gd 内像素的一组索引; y *是阈值图的标签。

    在推断期间,我们可以使用概率图或近似二值图来生成文本边界框,从而产生几乎相同的结果。 为了提高效率,我们使用概率图,以便可以除去阈值分支。 框形成过程包括三个步骤:(1)首先将概率图或者近似二值图用恒定阈值(0.2)二值化,得到二值图; (2)从二值图获得连接区域(缩小的文本区域); (3)用Vatti裁剪算法用偏移量D’扩大收缩区域。D '的计算方法为:
    在这里插入图片描述

    其中A0是收缩多边形的面积; L0 是收缩多边形的周长; r 根据经验设置为 1.5。

    实验

    image-20211129160719400

    ​ 图 7:各种形状的文本实例的一些可视化结果,包括弯曲文本、多向文本、垂直文本和长文本行。 对于每个单元,右上角是阈值图; 右下角是概率图。

    image-20211129154331910

    ​ 表 1:不同设置下的检测结果。 “DConv”表示可变形卷积。 “P”、“R”和“F”分别表示准确率、召回率和 f-measure。

    数据集
    1. SynthText是一个由 80 万张图像组成的合成数据集。 这些图像是从 8k 背景图像合成的。 该数据集仅用于预训练我们的模型。
    2. MLT-2017 数据集是一个多语言数据集。 它包括代表 6 种不同脚本的 9 种语言。 该数据集中有 7,200 张训练图像、1,800 张验证图像和 9,000 张测试图像。 我们在微调期间同时使用训练集和验证集。
    3. ICDAR 2015 数据集由 1000 张训练图像和 500 张测试图像组成,由谷歌眼镜以 720 × 1280 的分辨率捕获。文本实例在单词级别进行标记。
    4. MSRA-TD500 数据集是一个包含英文和中文的多语言数据集。 有 300 张训练图像和 200 张测试图像。文本实例在文本行级别进行标记。 遵循之前的方法(Zhou et al. 2017; Lyu et al. 2018b; Long et al.2018),我们包含了来自 HUST-TR400(Yao、Bai 和 Liu 2014)的额外 400 张训练图像。
    5. CTW1500 数据集 CTW1500 (Liu et al. 2019a) 是一个专注于弯曲文本的数据集。 它由 1000 张训练图像和 500 张测试图像组成。 文本实例在文本行级别进行注释。
    6. Total-Text 数据集 Total-Text (Chng and Chan 2017) 是一个包含各种形状的文本的数据集,包括水平、多向和弯曲。 它们是 1255 张训练图像和 300 张测试图像。 文本实例在单词级别进行标记。
    实施细则

    对于所有模型,我们首先使用 SynthText 数据集对它们进行 100k 次迭代预训练。 然后,我们在相应的真实世界数据集上微调模型 1200 个时期。 训练批量大小设置为 16。我们遵循多元学习率策略,其中当前的学习率等于初始学习率乘以 (),其中初始学习率设置为 0.007,幂为 0.9。我们使用 0.0001 的权重衰减和 0.9 的动量。 max_iter 表示最大迭代次数,这取决于最大 epochs。训练数据的数据增强包括: (1) 角度范围为 (-10 , 10 ) 的随机旋转; (2) 随机裁剪; (3) 随机翻转。 所有处理过的图像都被重新调整为 640×640 以提高训练效率。

    在推理期间,我们保持测试图像的纵横比,并通过为每个数据集设置合适的高度来重新调整输入图像的大小。 推理速度是在批处理大小为 1 的情况下测试的,在单个线程中使用单个 1080ti GPU。 推理时间成本包括模型前向时间成本和后处理时间成本。 后处理时间成本约为推理时间的 30%。

    消融研究

    我们对 MSRA-TD500 数据集和 CTW1500 数据集进行了消融研究,以展示我们提出的可微二值化、可变形卷积和不同主干的有效性。 详细的实验结果见表1。

    可微二值化

    在图 1 中,我们可以看到我们提出的 DB 显着提高了两个数据集上 ResNet-18 和 ResNet-50 的性能。 对于 ResNet-18 主干,DB 在 MSRA-TD500 数据集和 CTW1500 数据集上的 F-measure 方面实现了 3.7% 和 4.9% 的性能增益。对于 ResNet-50 主干,DB 带来了 3.2%(在 MSRA-TD500 数据集上)和 4.6%(在 CTW1500 数据集上)的改进。 此外,由于在推理期间可以去除DB,因此速度与没有DB的速度相同。

    可变形卷积

    如图 1 所示,可变形卷积还可以带来 1.5 - 5.0 的性能提升,因为它为主干提供了一个灵活的接收域,而额外的时间成本很小。对于 MSRA-TD500 数据集,可变形卷积使 F-measure 增加 1.5%(使用 ResNet-18)和 5.0%(使用 ResNet-50)。对于 MSRA-TD500 数据集,可变形卷积使 F-measure 增加 1.5%(使用 ResNet-18)和 5.0%(使用 ResNet-50)。 对于 CTW1500 数据集,可变形卷积实现了 3.6%(使用 ResNet-18)和 4.9%(使用 ResNet-50)的改进。

    image-20211129154943136

    ​ 表 2:监督阈值图对 MLT-2017 数据集的影响。 “Thr-Sup”表示对阈值图应用监督。

    阈值图的监督

    尽管有监督和无监督的阈值图在外观上相似,但监督可以带来性能提升。 如表所示。 2,监督在 MLT-2017 数据集上提高了 0.7% (ResNet-18) 和 2.6% (ResNet-50)。

    主干网络

    建议的带有 ResNet-50 主干的检测器的性能比 ResNet-18 更好,但运行速度较慢。 具体来说,最好的 ResNet-50 模型比最好的 ResNet-18 模型好 2.1%(在 MSRA-TD500 数据集上)和 2.4%(在 CTW1500 数据集上),时间成本大约是两倍。

    与以往方法的比较

    我们在五个标准基准上将我们提出的方法与之前的方法进行了比较,包括两个弯曲文本基准、一个多向文本基准和两个长文本行多语言基准。 一些定性结果如图 7 所示。

    image-20211129155434542

    表 3:在 Total-Text 数据集上的检测结果。 括号中的值表示输入图像的高度。 “*”表示多尺度测试。 “MTS”和“PSE”是 Mask TextSpotter 和 PSENet 的缩写。

    image-20211129155517164

    ​ 表 4:在CTW1500 上的检测结果。 带“*”的方法收集自(Liu et al. 2019a)。 括号中的值表示输入图像的高度。

    弯曲文本检测

    我们在两个弯曲文本基准(Total-Text 和 CTW1500)上证明了我们的方法的形状鲁棒性。 如表所示。 3 和表。 4,我们的方法在准确性和速度方面都达到了最先进的性能。 具体来说,“DB-ResNet-50”在 TotalText 和 CTW1500 数据集上的性能比之前的最先进方法高 1.1% 和 1.2%。 “DB-ResNet-50”的运行速度比之前所有的方法都要快,并且可以通过使用 ResNet-18 骨干网进一步提高速度,但性能下降很小。 与最近在 TotalText 上运行 3.9 FPS 的基于分割的检测器(Wang et al. 2019a)相比,“DB-ResNet-50 (800)”快 8.2 倍,“DB-ResNet-18 (800)” 快 12.8 倍。

    多向文本检测

    ICDAR 2015 数据集是一个多方向的文本数据集,包含许多小而低分辨率的文本实例。在选项卡中。 在图 5 中,我们可以看到“DB-ResNet-50 (1152)”在准确度上达到了最先进的性能。 与之前最快的方法(Zhou et al. 2017)相比,“DB-ResNet-50 (736)”在准确度上高出 7.2%,运行速度快两倍。 对于“DB-ResNet-18 (736)”,当 ResNet-18 应用于主干时速度可以达到 48 fps,f-measure 为 82.3。

    image-20211129155804945

    ​ 表 5:在ICDAR 2015 数据集上的检测结果。 括号中的值表示输入图像的高度。 “TB”和“PSE”是 TextBoxes++ 和 PSENet 的缩写。

    多语言文本检测

    我们的方法在多语言文本检测上是稳健的。 如表所示。 6 和表。 7,“DB-ResNet-50”在准确性和速度上优于以前的方法。 对于准确性,“DB-ResNet-50”在 MSRA-TD500 和 MLT-2017 数据集上分别超过了之前最先进的方法 1.9% 和 3.8%。 对于速度,在 MSRA-TD500 数据集上,“DB-ResNet-50”比之前最快的方法(Liao et al. 2018)快 3.2 倍。 使用轻量级主干,“DB-ResNet-18(736)”与之前的最先进方法(Liu et al.2018)(82.8 vs 83.0)相比达到了相当的准确度,并在 在 MSRA-TD500 上,62 FPS,比之前最快的方法(Liao 等人,2018 年)快 6.2 倍。 通过减小输入大小,速度可以进一步加速到 82 FPS(“ResNet-18 (512)”)。

    局限性

    我们的方法的一个限制是它不能处理“文本内的文本”的情况,这意味着一个文本实例在另一个文本实例内。 虽然收缩的文本区域对于文本实例不在另一个文本实例的中心区域的情况有帮助,但当文本实例正好位于另一个文本实例的中心区域时,它就会失败。 这是基于分割的场景文本检测器的常见限制。

    image-20211129160142031

    ​ 表 6: MSRA-TD500 数据集上的检测结果。 括号中的值表示输入图像的高度。

    image-20211129160229469

    表 7: MLT-2017 数据集上的检测结果。 带有“*”的方法收集自(Lyu 等人,2018b)。 在我们的方法中,MLT-2017 数据集中的图像大小被重新调整为 768 × 1024。 “PSE”是 PSENet 的缩写。

    结论

    在本文中,我们提出了一种用于检测任意形状场景文本的新框架,其中包括在分割网络中提出的可微二值化过程(DB)。 实验已经验证,我们的方法(ResNet-50 主干)在速度和准确性方面始终优于五个标准场景文本基准上的最新方法。 特别是,即使使用轻量级主干 (ResNet-18),我们的方法也可以在所有测试数据集上以实时推理速度实现具有竞争力的性能。 将来,我们有兴趣扩展我们的端到端文本识别方法。
    被重新调整为 768 × 1024。 “PSE”是 PSENet 的缩写。

    结论

    在本文中,我们提出了一种用于检测任意形状场景文本的新框架,其中包括在分割网络中提出的可微二值化过程(DB)。 实验已经验证,我们的方法(ResNet-50 主干)在速度和准确性方面始终优于五个标准场景文本基准上的最新方法。 特别是,即使使用轻量级主干 (ResNet-18),我们的方法也可以在所有测试数据集上以实时推理速度实现具有竞争力的性能。 将来,我们有兴趣扩展我们的端到端文本识别方法。

    展开全文
  • paddleocr文本检测模型的训练

    千次阅读 2021-08-05 14:17:26
    为此我这里有一份可以直接用的icdar数据集,链接:百度云盘链接提取码:7j0u 这个数据集里面包含着文本检测和文本识别的数据集,该博客讲述的文本检测模型的训练,文本识别后面会讲,所以也会用到这个数据集。...
  • 文本检测传统文本检测形态学:MSER+NMS深度学习文本检测分类基于候选框的文本检测基于分割的文本检测基于混合的文本检测 传统文本检测 当前应用中面对文本检测会遇到很多难点: 文本图像的背景多样化,很多背景可能...
  • 基于改进EAST算法的文本检测

    千次阅读 2021-11-06 14:19:26
    从图像中高效、精准、全面地提取文本和地理信息坐标等有用知识这一课题,也成为图像处理的一个重要方向。 随着近些年来深度学习技术不断进步发展,对于一些特定场景的图像文本定位任务成为国内外计算机视觉、模式...
  • 注释:文本检测 和 文本识别是两回事。 可能现在已经有 end-to-end的深度神经网络可以将文本检测和识别一起实现,这个要去搜相关的sci论文。 文本检测,是从一张图片中找到文字区域,并用矩形框标注出来。 不做识别...
  • 人工智能大数据与深度学习 公众号:datayx TextFuseNet: Scene Text Detection with Richer Fused Features   自然场景中任意形状文本检测是一项极具挑战性的任务,与现有的仅基于有限特征表示感知文本的文本检测...
  • 最近在查找OCR开源项目时,发现了商汤公司的MMOCR,它和百度公司的PaddleOCR一样都是用于OCR文本检测和识别的开源框架,里面也集成了很多当下比较优秀的检测与识别模型,比如DBNet, CRNN等。之前有用过PaddleOCR,还...
  • 文本检测和文本识别可以分成两个部分; 目前的深度学习方案也有很多端到端的系统。 本质也是计算机视觉中的一种物体检测和识别分支; -- 传统方法用手工特征提取检测是否文本区域; 之后通过传统的机器学习...
  • 特点概述:在这篇文章中,提出了一个快速且精确的场景文本检测方法,该方法取消了一些不必要的步骤(如:候选区域的聚合和词的分割),且它只包含两个阶段,可以在整幅图像中检测任意形状和方向的单词或文本行。...
  • 文本检测和识别综述

    千次阅读 2021-12-13 10:40:15
    在深度学习时代之前,只有少数作品关注任意形状的文本检测。 Shivakumara 等人。 [43] 提出了一种基于四叉树的方法来检测视频中的弯曲文本。 法布里齐奥等人。 [44] 提出将提取的候选文本 CC 分组为一个图形,其中...
  • 针对曲形文本检测任务,基于分割的算法比回归算法的表现更好,但是分割算法都需手工设置二值化的后处理算法,将分割生成的概率图转换成文本的包围框。 提出Differentiable Binarization(DB),可以在分割网络中...
  • CVPR 2020 之文本检测识别论文大盘点

    千次阅读 2020-12-25 14:44:08
    1)场景文本检测(Scene Text Detection),从街景等场景文本中检测文本的位置,2 篇文献均为不规则任意形状文本的检测; 2)场景文本识别(Scene Text Recognition),对场景文本检测得到的结果进行识别,共 4 篇...
  • pytorchOCR之DBnet(多类别文本检测2)

    热门讨论 2021-07-08 17:12:42
    pytorchOCR之DBnet(多类别文本检测2) 上一篇文章这里我们添加了一个类别分支来分类文本类别。这里我们可以换一种思路来做这个分类,假设我们一共有N类,那么我们可以预测N个map来分割文本,这里有点类似ps中的分层...
  • 自然场景下的文本检测和识别OCR概述 最近组里有个项目是关于中国能效标识的数据识别,大概是说希望利用计算机视觉的方法得到下图中的ROI并识别ROI里面的字内容。 我国能效标识制度2005年3月1日开始实施 根据《办法...
  • 现有的文本检测方法主要有两大类,一种是基于回归框的检测方法(基于物体检测的方法),如CTPN,EAST,这类方法很难检测任意形状的文本(曲线文本), 一种是基于像素的分割检测器(基于实例分割的方法),这类方法很难将...
  • 摘要:随着手机、平板等智能移动终端的普及,使用移动设备的摄像头所拍摄的自然场景图像大量涌现。文字,作为人类最具影响力的发明之一,在人类...检测图像中文字所在的位置,将其提取并识别出来对场景图像的分析有着...
  • ... 一:网络简介 ​ 网络结构: ...可微二值化(Differentiable Binarization ) : ...创新点在于对每一个像素点进行自适应二值化,二值化阈值由网络学习,提高文本检测鲁棒。 可微二值化公式如下: .
  • 文本检测(Text Detection)和识别是计算机视觉领域中的两个主要问题,需要从图像中找到自然语言文本的位置并识别出具体的内容,在体育视频分析,自动驾驶,工业自动化等领域具有广泛的应用。随着深度学习的发展,...
  • 再次整理一波文本检测论文,前面写过的就不写了。 这是一个目录TextBPNMotivationPipeline损失函数RSCAMotivationPipeline损失函数NASKMotivationPipelinePCRMotivationPipeline TextBPN 论文全名:Adaptive ...
  • 一 网络优点和总体设计思想 优点:pannet是psenet的优化版本,一方面是...一般来说,基于实例分割的文本检测算法对于靠得很近的文字区域容易粘连到一起,pannet采用了和psenet基本一致的思想,预测文本核心区域和文本
  • 文本检测的难点 背景多样化.自然场景下,文本行的背景可以为任意,同时还会受一些结构相近的背景影响(如栅栏) 文本行形状和方向的多样化.如水平、垂直、倾斜、曲线等 文本行颜色、字体、尺度的多样化 不同程度...
  • 1.首先根据官方文档我们可以很轻易的找到弯曲文本检测模型 由此可见对于弯曲文本检测效果很不错!但是!!!想去和识别模型串联使用时 2.没有办法串联使用,只能换方法了,使用端到端的PGNet算法 链接: ...
  • 计算机视觉系列-文本检测系列算法(1) 目录 文本检测算法原理Top-Down VS Bottom-up文本检测传统方法深度学习方法常规物体检测算法的问题改进方法 文本检测算法原理 Top-Down VS Bottom-up 文本检测传统方法 深度...
  • 文本检测

    2021-03-31 23:31:58
    相比其他目标检测任务,文本目标的长宽比变化大、具有方向性(弯曲) 一、 趋势 1、矩形->四边形 2、英文->多语言 3、端对端->语义、NLP 二、归类 1. 基于回归 CPTN:FRCN+LSTM,空间+时序,优点:...
  • 检测模型训练 官方教程:https://codechina.csdn.net/mirrors/paddlepaddle/paddleocr/-/blob/develop/doc/doc_ch/detection.md 数据集制作:利用OCRLable 对于检测模型 det 进行训练 1. 预训练的检测det模型 Paddle...
  • 计算机视觉系列-文本检测FTSN DMPNet算法(3) 计算机视觉系列-文本检测CTPN、RRPN算法 https://duanzhihua.blog.csdn.net/article/details/113709484 计算机视觉系列-文本检测系列算法 ...目录 FTSN算法FTSN论文FSTN ...
  • 四、总结 在本文中,作者提出了对任意形状文本友好的内核表示,并在此基础上开发了一个端到端的文本检测与识别框架PAN++,通过设计一系列轻量级模块,实现了高效且精确的任意形状文本检测与识别。与其它现有方法...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 332,040
精华内容 132,816
关键字:

文本检测