0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

什么是图像实例分割?常见的图像实例分割有哪几种?

英特尔物联网 来源:英特尔物联网 作者:英特尔物联网 2021-06-17 11:15 次阅读

实例分割概念

图像实例分割是在对象检测的基础上进一步细化,分离对象的前景与背景,实现像素级别的对象分离。所以图像实例分割是基于对象检测的基础上进一步提升。图像实例分割在目标检测、人脸检测、表情识别、医学图像处理与疾病辅助诊断、视频监控与对象跟踪、零售场景的货架空缺识别等场景下均有应用。很多人会把图像语义分割跟实例分割搞混淆,其实图像的语义分割(Semantic Segmentation)与图像的实例分割(Instance Segmentation)是两个不同的概念,看下图:

pYYBAGDKv6uAYBy_AAB9o95sMt0452.jpg

图-1(来自COCO数据集论文)

左侧是图像语义分割的结果,几个不同的类别人、羊、狗、背景分别用不同的颜色表示;右侧是图像实例分割的结果,对每只羊都用不同的颜色表示,而且把每个对象从背景中分离出来。这个就是语义分割跟实例分割的区别,直白点可以说就是语义分割是对每个类别、实例分割是针对每个对象(多个对象可能属于同一个类别)。

常见的实例分割网络

Mask-RCNN实例分割网络

图像实例分割是在对象检测的基础上再多出个基于ROI的分割分支,基于这样思想的实例分割Mask-RCNN就是其经典代表,它的网络结构如下:

poYBAGDKv6OAFLpIAAEu3WLlC-Q575.jpg

图-2(来自Mask-RCNN的论文)

Mask-RCNN可以简单地认为是Faster-RCNN的基础上加上一个实例分割分支。

RetinaMask实例分割网络

RetinaMask可以看成RetinaNet对象检测网络跟Mask-RCNN实例分割网络的两个优势组合,基于特征金字塔实现了更好的Mask预测,网络结构图示如下:

poYBAGDKv5yACaWHAAEuFuxGlNc218.jpg

图-3(来自RetinaMask论文)

PANet实例分割网络

PANet主要工作是基于Mask-RCNN网络上改进所得,作者通过改进Backbone部分提升了特征提取能力,通过自适应的池化操作得到更多融合特征,基于全链接融合产生mask,最终取得了比Mask-RCNN更好的实例分割效果,该模型的结构如下:

pYYBAGDKv5WAFU5XAAFrIFAWag0086.jpg

图-4(来自PANet论文)

其中全链接特征融合mask分支如下图:

poYBAGDKv4uAQoRpAACclvcVP18135.jpg

图-5(来自PANet论文)

YOLACT实例分割网络

该实例分割网络也是基于RetinaNet对象检测网络的基础上,添加一个Mask分支,不过在添加Mask分支的时候它的Mask分支设计跟RetinaMask有所不同,该网络的结构图示如下:

pYYBAGDKv4WAEUWxAAF74KAjj7A255.jpg

图-6(来自YOLACT作者论文)

CenterMask实例分割网络

该实例网络是基于FCOS对象检测框架的基础上,设计一个Mask分支输出,该Mask分支被称为空间注意力引导蒙板(Spatial Attention Guided Mask),该网络的结构如下:

poYBAGDKv36AKwIOAAEWGfj2k_Q871.jpg

图-7(来自CenterMask论文)

OpenVINO 支持Mask-RCNN模型

OpenVINO 中支持两种实例分割模型分别是Mask-RCNN与YOLACT模型,其中Mask-RCNN模型支持来自英特尔官方库文件、而YOLACT则来自公开的第三方提供。我们这里以官方的Mask-RCNN模型instance-segmentation-security-0050为例说明,该模型基于COCO数据集训练,支持80个类别的实例分割,加上背景为81个类别。

OpenVINO 支持部署Faster-RCNN与Mask-RCNN网络时候输入的解析都是基于两个输入层,它们分别是:

im_data : NCHW=[1x3x480x480]

im_info: 1x3 三个值分别是H、W、Scale=1.0

输出有四个,名称与输出格式及解释如下:

name: classes, shape: [100, ] 预测的100个类别可能性,值在[0~1]之间

name: scores: shape: [100, ] 预测的100个Box可能性,值在[0~1]之间

name: boxes, shape: [100, 4] 预测的100个Box坐标,左上角与右下角,基于输入的480x480

name: raw_masks, shape: [100, 81, 28, 28] Box ROI区域的实例分割输出,81表示类别(包含背景),28x28表示ROI大小,注意:此模型输出大小为14x14

模型实例分割代码演示

