• 【计算机视觉40例】案例23:语义分割


    导读】本文是专栏《计算机视觉40例简介》的第23个案例《语义分割》。该专栏简要介绍李立宗主编《计算机视觉40例——从入门到深度学习(OpenCV-Python)》一书的40个案例。

    目前,该书已经在电子工业出版社出版,大家可以在京东、淘宝、当当等平台购买。

    大家可以在公众号“计算机视觉之光”回复关键字【案例23】获取本文案例的源代码及使用的测试图片等资料。

    针对本书40个案例的每一个案例,分别录制了介绍视频。如果嫌看文字版麻烦,可以关注公众号“计算机视觉之光”直接观看视频介绍版。

    本文简要介绍了本案例的一些基础知识,更详细的理论介绍、代码实现等内容请参考《计算机视觉40例简介》第24章《深度学习应用实践》以获取更详细信息。

    根据分割粒度的不同,可以将图像分割划分为语义分割和实例分割两种形式。

    语义分割是指在像素级别进行分类,同类别的像素被划分到同一类中。与目标检测使用方框标注相比较,语义分割更加精细。

    实例分割比语义分割更细致,能够将相同类别但是属于不同个体的物体都区分开。

    例如,在图1中:

    1. 图(a)是图像分类。
    2. 图(b)是目标检测。此时,识别结果中将对象使用方框标注。
    3. 图(c)是语义分割,将相同类别的不同个体作为一个识别对象处理。此时,识别精确到像素。
    4. 图(d)是实例分割,会将相同类别的不同个体区分开。

     

    图1  图像处理比较

    语义分割将图像内的每一个像素划分到一个类别中,是像素级别的分类任务。与图像分类和目标检测相比,语义分割需要精确到每一个像素,因此图像本身的分辨率和计算效率都是非常关键的问题。与传统方法相比,基于神经网络实现的语义分割在精度有了较大提升,但是深度神经网络中的众多参数导致运算时间过长。因此,如何取得在计算精度和实时性上的平衡是一个非常关键的问题。语义分割具有非常重要的实用价值,在自动驾驶、机器人、医疗影像分析、地理信息系统(GIS)等领域都发挥着非常关键的作用。

    目前,语义分割的主要模型有FCN、SegNet、DeepLab、Refine、NetPSPNet等。这里,我们以FCN为例进行简单介绍。

    FCN是指Fully Convolutional Networks(全卷积网络)。

    如图2所示,其中上部的网络是传统的CNN网络,下部的网络是FCN。在上部的传统CNN结构中,前5层是卷积层,第6层和第7层分别是一个长度为4096的一维向量,第8层是长度为1000的一维向量,分别对应1000个类别的概率。最后的输出表示输入图像属于每一类的概率,其在“tabby cat”这一类统计概率最高。而在下部的FCN中,将传统CNN中的全连接层转化成一个个的卷积层,即将CNN的最后3层表示为卷积层,卷积核的大小(通道数,宽,高)分别为(4096,1,1)、(4096,1,1)、(1000,1,1)。在FCN中,所有的层都是卷积层,故称为全卷积网络。同时,FCN的输出不再是类别而是热力图(heatmap)。

     

    图2  传统的CNN网络与FCN网络对比

    传统的CNN通过卷积和池化操作,实现的是下采样,让图像不断地缩小尺寸、降低分辨率。而语义分割要实现的是针对像素级别的分割,所以还需要一个上采样的效果,将下采样的结果还原到输入图像的分辨率。在FCN中,使用到了反卷积(转置卷积)和反池化操作,将输入图像在经过常规CNN操作后的结果还原分辨率,FCN结构如图3所示。

     

    图3  FCN网络

    程序核心代码如下:

    1. # =================模型推理过程=================
    2. model="fcn8s-heavy-pascal.caffemodel"
    3. config="fcn8s-heavy-pascal.prototxt"
    4. net = cv2.dnn.readNet(model, config)
    5. blob = cv2.dnn.blobFromImage(image, 1.0, (W,H), (0, 0, 0), False, crop=False)
    6. net.setInput(blob)
    7. score = net.forward()
    8. #=============根据推理结果,将每个像素用其所属类颜色构建一个新的模板mask=================
    9. classIDS = np.argmax(score[0], axis=0) #获取每个像素点所属的分类ID
    10. print(classIDS.shape)
    11. # 根据classIDS确定模板mask
    12. # 每个像素点的颜色为色卡所指定的颜色(色卡颜色来源于classesCOLORS)
    13. mask = np.stack([classesCOLORS[index] for index in classIDS.flatten()])
    14. mask = mask.reshape(H, W, 3) #调整模板mask为图像的尺寸大小
    15. result =cv2.addWeighted(image,0.2,mask,0.8,0) #将图像image和模板mask进行加权和计算

    运行程序,显示如图4所示,在图中对各个对象进行了语义分割。

     

    4  运行结果

    欢迎大家阅读《计算机视觉40例——从入门到深度学习(OpenCV-Python)》一书中第24章《深度学习应用实践》获取详细内容。

    《计算机视觉40例——从入门到深度学习(OpenCV-Python)》在介绍Python基础、OpenCV基础、计算机视觉理论基础、深度学习理论的基础上,介绍了计算机视觉领域内具有代表性的40个典型案例。这些案例中,既有传统的案例(数字识别、答题卡识别、物体计数、缺陷检测、手势识别、隐身术、以图搜图、车牌识别、图像加密、指纹识别等),也有深度学习案例(图像分类、风格迁移、姿势识别、实例分割等),还有人脸识别方面的案例(表情识别、驾驶员疲劳监测、识别性别与年龄等)。

     

  • 相关阅读:
    Swift之深入解析Sendable和@Sendable闭包代码实例
    MySQL8.0学习记录17 -Create Table
    面试:单例模式VS静态方法
    详解:生产线平衡改善的四大方法与八大步骤!
    web3.0 nft 是什么? nft的意义是什么?
    Linux命令记载
    Intel® Hyper-Threading Technolog 超线程技术
    SQL关于日期的计算合集
    快手如何快速的进行引流,并且推荐几款我正在用的工具。
    Linux内核顶层Makefile的make过程总结
  • 原文地址:https://blog.csdn.net/superdont/article/details/126262127