EAST文本检测器应用

简介

  1. 最近在做的一个项目中需要对自然场景的文本进行检测,查找文献后发现了一个性能较好的文本检测器——EAST Text Detector,应用这个模型后确实得到了较为鲁棒的效果。

  2. 完全应用这个模型需要配置较多环境(tensorflow、gpu等),后来在一篇外文博客上发现opencv的dnn模块可以加载这个模型并直接应用,这篇博客十分通俗的介绍了如何使用python-opencv应用这一模型。征得原作者允许,我打算介绍我通过这篇博客应用这一模型的过程(和翻译差不多,但有一些自己的想法)。并且欢迎关注该作者的网站pyimagesearch,一个非常不错的深度学习和计算机视觉的入门进阶网站。

性能简要介绍

     模型具体介绍可以点击上面连接进入原论文深入了解,我就不介绍了(主要是我也不太懂)。但博客说该模型特点如下:

  1. 对于720p的视频,在实时状态下可以跑出~13FPS,但可能是在GPU平台。
  2. 在我电脑上实测(联想小新pro13 r5-4600U),一张480x640的图片检测一次(包括nms)平均需要200ms,也就是cpu下~5FPS的速度,还算可以。
  3. 仍然保持高水准(state-of-the-art)的准确率,这倒是不假,效果是可以令人接受的。

模型应用

环境准备

  • Win10
  • python3
  • opencv > 3.0

基本参数

     为了方便应用,我们把这个检测器携程一个类,类名为TexTDetector。

TextDetector.py

import cv2
from object_detection import non_max_suppression
import numpy as np
import time
import global_vars as gv

class TexTDetector:
	# model_path: 模型路径
    def __init__(self, model_path):
    	# 输入网络的图片尺寸(必须为8的倍数)
        self.rw = 320
        self.rh = 320
        # 最小置信度
		self.min_confidence = 0.5

        self.net = cv2.dnn.readNet(model_path)
        self.layerNames = [
            "feature_fusion/Conv_7/Sigmoid",
            "feature_fusion/concat_3"]

     cv2.dnn.readNet可以读取网络,加载模型数据,而我们感兴趣的网络部分:

  • sigmiod给出检测出的文本区域的置信度
  • concat_3给出文本区域对应的几何数据

文本检测函数

    def detect_text(self, image):
        (imgh, imgw) = image.shape[:2]
        # 记录原图像大小与缩小后的比值,得到预测结果后需要乘上这个缩放因子
        rW = imgw / float(self.rw)
        rH = imgh / float(self.rh)
        # 放缩到网络可以接受的尺寸
        image = cv2.resize(image, (self.rw, self.rh))
        # 图像预处理
        blob = cv2.dnn.blobFromImage(image, 1.0, (self.rw, self.rh), (123.68, 116.78, 103.94), swapRB=True, crop=False)
        self.net.setInput(blob)
        # 前向传播,获得置信度和几何数据
        (scores, geometry) = self.net.forward(self.layerNames)

        (rows, cols) = scores.shape[2:4]
        rects = []
        confidences = []

        # 对得到的框进行筛选,先用最小置信度进行粗筛选
        for i in range(rows):
            scoresData = scores[0, 0, i]
            xData0 = geometry[0, 0, i]
            xData1 = geometry[0, 1, i]
            xData2 = geometry[0, 2, i]
            xData3 = geometry[0, 3, i]
            anglesData = geometry[0, 4, i]
            for j in range(cols):
                if scoresData[j] < self.min_confidence:
                    continue

                (offsetX, offsetY) = (j * 4.0, i * 4.0)
                angle = anglesData[j]
                cos = np.cos(angle)
                sin = np.sin(angle)

                h = xData0[j] + xData2[j]
                w = xData1[j] + xData3[j]

                endX = int(offsetX + (cos * xData1[j]) + (sin * xData2[j]))
                endY = int(offsetY - (sin * xData1[j]) + (cos * xData2[j]))
                startX = int(endX - w)
                startY = int(endY - h)

                rects.append((startX, startY, endX, endY))
                confidences.append(scoresData[j])

        # 再使用非极大值抑制算法细筛选
        rects = np.array(rects)
        pick = non_max_suppression(rects, probs=confidences)
        boxes = rects[pick]

        # 得到最终的文本框
        boxes[:, [0, 2]] = (boxes[:, [0, 2]] * rW).astype(np.int32)
        boxes[:, [1, 3]] = (boxes[:, [1, 3]] * rH).astype(np.int32)

        return boxes

    关键地方已有注释。

    注意:这里非极大值抑制(nms)的实现还未给出,正常是没有imutils这个包的,这时候有两个途径:

  1. 直接下载博主实现的图像处理包imutils
pip install imutils
  1. 直接进入imutils的链接,复制 /imuils/object_detection.py 的代码,放在同一文件夹。我也是用这种方式,而且还需要修改一个地方:
# return only the bounding boxes that were picked
	return boxes[pick].astype("int")

改为

	return pick

应用

  1. 下载EAST预训练模型,并与代码放在同一文件夹

  2. 使用demo

import TextDetector as td
import cv2
import os

model_path = r'./frozen_east_text_detector.pb'
textModel = td.TextDetector(model_path)

# 你的图片路径
img_path = r'your image path'

for each in os.listdir(img_path):
	img = cv2.imread(os.path.join(img_path, each))
	try:
		boxes = textModel.detect_text(img)
        for (x, y, ex, ey) in boxes:
            cv2.rectangle(img, (x, y), (ex, ey), (0, 255, 0), 2)
        cv2.imshow('demo', img)
        # 按下esc键退出
		if cv2.waitKey(100) == 27:
			cv2.destroyAllWindows()
			break
	Except IndexError:
		print('no boxes is detected!')	

效果

我还是放我项目的一个小视频吧!

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值