因为模型的加载与推理部分的代码跟前面系列文章的非常相似,这里就不再给出。代码演示部分重点在输出的解析,为了简化,我用了两个for循环设置了输入与输出数据精度,然后直接通过hardcode的输出层名称来获取推理之后各个输出层对应的数据部分,首先获取类别,根据类别ID与Box的索引,直接获取实例分割mask,然后随机生成颜色,基于mask实现与原图BOX ROI的叠加,产生了实例分割之后的效果输出。解析部分的代码首先需要获取推理以后的数据,获取数据的代码如下:

float w_rate = static_cast(im_w) / 480.0;

float h_rate = static_cast(im_h) / 480.0;

auto scores = infer_request.GetBlob("scores");

auto boxes = infer_request.GetBlob("boxes");

auto clazzes = infer_request.GetBlob("classes");

auto raw_masks = infer_request.GetBlob("raw_masks");

const float* score_data = static_cast::value_type*>(scores->buffer());

const float* boxes_data = static_cast::value_type*>(boxes->buffer());

const float* clazzes_data = static_cast::value_type*>(clazzes->buffer());

const auto raw_masks_data = static_cast::value_type*>(raw_masks->buffer());

const SizeVector scores_outputDims = scores->getTensorDesc().getDims();

const SizeVector boxes_outputDims = boxes->getTensorDesc().getDims();

const SizeVector mask_outputDims = raw_masks->getTensorDesc().getDims();

const int max_count = scores_outputDims[0];

const int object_size = boxes_outputDims[1];

printf("mask NCHW=[%d, %d, %d, %d] ", mask_outputDims[0], mask_outputDims[1], mask_outputDims[2], mask_outputDims[3]);

int mask_h = mask_outputDims[2];

int mask_w = mask_outputDims[3];

size_t box_stride = mask_h * mask_w * mask_outputDims[1];

然后根据输出数据格式开始解析Box框与Mask,这部分的代码如下:

for (int n = 0; n < max_count; n++) {

float confidence = score_data[n];

float xmin = boxes_data[n*object_size] * w_rate;

float ymin = boxes_data[n*object_size + 1] * h_rate;

float xmax = boxes_data[n*object_size + 2] * w_rate;

float ymax = boxes_data[n*object_size + 3] * h_rate;

if (confidence > 0.5) {

cv::Scalar color(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));

cv::Rect box;

float x1 = std::max(0.0f, xmin), static_cast(im_w));

float y1 = std::max(0.0f, ymin), static_cast(im_h));

float x2 = std::max(0.0f, xmax), static_cast(im_w));

float y2 = std::max(0.0f, ymax), static_cast(im_h));

box.x = static_cast(x1);

box.y = static_cast(y1);

box.width = static_cast(x2 - x1);

box.height = static_cast(y2 - y1);

int label = static_cast(clazzes_data[n]);

std::cout << "confidence: " << confidence << " class name: " << coco_labels[label] << std::endl;

// 解析mask

float* mask_arr = raw_masks_data + box_stride * n + mask_h * mask_w * label;

cv::Mat mask_mat(mask_h, mask_w, CV_32FC1, mask_arr);

cv::Mat roi_img = src(box);

cv::Mat resized_mask_mat(box.height, box.width, CV_32FC1);

cv::resize(mask_mat, resized_mask_mat, cv::Size(box.width, box.height));

cv::Mat uchar_resized_mask(box.height, box.width, CV_8UC3, color);

roi_img.copyTo(uchar_resized_mask, resized_mask_mat <= 0.5);

cv::addWeighted(uchar_resized_mask, 0.7, roi_img, 0.3, 0.0f, roi_img);

cv::putText(src, coco_labels[label].c_str(), box.tl() + (box.br() - box.tl()) / 2, cv::FONT_HERSHEY_PLAIN, 1.0, cv::Scalar(0, 0, 255), 1, 8);

}

}

其中Mask部分的时候有个技巧的地方,首先获取类别,然后根据类别,直接获取Mask中对应的通道数据生成二值Mask图像,添加上颜色,加权混合到ROI区域即可得到输出结果。

责任编辑:lq6

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 图像
    +关注

    关注

    2

    文章

    1083

    浏览量

    40449

原文标题:OpenVINO™ 实现图像实例分割

