智能标注-半自动化标注实现
2021-01-06 本文已影响0人
YANJINING
随着AI发展的越来越迅速,数据的质量显得尤为重要,特别是在cv行业,数据标注的好坏可以直接决定模型的上限,而数据标注需要耗费大量的人力和物力,为了节约成本问题,解放生产力,推动AI的发展进步,科学家们绞尽脑汁,提出了各种前沿算法,如半监督学习,GAN网络等来解决标注困难带来的问题,国内大厂也开发了AI智能平台来解决这个问题,如百度的EasyDL,华为的ModerArts,通过智能标注可以极大的解放人力物力,节约大约百分之70的标注时间,给工业上带了颠覆性的变化。
本文介绍的半自动标注是基于公司需求开发的,功能跟大厂的技术是有一定差距,这里只是记录一下思路,将方法共享出来,供大家借鉴,有更好的方法欢迎提出,一起探讨。
本文的半自动化标注的思想是,首先需要准备训练数据,然后将每一类的数据抽取一小部分进行人工标注,标注完后投入进我们准备好的基模型中进行训练,训练得出结果后,我们获取结果的类标签(也就是标注中使用的标签)和矩形框四个坐标点,再将图片名字,类标签,坐标点依次写入txt文件中,用于将来制作xml文件,制作好xml文件后,将xml文件和原图片存起来,在labelimg中打开进行人工纠正,接着从未标注数据中选出一部分数据和我们上述得到的数据一起重新投入到模型中继续训练,反复重复此过程,直到精度达到我们心里所期望的一个阈值之后,就把剩余数据和我们得到标注结果的数据都投入到模型中一起训练,最后再进行人工纠正即可。写入txt文件代码如下:
from frcnn import FRCNN
from PIL import Image
import os
frcnn = FRCNN()
path = 'D:/faster-rcnn/img'
res_path = 'D:/faster-rcnn/res/'
for img in os.listdir(path):
filename = os.path.join(path, img)
try:
image = Image.open(filename)
except:
print('Open Error! Try again!')
continue
else:
r_image, box, class_sta, class_num = frcnn.detect_image(image)
with open('D:/fasrer-rcnn/txt/' + img.split('.')[0] + '.txt', 'w') as file:
if len(class_sta) == 1:
file.write(img + ' ')
for i in range(len(box)):
for index, value in enumerate(class_sta):
file.write(value + ' ')
file.write(str(box[i][0]) + ' ')
file.write(str(box[i][1]) + ' ')
file.write(str(box[i][2]) + ' ')
file.write(str(box[i][3]) + ' ' + '\n')
else:
file.write(img + ' ')
for i, value in enumerate(class_num):
file.write(value + ' ')
file.write(str(box[i][0]) + ' ')
file.write(str(box[i][1]) + ' ')
file.write(str(box[i][2]) + ' ')
file.write(str(box[i][3]) + ' ' + '\n')
frcnn.close_session()
txt文件如下:
image.pngshui.txt文件内容如下
shui.jpg a 413 301 437 423
有了这个txt文件之后,我们就可以制作我们自己的xml文件了,代码如下:
import os
import glob
from PIL import Image
# 图像存储位置
src_img_dir = "D:/faster-rcnn-keras-master/img" # 添加你的路径
# 图像的txt文件存放位置
src_txt_dir = "D:/faster-rcnn-keras-master/txt"
src_xml_dir = "D:/faster-rcnn-keras-master/res"
img_Lists = glob.glob(src_img_dir + '/*.jpg')
img_basenames = []
for item in img_Lists:
img_basenames.append(os.path.basename(item))
img_names = []
for item in img_basenames:
temp1, temp2 = os.path.splitext(item)
img_names.append(temp1)
for img in img_names:
im = Image.open((src_img_dir + '/' + img + '.jpg'))
width, height = im.size
# 打开txt文件
gt = open(src_txt_dir + '/' + img + '.txt').read().splitlines()
# 将主干部分写入xml文件中
xml_file = open((src_xml_dir + '/' + img + '.xml'), 'w')
xml_file.write('<annotation>\n')
xml_file.write(' <folder>VOC2007</folder>\n')
xml_file.write(' <filename>' + str(img) + '.jpg' + '</filename>\n')
xml_file.write(' <size>\n')
xml_file.write(' <width>' + str(width) + '</width>\n')
xml_file.write(' <height>' + str(height) + '</height>\n')
xml_file.write(' <depth>3</depth>\n')
xml_file.write(' </size>\n')
# write the region of image on xml file
for img_each_label in gt:
spt = img_each_label.split(' ') # 这里如果txt里面是以逗号‘,’隔开的,那么就改为spt = img_each_label.split(',')。
xml_file.write(' <object>\n')
xml_file.write(' <name>' + str(spt[1]) + '</name>\n')
xml_file.write(' <pose>Unspecified</pose>\n')
xml_file.write(' <truncated>0</truncated>\n')
xml_file.write(' <difficult>0</difficult>\n')
xml_file.write(' <bndbox>\n')
xml_file.write(' <xmin>' + str(spt[2]) + '</xmin>\n')
xml_file.write(' <ymin>' + str(spt[3]) + '</ymin>\n')
xml_file.write(' <xmax>' + str(spt[4]) + '</xmax>\n')
xml_file.write(' <ymax>' + str(spt[5]) + '</ymax>\n')
xml_file.write(' </bndbox>\n')
xml_file.write(' </object>\n')
xml_file.write('</annotation>')
最后,得到xml文件之后,就可以在labelimg里面进行人工纠正了。
有好想法希望各位AI同僚分享出来,一起交流!