总结用FCN训练自己数据集(Tensorflow)运行代码中出现的问题及解决办法(一)

想要复现fcn网络,用自己的数据训练网络,本以为网上下载代码会很容易,没想到调试代码用了好几天的时间,总是一些小问题和网上给出的结果不一致,导致代码运行失败,总结原因可能是使用的包版本不同,电脑环境配置不同导致。

1、使用labelme,实现标注,批量转换成想要的图片。参考博客:https://blog.csdn.net/weixin_41319671/article/details/82684334https://blog.csdn.net/fengxin1995/article/details/80511227

(1)使用labelme标注图像,生成.json文件。

(2)将.json文件,转换成文件夹。很多文章都有下面的代码,功能为实现批量执行下面的语句,语句为调用labelme安装带的程序,实现转换。

#coding:utf-8
import os
 
path = 'E:\\data' #path是存放json的路径
json_file = os.listdir(path)
 
for file in json_file:
    os.system("python E:\Anocado\Anocado3\envs\labelme\Scripts\labelme_json_to_dataset.py %s"
              % (path + file))         #使用自己的labelme路径

将C:\Users\Administrator\Anaconda3\envs\labelme\Lib\site-packages\labelme\cli下的json_to_dataset.py,改为下面的代码

import argparse
import base64
import json
import os
import os.path as osp
import warnings

import PIL.Image
import yaml

from labelme import utils


def main():
    warnings.warn("This script is aimed to demonstrate how to convert the\n"
                  "JSON file to a single image dataset, and not to handle\n"
                  "multiple JSON files to generate a real-use dataset.")

    parser = argparse.ArgumentParser()
    parser.add_argument('json_file')
    parser.add_argument('-o', '--out', default=None)
    args = parser.parse_args()

    json_file = args.json_file

    alist = os.listdir(json_file)
    


    for i in range(0,len(alist)):
        path = os.path.join(json_file,alist[i])
        data = json.load(open(path))

        out_dir = osp.basename(path).replace('.', '_')
        out_dir = osp.join(osp.dirname(path), out_dir)

        if not osp.exists(out_dir):
            os.mkdir(out_dir)

        if data['imageData']:
            imageData = data['imageData']
        else:
            imagePath = os.path.join(os.path.dirname(path), data['imagePath'])
            with open(imagePath, 'rb') as f:
                imageData = f.read()
                imageData = base64.b64encode(imageData).decode('utf-8')

        img = utils.img_b64_to_arr(imageData)

        label_name_to_value = {'_background_': 0}
        for shape in data['shapes']:
            label_name = shape['label']
            if label_name in label_name_to_value:
                label_value = label_name_to_value[label_name]
            else:
                label_value = len(label_name_to_value)
                label_name_to_value[label_name] = label_value

        # label_values must be dense
        label_values, label_names = [], []
        for ln, lv in sorted(label_name_to_value.items(), key=lambda x: x[1]):
            label_values.append(lv)
            label_names.append(ln)
        assert label_values == list(range(len(label_values)))

        lbl = utils.shapes_to_label(img.shape, data['shapes'], label_name_to_value)

        captions = ['{}: {}'.format(lv, ln)
                    for ln, lv in label_name_to_value.items()]
        lbl_viz = utils.draw_label(lbl, img, captions)

        PIL.Image.fromarray(img).save(osp.join(out_dir, 'img.png'))
        utils.lblsave(osp.join(out_dir, 'label.png'), lbl)
        PIL.Image.fromarray(lbl_viz).save(osp.join(out_dir, 'label_viz.png'))

        with open(osp.join(out_dir, 'label_names.txt'), 'w') as f:
            for lbl_name in label_names:
                f.write(lbl_name + '\n')

        warnings.warn('info.yaml is being replaced by label_names.txt')
        info = dict(label_names=label_names)
        with open(osp.join(out_dir, 'info.yaml'), 'w') as f:
            yaml.safe_dump(info, f, default_flow_style=False)

        print('Saved to: %s' % out_dir)


if __name__ == '__main__':
    main()

在终端激活labelme环境:activate labelme,打开要保存结果的文件夹,执行语句:labelme_json_to_dataset + (.json文件的文件夹) ,下面的截图中,前5行为打开保存结果的文件夹,然后是激活环境,然后是执行语句。

注意:代码运行中会报错:ModuleNotFoundError: No module named 'labelme',解决办法为:打开labelme环境下的编译器spyder即可解决。过程中还报错:ModuleNotFoundError: No module named 'skimage',解决办法:激活labelme的环境下:conda install scikit-image。总结:在labelme环境下运行代码,安装需要的库要到labelme环境下。

