FCN源码解读之vis.py

转载自 https://blog.csdn.net/qq_21368481/article/details/80357950

FCN中的vis.py用于测试时输出可视化分割图像,可以选择两种可视化输出,一种为直接可视化的彩色分割图(左图);一种为含有掩膜的分割图(原图与分割彩色图的加权融合,右图)。

 

vis.py源码如下:


   
   
  1. import numpy as np
  2. def make_palette(num_classes):
  3.     """
  4.     Maps classes to colors in the style of PASCAL VOC.
  5.     Close values are mapped to far colors for segmentation visualization.
  6.     See http://host.robots.ox.ac.uk/pascal/VOC/voc2012/index.html#devkit
  7.     Takes:
  8.         num_classes: the number of classes
  9.     Gives:
  10.         palette: the colormap as a k x 3 array of RGB colors
  11.     """
  12.     palette = np.zeros((num_classes, 3), dtype=np.uint8)
  13.     for k in xrange( 0, num_classes):
  14.         label = k
  15.         i = 0
  16.         while label:
  17.             palette[k, 0] |= (((label >> 0) & 1) << ( 7 - i))
  18.             palette[k, 1] |= (((label >> 1) & 1) << ( 7 - i))
  19.             palette[k, 2] |= (((label >> 2) & 1) << ( 7 - i))
  20.             label >>= 3
  21.             i += 1
  22.     return palette
  23. def color_seg(seg, palette):
  24.     """
  25.     Replace classes with their colors.
  26.     Takes:
  27.         seg: H x W segmentation image of class IDs
  28.     Gives:
  29.         H x W x 3 image of class colors
  30.     """
  31.     return palette[seg.flat].reshape(seg.shape + ( 3,))
  32. def vis_seg(img, seg, palette, alpha=0.5):
  33.     """
  34.     Visualize segmentation as an overlay on the image.
  35.     Takes:
  36.         img: H x W x 3 image in [0, 255]
  37.         seg: H x W segmentation image of class IDs
  38.         palette: K x 3 colormap for all classes
  39.         alpha: opacity of the segmentation in [0, 1]
  40.     Gives:
  41.         H x W x 3 image with overlaid segmentation
  42.     """
  43.     vis = np.array(img, dtype=np.float32)
  44.     mask = seg > 0
  45.     vis[mask] *= 1. - alpha
  46.     vis[mask] += alpha * palette[seg[mask].flat]
  47.     vis = vis.astype(np.uint8)
  48.     return vis

源码解读如下:

(1)make_palette()

此函数通过输入的类别数(num_classes)生成一个调色板,每个类别对应一种颜色。


   
   
  1. #生成调色板
  2. def make_palette(num_classes):
  3.     """
  4.     Maps classes to colors in the style of PASCAL VOC.
  5.     Close values are mapped to far colors for segmentation visualization.
  6.     See http://host.robots.ox.ac.uk/pascal/VOC/voc2012/index.html#devkit
  7.     Takes:
  8.         num_classes: the number of classes 输入为类别数目
  9.     Gives:
  10.         palette: the colormap as a k x 3 array of RGB colors 输出为k×3大小的RGB颜色数组
  11.     """
  12.     palette = np.zeros((num_classes, 3), dtype=np.uint8)
  13.     #xrange() 函数用法与 range 完全相同,所不同的是生成的不是一个数组,而是一个生成器
  14.     for k in xrange( 0, num_classes):
  15.         label = k
  16.         i = 0
  17.         while label:  #按一定规则移位产生调色板
  18.             palette[k, 0] |= (((label >> 0) & 1) << ( 7 - i)) #>>为二进制右移
  19.             palette[k, 1] |= (((label >> 1) & 1) << ( 7 - i))
  20.             palette[k, 2] |= (((label >> 2) & 1) << ( 7 - i))
  21.             label >>= 3
  22.             i += 1
  23.     return palette

若输入的num_classes=21,则输出结果如下(每行对应一种颜色,从结果中也可以看出每个类别对应的颜色是不一样的):


   
   
  1. [[ 0 0 0]
  2. [ 128 0 0]
  3. [ 0 128 0]
  4. [ 128 128 0]
  5. [ 0 0 128]
  6. [ 128 0 128]
  7. [ 0 128 128]
  8. [ 128 128 128]
  9. [ 64 0 0]
  10. [ 192 0 0]
  11. [ 64 128 0]
  12. [ 192 128 0]
  13. [ 64 0 128]
  14. [ 192 0 128]
  15. [ 64 128 128]
  16. [ 192 128 128]
  17. [ 0 64 0]
  18. [ 128 64 0]
  19. [ 0 192 0]
  20. [ 128 192 0]
  21. [ 0 64 128]]

(2)color_seg()

此函数所产生的分割图像即如上面的左图。


   
   
  1. #产生一个可视化的类别数组
  2. def color_seg(seg, palette):
  3. """
  4. Replace classes with their colors.
  5. Takes:
  6. seg: H x W segmentation image of class IDs
  7. seg是score层产生的类别图(即每一像素的值是0-(num_classes-1)中的一个)
  8. Gives:
  9. H x W x 3 image of class colors
  10. 生成一张三通道的彩色图(其中每一种颜色对应一种类别),实际生成是H×W×3的数组,需要经过python中但PIL库调用函数Image.fromarray将此数组转化为一张彩色图(详见infer.py最后几行)
  11. """
  12. return palette[seg.flat].reshape(seg.shape + ( 3,)) #按照类别进行上色

(3)vis_seg()

此函数所产生的分割图像即如上面的右图。


   
   
  1. #产生一个可视化的含有分割掩膜数组(即包含原图和分割掩膜但数组,本质上就是两者的加权融合)
  2. def vis_seg(img, seg, palette, alpha=0.5): #alpha为透明度,也即加权融合因子
  3. """
  4. Visualize segmentation as an overlay on the image.
  5. Takes:
  6. img: H x W x 3 image in [0, 255] 原图
  7. seg: H x W segmentation image of class IDs 同color_seg中的seg
  8. palette: K x 3 colormap for all classes 调色板
  9. alpha: opacity of the segmentation in [0, 1] 透明度
  10. Gives:
  11. H x W x 3 image with overlaid segmentation 输出含有掩膜的大小为H×W×3的数组
  12. """
  13. vis = np.array(img, dtype=np.float32) #将图像转换为数组
  14. mask = seg > 0 #产生去除背景(标号为0)的掩膜
  15. vis[mask] *= 1. - alpha #原图像除背景外乘上alpha
  16. vis[mask] += alpha * palette[seg[mask].flat] #加上alpha倍的上色图(也除去了背景)
  17. vis = vis.astype(np.uint8) #强制转化为unchar型(图像像素0-255的限制,所以需要强制转换)
  18. return vis
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值