c语言sscanf函数的用法是什么
304
2022-08-22
【计算机视觉40例】案例24:实例分割
根据分割粒度的不同,可以将图像分割划分为语义分割和实例分割两种形式。
语义分割是指在像素级别进行分类,同类别的像素被划分到同一类中。与目标检测使用方框标注相比较,语义分割更加精细。
实例分割比语义分割更细致,能够将相同类别但是属于不同个体的物体都区分开。
例如,在图1中:
图(a)是图像分类。图(b)是目标检测。此时,识别结果中将对象使用方框标注。图(c)是语义分割,将相同类别的不同个体作为一个识别对象处理。此时,识别精确到像素。图(d)是实例分割,会将相同类别的不同个体区分开。
图1 图像处理比较
实例分割会预测物体的类别,并使用像素级实现模板(mask)来定位图像中不同的实例。
目前,深度学习在实例分割方面的应用主要有Mask RCNN、FCIS、MaskLab、PANet等。本节,我们介绍Mask RCNN的基本原理。
Mask R-CNN将Faster R-CNN和FCN结合起来,实现实例分割,其结构如图2所示。
图2 Mask R-CNN结构图
Faster RCNN使用CNN提取图像特征,接下来使用region proposal network(RPN)获取ROI(Region of Interest,感兴趣区域),然后使用ROI pooling将所有ROI变为固定尺寸大小,最后将ROI传递给全连接层进行回归和分类预测,得到class(类别)和box(Bounding box,边框)。Mask R-CNN在Faster R-CNN的基础上增加了一个FCN分支,专门用来预测每个像素的分割掩膜(Mask、掩码)。
更近一步来说,Mask R-CNN在最初选取具有代表性的300个边框作为最初的候选框,在经过回归、分类预测后进行非极大值抑制,保留其中100个候选框作为最终候选框。最终的输出包含两部分:
候选框:维度是四维的,大小为:(1,1,100,7)表示100个候选框的“类别、置信度、位置”。掩膜:维度是四维的,大小为:(100, 90, 15, 15)表示100个候选框对应的90个对象类的掩膜信息,其中每个掩膜的大小为 15×15。
在Mask R-CNN中,应用到了特征金字塔和感兴趣区域对齐(ROI Align)技术。
1特征金字塔
如图3所示,在特征金字塔网络(Feature Pyramid Network ,FPN)中存在着自下而上、自上而下、侧连接三种结构。左上方是自下而上的金字塔(下采样),它通过卷积模块得到不同尺度的特征图。右上方自上而下的金字塔(上采样),通过1×1卷积(1×1 conv)和2倍的上采样(2×up)过程构建高分辨率特征图,并在每一层做预测。同时,很关键的一点在于,它通过横向连接使用自下而上金字塔中对应的特征图来增强自上而下的特征图。自上而下的上采用过程中,图像虽然看起来越来越不清晰了,但是每一层都有来自左侧自下而上的对应层的侧连接,其语义特征更强了。
图3 特征金字塔(来自于参考文献29)
2 ROI Align
将ROI划分为固定大小的子单元后,要将其进一步划分,然后计算每个子单元的值。但是,存在的问题是,我们所确定的ROI未必恰好与像素值对齐,如图4中的图(a)所示。下面,我们看下如何解决该问题:
传统上,先将图(a)转换到图(c),再转换到图(d)进行解决。首先,在图(c)中,将ROI移动到最近的像素点保证ROI与像素点对齐,这个过程解决了ROI与像素点没有对齐的问题;图(d)中,通过将子单元划分为不同大小(其中一个包含2个像素点、另一个包含4个像素点),解决了内部像素点无法均匀划分的问题。ROI Align采用图(b)的方式解决。其采用临近点取加权均值(双线性插值)的方式,将每一个子单元的值都使用周围像素点的值来合理填充。
图4 ROI Align示意图
程序核心代码如下:
for i in range(number): # 获取类别名称 classID = int(boxes[0, 0, i, 1]) # 获取置信度 confidence = boxes[0, 0, i, 2] # 考虑较大置信度的,将较小的忽略 if confidence > 0.5: # 获取当前候选框的位置(将百分比形式转换为像素值形式) box = boxes[0, 0, i, 3:7] * np.array([W, H, W, H]) (x1, y1, x2, y2) = box.astype("int") # 获取当前候选框(以切片形式从background内截取) box = background[y1: y2, x1: x2] # import random #供下一行random.randint使用 # cv2.imshow("box" + str(random.randint(3,100)),box) #测试各个候选框 # 获取候选框的高度和宽度(可以通过box.shape计算,也可以通过坐标直接计算) # boxHeight, boxWidth= box.shape[:2] boxHeight = y2 - y1 boxWidth = x2 - x1 # 获取当前的模板mask(单个masks的尺度15*15) mask = masks[i, int(classID)] # mask的大小为15*15像素大小,要调整到与候选框一致大小。 mask = cv2.resize(mask, (boxWidth, boxHeight)) # import random #供下一行random.randint使用 # cv2.imshow("maska" + str(random.randint(3,100)),mask) #测试各个候选框 # 阈值处理,处理为二值形式 rst, mask = cv2.threshold(mask, 0.5, 255, cv2.THRESH_BINARY) # import random #供下一行random.randint使用 # cv2.imshow("maskb" + str(random.randint(3,100)),mask) #测试各个实例 #获取mask内的轮廓(实例) contours, hierarchy = cv2.findContours(np.array(mask, np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 设置随机颜色 color = np.random.randint(0, 255, 3) color = tuple ([int(x) for x in color]) #设置为元组,整数 # color是int64,需要转换为int【无法直接使用tuple(color)实现】 # 绘制实例的轮廓(实心形式) cv2.drawContours(box,contours,-1,color,-1) # 输出对应的类别及置信度 msg = "{}: {:.0f}%".format(LABELS[classID], confidence*100) cv2.putText(background, msg, (x1+50, y1 +45), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255,255,255), 2)
运行程序,显示如图5所示,在图中对各个对象进行了实例分割。
图5 运行结果
欢迎大家阅读《计算机视觉40例——从入门到深度学习(OpenCV-Python)》一书中第24章《深度学习应用实践》获取详细内容。
《计算机视觉40例——从入门到深度学习(OpenCV-Python)》在介绍Python基础、OpenCV基础、计算机视觉理论基础、深度学习理论的基础上,介绍了计算机视觉领域内具有代表性的40个典型案例。这些案例中,既有传统的案例(数字识别、答题卡识别、物体计数、缺陷检测、手势识别、隐身术、以图搜图、车牌识别、图像加密、指纹识别等),也有深度学习案例(图像分类、风格迁移、姿势识别、实例分割等),还有人脸识别方面的案例(表情识别、驾驶员疲劳监测、识别性别与年龄等)。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~