如何使用pspnet训练出仪表的指针和表盘
第一步先打标,打标之前先安装labelme,这里我用的labelme版本是3.16.7
pip install labelme==3.16.7
然后在终端桥labelme 打开labelme的界面
如下:
把表盘的部分和指针的部分分别用pan和zhen来表示,我标注了1700多张图片数据,然后需要把json文件和图片整理成voc的数据格式。这是一段 json_to_dataset.py的文件,在很多github仓库中都能找到,我用的代码地址是这个github
代码如下:
import argparseimport base64import jsonimport osimport os.path as ospimport warningsimport numpy as npimport PIL.Imageimport yamlfrom labelme import utils'''我使用的labelme版本是3.16.7,建议使用该版本的labelme,有些版本的labelme会发生错误此处生成的标签图是8位彩色图,每个像素点的值就是这个像素点所属的种类'''if __name__ == '__main__':jpgs_path = "datasets/JPEGImages"pngs_path = "datasets/SegmentationClass"#classes = ["_background_","aeroplane", "bicycle", "bird", "boat", "bottle", "bus", "car", "cat", "chair", "cow", "diningtable", "dog", "horse", "motorbike", "person", "pottedplant", "sheep", "sofa", "train", "tvmonitor"]classes = ["_background_","pan","zhen"]count = os.listdir("./datasets/before/") for i in range(0, len(count)):path = os.path.join("./datasets/before", count[i])if os.path.isfile(path) and path.endswith('json'):data = json.load(open(path))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 denselabel_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)PIL.Image.fromarray(img).save(osp.join(jpgs_path, count[i].split(".")[0]+'.jpg'))new = np.zeros([np.shape(img)[0],np.shape(img)[1]])for name in label_names:index_json = label_names.index(name)index_all = classes.index(name)new = new + index_all*(np.array(lbl) == index_json)utils.lblsave(osp.join(pngs_path, count[i].split(".")[0]+'.png'), new)print('Saved ' + count[i].split(".")[0] + '.jpg and ' + count[i].split(".")[0] + '.png')
处理成voc的数据格式以后,第二步我们需要对数据进行分类,分为训练集和验证集。
分类的代码如下
import osimport random random.seed(0)segfilepath=r'./datasets/VOC/SegmentationClass'saveBasePath=r"./datasets/VOC/ImageSets/Segmentation/"#----------------------------------------------------------------------## 想要增加测试集修改trainval_percent# 修改train_percent用于改变验证集的比例#----------------------------------------------------------------------#trainval_percent=1train_percent=0.9temp_seg = os.listdir(segfilepath)total_seg = []for seg in temp_seg:if seg.endswith(".png"):total_seg.append(seg)num=len(total_seg) list=range(num) tv=int(num*trainval_percent) tr=int(tv*train_percent) trainval= random.sample(list,tv) train=random.sample(trainval,tr) print("train and val size",tv)print("traub suze",tr)ftrainval = open(os.path.join(saveBasePath,'trainval.txt'), 'w') ftest = open(os.path.join(saveBasePath,'test.txt'), 'w') ftrain = open(os.path.join(saveBasePath,'train.txt'), 'w') fval = open(os.path.join(saveBasePath,'val.txt'), 'w') for i in list: name=total_seg[i][:-4]+'\n' if i in trainval: ftrainval.write(name) if i in train: ftrain.write(name) else: fval.write(name) else: ftest.write(name) ftrainval.close() ftrain.close() fval.close() ftest .close()
接着按着voc的数据目录格式把训练的数据丢进去
数据目录格式,然后替换掉原来工程的
然后执行训练就可以了
python train.py
训练过程如图所示,收敛就好
如果觉得《利用语义分割算法做指针式仪表的读数识别》对你有帮助,请点赞、收藏,并留下你的观点哦!