查看原文
其他

场景文字检测模型PixelLink详解与使用….

gloomyfish OpenCV学堂 2020-02-04

点击上方↑↑↑“OpenCV学堂”关注我

详解PixelLink模型与使用!

觉得不错,请点【在看】支持!

OpenVINO是英特尔推出基于CPU/GPU新一代视觉加速框架,可以对常见的各种检测模型与分割模型在CPU端侧实现10倍以上加速。其自带预训练模型库支持多种常见视觉感知与识别应用场景,可以快速搭建原型演示程序与极简应用。相关视频教程可以点击下面链接学习:

首发 | OpenVINO开发配套视频教程发布了

PixelLink模型详解

OpenVINO支持的场景文字检测是基于PixelLink模型,该模型是浙大联合阿里提出,其核心思想是基于图像分割来实现场景文字检测

比起之前的很多基于检测的场景文字检测模型来说在性能与准确率方面都有比较明显的提升。PixelLink网络模型架构如下:

其中CNN部分采用了VGG16做为特征提取网络,对输出分为两个部分

  • 像素分割,判断每个像素是否为text/non-text

  • 链接预测,对每个像素点八领域进行链接预测,如果是positive则合并为text像素,如果不是则放弃。

通过上述两步之后得到叠加的TEXT图像mask,对mask图像进行连通组件发现或者基于OpenCV的轮廓发现即可得到最终检测框输出。检测框输出分为两种

  • 基于minAreaRect

  • 基于boundingRect

代码实现

代码实现基于OpenVINO Python版本 SDK与OpenCV实现,各步分解代码分别如下:

加载网络

# 加载IR
log.info("Reading IR...")
net = IENetwork(model=model_xml, weights=model_bin)


获取输入层与输出层

# 获取输入输出层
input_blob = next(iter(net.inputs))
outputs = iter(net.outputs)

# 获取多个输出层名称
out_blob = next(outputs)
second_blob = next(outputs)
log.info("Loading IR to the plugin...")
print("pixel output: %s, link output: %s \n"%(out_blob, second_blob))


输入图像,执行推断

in_frame = cv2.resize(image, (w, h))
in_frame = in_frame.transpose((201))  # Change data layout from HWC to CHW
in_frame = in_frame.reshape((n, c, h, w))
exec_net.infer(inputs={input_blob: in_frame})


获取输出

# 获取输出
res1 = exec_net.requests[0].outputs[out_blob]
res2 = exec_net.requests[0].outputs[second_blob]


解析输出生成mask

# 像素分割
for row in range(h):
    for col in range(w):
        pv1 = res1[row, col, 0]
        pv2 = res1[row, col, 1]
        if pv2 > 0.95:
            pixel_mask[row, col] = 255

# 领域链接
for row in range(1, h-11):
    for col in range(1, w-11):
        pv = pixel_mask[row, col]
        if pv == 0:
            continue
        link_mask[row, col] = 255
        # left
        pv1 = res2[row, col, 0]
        pv2 = res2[row, col, 1]
        # left-down
        pv3 = res2[row, col, 2]
        pv4 = res2[row, col, 3]
        # left-up
        pv5 = res2[row, col, 4]
        pv6 = res2[row, col, 5]
        # right
        pv7 = res2[row, col, 6]
        pv8 = res2[row, col, 7]
        # right-down
        pv9 = res2[row, col, 8]
        pv10 = res2[row, col, 9]
        # right-up
        pv11 = res2[row, col, 10]
        pv12 = res2[row, col, 11]
        # up
        pv13 = res2[row, col, 12]
        pv14 = res2[row, col, 13]
        # down
        pv15 = res2[row, col, 14]
        pv16 = res2[row, col, 15]
        if pv1 > 0.5:
            link_mask[row, col-1] = 255
        if pv3 > 0.5:
            link_mask[row+1, col - 1] = 255
        if pv5 > 0.5:
            link_mask[row-1, col - 1] = 255
        if pv7 > 0.5:
            link_mask[row, col + 1] = 255
        if pv9 > 0.5:
            link_mask[row+1, col + 1] = 255
        if pv11 > 0.5:
            link_mask[row+1, col - 1] = 255
        if pv13 > 0.5:
            link_mask[row-1, col] = 255
        if pv15 > 0.5:
            link_mask[row+1, col] = 255


轮廓扫描生成boxes

contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for c in range(len(contours)):
    rect = cv2.minAreaRect(contours[c])
    box = cv2.boxPoints(rect)
    box = np.int0(box)
    print(box)
    cv2.drawContours(image, [box], 0, (00255), 2)

 

运行效果

输入原图

生成的mask区域

最终检测框


往期精华


志合者不以山海为远

道乖者不以咫尺为近


扫码加入OpenCV研习社

系统化学习OpenCV4,解锁更多技能!

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存