Tags: ComputerVision

编译

  1. src/caffe/layers/contrastive_loss_layer.cpp:56:30: error: no matching function for call to ‘max(double, float)’
    Dtype dist = std::max(margin - sqrt(dist_sq_.cpu_data()[i]), Dtype(0.0));

Replace line 56 by this one :
Dtype dist = std::max(margin - (float)sqrt(dist_sq_.cpu_data()[i]), Dtype(0.0));

  1. .build_release/lib/libcaffe.so: undefined reference to `cv::imread(cv::String const&, int)'

Change Makefile:
LIBRARIES += glog gflags protobuf leveldb snappy
lmdb boost_system hdf5_hl hdf5 m
opencv_core opencv_highgui opencv_imgproc
add :opencv_imgcodecs

数据处理

  1. median frequency balancing的计算
    图片分割经常会遇到class unbalance的情况,如果你的target是要求每个类别的accuracy 都很高那么在训练的时候做class balancing 很重要,如果你的target要求只要求图片总体的pixel accuracy好,那么class balancing 此时就不是很重要,因为占比小的class, accuray 虽然小,但是对总体的Pixel accuracy影响也较小。
    那么看下本文中的meidan frequency balancing是如何计算的:
    对于一个多类别图片数据库,每个类别都会有一个class frequency, 该类别像素数目除以数据库总像素数目, 求出所有class frequency 的median 值,除以该类别对应的frequency 得到weight:

     

    weighti=median(weights)/weightiweighti=median(weights)/weighti


    这样可以保证占比小的class, 权重大于1, 占比大的class, 权重小于1, 达到balancing的效果.
    如对我自己的数据有两类分别为0,1, 一共55张500500训练图片,统计55张图片中0,1像素的个数:
    count1 227611
    count0 13522389
    freq1 = 227611/(500
    50055) = 0.0166
    freq0 = 13522389/(500
    500*55) = 0.9834
    median = 0.5
    weight1 = 30.12
    weight0 = 0.508
  2. webdemo权重
    作者训练的webdemo和他给出的模型文件的类别数目和label 是对不上号的,因此可以使用webdemo跑测试,但是最好不要在上面finetune, 直接在VGG-16上面finetune 就行

  3. rgb label 转换为 gray label

一些数据集给出的label是rgb的,如下图,但是训练过程中输入网络的label一般是0 - class_num-1标记的label map, 因此需要一个转换过程,下面给出一个python2转换脚本:

 
  1. #!/usr/bin/env python

  2. import os

  3. import numpy as np

  4. from itertools import izip

  5. from argparse import ArgumentParser

  6. from collections import OrderedDict

  7. from skimage.io import ImageCollection, imsave

  8. from skimage.transform import resize

  9.  
  10.  
  11. camvid_colors = OrderedDict([

  12. ("Animal", np.array([64, 128, 64], dtype=np.uint8)),

  13. ("Archway", np.array([192, 0, 128], dtype=np.uint8)),

  14. ("Bicyclist", np.array([0, 128, 192], dtype=np.uint8)),

  15. ("Bridge", np.array([0, 128, 64], dtype=np.uint8)),

  16. ("Building", np.array([128, 0, 0], dtype=np.uint8)),

  17. ("Car", np.array([64, 0, 128], dtype=np.uint8)),

  18. ("CartLuggagePram", np.array([64, 0, 192], dtype=np.uint8)),

  19. ("Child", np.array([192, 128, 64], dtype=np.uint8)),

  20. ("Column_Pole", np.array([192, 192, 128], dtype=np.uint8)),

  21. ("Fence", np.array([64, 64, 128], dtype=np.uint8)),

  22. ("LaneMkgsDriv", np.array([128, 0, 192], dtype=np.uint8)),

  23. ("LaneMkgsNonDriv", np.array([192, 0, 64], dtype=np.uint8)),

  24. ("Misc_Text", np.array([128, 128, 64], dtype=np.uint8)),

  25. ("MotorcycleScooter", np.array([192, 0, 192], dtype=np.uint8)),

  26. ("OtherMoving", np.array([128, 64, 64], dtype=np.uint8)),

  27. ("ParkingBlock", np.array([64, 192, 128], dtype=np.uint8)),

  28. ("Pedestrian", np.array([64, 64, 0], dtype=np.uint8)),

  29. ("Road", np.array([128, 64, 128], dtype=np.uint8)),

  30. ("RoadShoulder", np.array([128, 128, 192], dtype=np.uint8)),

  31. ("Sidewalk", np.array([0, 0, 192], dtype=np.uint8)),

  32. ("SignSymbol", np.array([192, 128, 128], dtype=np.uint8)),

  33. ("Sky", np.array([128, 128, 128], dtype=np.uint8)),

  34. ("SUVPickupTruck", np.array([64, 128, 192], dtype=np.uint8)),

  35. ("TrafficCone", np.array([0, 0, 64], dtype=np.uint8)),

  36. ("TrafficLight", np.array([0, 64, 64], dtype=np.uint8)),

  37. ("Train", np.array([192, 64, 128], dtype=np.uint8)),

  38. ("Tree", np.array([128, 128, 0], dtype=np.uint8)),

  39. ("Truck_Bus", np.array([192, 128, 192], dtype=np.uint8)),

  40. ("Tunnel", np.array([64, 0, 64], dtype=np.uint8)),

  41. ("VegetationMisc", np.array([192, 192, 0], dtype=np.uint8)),

  42. ("Wall", np.array([64, 192, 0], dtype=np.uint8)),

  43. ("Void", np.array([0, 0, 0], dtype=np.uint8))

  44. ])

  45.  
  46.  
  47. def convert_label_to_grayscale(im):

  48. out = (np.ones(im.shape[:2]) * 255).astype(np.uint8)

  49. for gray_val, (label, rgb) in enumerate(camvid_colors.items()):

  50. match_pxls = np.where((im == np.asarray(rgb)).sum(-1) == 3)

  51. out[match_pxls] = gray_val

  52. assert (out != 255).all(), "rounding errors or missing classes in camvid_colors"

  53. return out.astype(np.uint8)

  54.  
  55.  
  56. def make_parser():

  57. parser = ArgumentParser()

  58. parser.add_argument(

  59. 'label_dir',

  60. help="Directory containing all RGB camvid label images as PNGs"

  61. )

  62. parser.add_argument(

  63. 'out_dir',

  64. help="""Directory to save grayscale label images.

  65. Output images have same basename as inputs so be careful not to

  66. overwrite original RGB labels""")

  67. return parser

  68.  
  69.  
  70. if __name__ == '__main__':

  71. parser = make_parser()

  72. args = parser.parse_args()

  73. labs = ImageCollection(os.path.join(args.label_dir, "*"))

  74. os.makedirs(args.out_dir)

  75. for i, (inpath, im) in enumerate(izip(labs.files, labs)):

  76. print(i + 1, "of", len(labs))

  77. # resize to caffe-segnet input size and preserve label values

  78. resized_im = (resize(im, (360, 480), order=0) * 255).astype(np.uint8)

  79. out = convert_label_to_grayscale(resized_im)

  80. outpath = os.path.join(args.out_dir, os.path.basename(inpath))

  81. imsave(outpath, out)

训练结果

基于VGG-16finetune训练的一个模型迭代20000次的测试结果:
图像分割 | 训练集输入labe(mask)处理以及类别不均衡的处理-以segnet为例
label:
图像分割 | 训练集输入labe(mask)处理以及类别不均衡的处理-以segnet为例
基于VGG-16自己数据训练的结果:
图像分割 | 训练集输入labe(mask)处理以及类别不均衡的处理-以segnet为例
label:
图像分割 | 训练集输入labe(mask)处理以及类别不均衡的处理-以segnet为例

测试结果:
图像分割 | 训练集输入labe(mask)处理以及类别不均衡的处理-以segnet为例
---------

Reference

  1. Demystifying Segnet:http://5argon.info/portfolio/d/SegnetTrainingGuide.pdf
  2. https://www.cnblogs.com/vincentcheng/p/9179606.html

相关文章:

  • 2021-12-27
  • 2021-06-06
  • 2022-12-23
  • 2021-12-30
  • 2022-12-23
  • 2022-12-23
  • 2021-11-18
猜你喜欢
  • 2021-07-17
  • 2021-06-04
  • 2021-09-08
  • 2021-04-24
  • 2021-12-12
  • 2022-01-12
相关资源
相似解决方案