文章出处:【微信号:英特尔物联网,微信公众号:英特尔物联网】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    图像语义分割的实用性是什么

    图像语义分割是一种重要的计算机视觉任务,它旨在将图像中的每个像素分配到相应的语义类别中。这项技术在许多领域都有广泛的应用,如自动驾驶、医学图像分析、机器人导航等。 一、
    的头像 发表于 07-17 09:56 415次阅读

    图像分割和语义分割的区别与联系

    图像分割和语义分割是计算机视觉领域中两个重要的概念,它们在图像处理和分析中发挥着关键作用。 1. 图像
    的头像 发表于 07-17 09:55 909次阅读

    图像分割与目标检测的区别是什么

    图像分割与目标检测是计算机视觉领域的两个重要任务,它们在许多应用场景中都发挥着关键作用。然而,尽管它们在某些方面有相似之处,但它们的目标、方法和应用场景很大的不同。本文将介绍图像
    的头像 发表于 07-17 09:53 1275次阅读

    图像识别算法哪几种

    图像识别算法是计算机视觉领域的核心技术之一,它通过分析和处理图像数据,实现对图像中的目标、场景和物体的识别和分类。 图像识别算法的发展历程 图像
    的头像 发表于 07-16 11:22 1051次阅读

    图像分割与语义分割中的CNN模型综述

    图像分割与语义分割是计算机视觉领域的重要任务,旨在将图像划分为多个具有特定语义含义的区域或对象。卷积神经网络(CNN)作为深度学习的一种核心模型,在
    的头像 发表于 07-09 11:51 831次阅读

    机器人视觉技术中常见图像分割方法

    、场景理解、导航和交互等任务至关重要。以下是一些常见图像分割方法: 阈值分割法(Thresholding) 阈值分割法是一种基于像素强度的
    的头像 发表于 07-09 09:31 658次阅读

    机器人视觉技术中图像分割方法哪些

    机器人视觉技术是人工智能领域的一个重要分支,它涉及到图像处理、模式识别、机器学习等多个学科。图像分割是机器人视觉技术中的一个重要环节,它的目标是从一幅图像中将目标物体与背景分离出来,以
    的头像 发表于 07-04 11:34 933次阅读

    STM32单片机哪几种常见的开发环境?

    STM32单片机是一款广泛应用于嵌入式系统开发的单片机,针对其开发,以下几种常见的方式:STM32单片机哪几种
    的头像 发表于 05-18 08:04 3033次阅读
    STM32单片机<b class='flag-5'>有</b><b class='flag-5'>哪几种</b><b class='flag-5'>常见</b>的开发环境?

    降噪是什么原理 降噪方法分为哪几种

    降噪是什么原理 降噪方法分为哪几种  降噪是指通过一系列技术手段减少或消除环境中存在的噪声干扰,从而提高音频、图像、信号等的质量或清晰度。降噪的原理主要涉及信号处理、数字滤波、统计学等方面的知识
    的头像 发表于 03-14 16:55 7397次阅读

    变压器的调压方式哪几种

    常见的大功率级别的调压方式哪些? 变压器调压又分为哪几种形式? 调压入合调压出合调压入分调压出分这几个概念分别是什么意思?
    发表于 02-21 15:11

    脉冲信号是指什么?常见的脉冲波形哪几种?分别是什么?

    脉冲信号是指什么?常见的脉冲波形哪几种?分别是什么? 脉冲信号是指信号的幅度在一个瞬时时间内从某个识别幅度快速变化的信号。这种信号常用来传递数字信息或者控制信号。脉冲信号的特点是幅度突变大、时间短
    的头像 发表于 02-05 15:52 9911次阅读

    什么是串行端口?哪几种分类?

    什么是串行端口?哪几种分类? 串行端口是计算机中用于进行数据传输的一种接口类型,通过单一的数据线逐位地传输数据。与串行端口相对应的是并行端口,与串行端口不同,它使用多条数据线同时传输数据。 串行
    的头像 发表于 02-02 15:40 2074次阅读

    改进棉花根系图像分割方法

    棉花是锦葵科棉属植物,棉花生产的纤维是我国各类衣服、家具布和工业用布的材料,目前我国的棉花产量也非常高,主要以新疆地区为主。根系是植物组成的重要部分,其生长发育至关重要。 根系图像分割是根系表型分析
    的头像 发表于 01-18 16:18 295次阅读

    机器视觉的图像目标识别方法操作要点

    通过加强图像分割,能够提高机器视觉的图像目标识别的自动化水平,使得图像目标识别效果更加显著。图像分割
    发表于 01-15 12:17 433次阅读

    【爱芯派 Pro 开发板试用体验】+ 图像分割和填充的Demo测试

    上进行了训练——准确地说,在1100万张图像中,超过10亿个掩码。这是一个相当大的数字。即便如此,SAM 如何知道要在图像分割出哪些对象?我们需要提示SAM精确细分哪个区域。目前版
    发表于 12-26 11:22