(3)生成对应图片的标注图片,下载https://github.com/hitzoro/FCN-ColorLabel.git文件,修改x.py文件。

import colorlabel
import PIL.Image
import yaml
import os
 
label_color = {
        'crack': 'red',
        '_background_': 'black'
    #这个是你自己的类别和对应的颜色
    #例如,'Dog': 'maroon'
    #注意:这里的颜色需要是下面颜色列表color中的颜色
}
path = 'E:\\testFCNvgg\\prepic\\111\\'	#你执行第二步时的存储路径
label_path = os.listdir(path)
for label_class in label_path:
    img = PIL.Image.open('%s\\label.png' % (path + label_class))
    import numpy as np
    from skimage import io,data,color
    label = np.array(img)
 
    yaml_file = path + label_class + '\\' + 'info.yaml'
    print(yaml_file)
    with open(yaml_file) as f:
        f = yaml.load(f)
        classes = f['label_names']
 
    color = ['red','black'] #颜色列表
    c = 1
    for i in classes:
        if c == 1:
            c = c+1
            continue
 
        color.append(label_color[i])
 
    #print (color)   #颜色列表
    dst = colorlabel.label2rgb(label, colors=(tuple)(color), bg_label = 0,bg_color =(0,0,0))
    #final = PIL.Image.fromarray(np.uint8(dst * 255))
    #final.show()
    #final.save('000001.png')
    save_path =  'E:\\testFCNvgg\\prepic\\1111' + '\\' + label_class[:-5] + '.png'	#你希望将标注图片存储的路径
    #print('11111%s' % save_path)
    io.imsave(save_path, dst)

注意,代码中的路径换成自己的,都是\\,有的还要注意路径的末尾是否加\\,否则报错:SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 9-10: truncated \UXXXXXXXX escape。

(4)转成8位图,https://github.com/xmojiao/deeplab_v2/tree/master/voc2012下载程序:convert_labels.py和utils.py,这里和原博客不一样,原博客代码会报错,推测是版本的问题,修改了部分代码,执行下面的代码即可,注意改成自己的路径。代码保存路径下,建name.txt中,每一行记录一个图片名。

#!/usr/bin/env python
# Martin Kersner, [email protected]
# 2016/01/25 

from __future__ import print_function
import os
import sys
from skimage.io import imread, imsave
from utils import convert_from_color_segmentation

def main():

  ext = '.png'


  #path, txt_file, path_converted = process_arguments(sys.argv)
  path = 'E:\\testFCNvgg\\prepic\\1111\\'
  txt_file='E:\\testFCNvgg\\prepic\\FCN-ColorLabel-master\\FCN-ColorLabel-master\\name.txt'
  path_converted = 'E:\\testFCNvgg\\prepic\\11111'
  # Create dir for converted labels
  if not os.path.isdir(path_converted):
    os.makedirs(path_converted)

  with open(txt_file, 'rb') as f:
    for img_name in f:
      img_base_name = img_name.strip()
      img_name = os.path.join(path, img_base_name.decode()) + ext
      #img_name ='%s.png'%(path+ img_base_name)
      img = imread(img_name)

      if (len(img.shape) > 2):
        img = convert_from_color_segmentation(img)
        imsave(os.path.join(path_converted, img_base_name.decode()) + ext, img)
      else:
        print(img_name + " is not composed of three dimensions, therefore " 
              "shouldn't be processed by this script.\n"
              "Exiting." , file=sys.stderr)

        exit()

def process_arguments(argv):
  if len(argv) != 4:
    help()

  path = argv[1]
  list_file = argv[2]
  new_path = argv[3]

  return path, list_file, new_path 

def help():
  print('Usage: python convert_labels.py PATH LIST_FILE NEW_PATH\n'
        'PATH points to directory with segmentation image labels.\n'
        'LIST_FILE denotes text file containing names of images in PATH.\n'
        'Names do not include extension of images.\n'
        'NEW_PATH points to directory where converted labels will be stored.'
        , file=sys.stderr)
  
  exit()

if __name__ == '__main__':
  main()

注:忘记在哪步了,报错:cannot import name '_validate_lengths',是因为numpy版本不符合导致的,重新安装新的版本:conda install numpy==1.15.0。

猜你喜欢

转载自blog.csdn.net/qq_34585338/article/details/89388995