我们这里需要用到的是数据标注工具labelimg,和我们文件名称处理程序。
LabelImg 一个图片标注工具.
用Python写成,Qt是图形界面的接口。
标准信息可保存到一个类似于Pascal voc格式你一样的,ImageNet使用的一个XML文件里。
Windows & Linux
macOS. 没有macOS的二进制文件,我们会尽快补充,在此之前,你可以用源码编译.
从源码编译
Linux/Ubuntu/Mac系统上 最低版本 Python 2.6 ,qt的最低版本 PyQt 4.8.
###Ubuntu Linux系统
sudo apt-get install pyqt4-dev-tools
sudo pip install lxml
make qt4py2
python labelImg.py
python labelImg.py [IMAGE_PATH] [PRE-DEFINED CLASS FILE]
sudo apt-get install pyqt5-dev-tools
sudo pip3 install lxml
make qt5py3
python3 labelImg.py
python3 labelImg.py [IMAGE_PATH] [PRE-DEFINED CLASS FILE]
brew install qt qt4
brew install libxml2
make qt4py2
python labelImg.py
python labelImg.py [IMAGE_PATH] [PRE-DEFINED CLASS FILE]
brew install qt # will install qt-5.x.x
brew install libxml2
make qt5py3
python labelImg.py
python labelImg.py [IMAGE_PATH] [PRE-DEFINED CLASS FILE]
新版本Python 3 Virtualenv + Binary 可以避免很多 QT / Python 版本问题,并且给你一个很好的.app文件,还有一个新的 SVG 图标
下载并安装Python 2.6, PyQt4,然后安装 install lxml
打开 cmd and cd 到labelImg 文件夹
pyrcc4 -o resources.py resources.qrc
python labelImg.py
python labelImg.py [IMAGE_PATH] [PRE-DEFINED CLASS FILE]
下载并安装 anaconda (python 3+)
打开cmd and cd 到 labelImg 文件夹
conda install pyqt=4
pyrcc4 -py3 -o resources.py resources.qrc
python labelImg.py
python labelImg.py [IMAGE_PATH] [PRE-DEFINED CLASS FILE]
pip install labelImg
labelImg
labelImg [IMAGE_PATH] [PRE-DEFINED CLASS FILE]
在 Ubuntu 14.04 and 16.04上,我测试了这个PIP命令,但是我么没有在 macOS and Windows上测试
docker run -it \
–user $(id -u) \
-e DISPLAY=unix$DISPLAY \
–workdir=$(pwd) \
–volume="/home/ U S E R : / h o m e / USER:/home/ USER:/home/USER" \
–volume="/etc/group:/etc/group:ro" \
–volume="/etc/passwd:/etc/passwd:ro" \
–volume="/etc/shadow:/etc/shadow:ro" \
–volume="/etc/sudoers.d:/etc/sudoers.d:ro" \
-v /tmp/.X11-unix:/tmp/.X11-unix \
tzutalin/py2qt4
make qt4py2;./labelImg.py
打包下载就避免了我们配置复杂的环境。
在https://tzutalin.github.io/labelImg下,选择是我们需要的版本。
编译并加载以上需要的依赖.
点击’Change default saved annotation folder’ in Menu/File
点击 ‘Open Dir’
点击 ‘Create RectBox’
Click 点击然后释放鼠标左键,就标注了一个矩形
需要时,你可以用右键拖动或者复制这个矩形
标注会被保存到你指定的文件夹里.
你可以用以下快捷键来加速工作流.
在 data/predefined_classes.txt 定义你要训练的类别.
编译安装并加载以上软件.
工具条上 “Save” 按钮的右下方, 点击 “PascalVOC” 按钮 转换为 YOLO 格式.
你可以用 Open/OpenDIR 来打开单张或者多张图片. 当完成一张图片后,点击 save.
yolo 格式时,与图片同名的txt文件会保存在你图片所在文件夹内. 一个名为 “classes.txt” 的文件也会保存在此文件夹里. “classes.txt” 定义了你所指定的类别.
Your label list shall not change in th在处理同一批图片时,标注列不能变。因为当你标注一个图片时classes.txt会被更新,但是前面的标注不会被更新.
YOLO格式时,我不建议你使用"default class" 因为它不会被引用.
YOLO 格式时, “difficult” 标志是无效的.
这里我们最好将图片的名称统一进行处理。我们用到以下的程序。
import os
path = "D:\\VOCdevkit\\VOC2007\\JPEGImages" # 这里修改为图片所保存的文件夹
filelist = os.listdir(path) #该文件夹下所有的文件(包括文件夹)
count=0
for file in filelist:
print(file)
for file in filelist: #遍历所有文件
Olddir=os.path.join(path,file) #原来的文件路径
if os.path.isdir(Olddir): #如果是文件夹则跳过
continue
filename=os.path.splitext(file)[0] #文件名
filetype=os.path.splitext(file)[1] #文件扩展名
Newdir=os.path.join(path,str(count).zfill(6)+filetype) #用字符串函数zfill 以0补全所需位数
os.rename(Olddir,Newdir)#重命名
count+=1
制作VOC格式的数据集,我们需要将文件的格式设置为如下
之后再用我们数据处理的程序对此进行批量的修改。
import xml as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
#我的项目中有5个类别,类别名称在这里修改
classes = [person,flower]
def convert(size, box):
dw = 1./size[0]
dh = 1./size[1]
x = (box[0] + box[1])/2.0
y = (box[2] + box[3])/2.0
w = box[1] - box[0]
h = box[3] - box[2]
x = x*dw
w = w*dw
y = y*dh
h = h*dh
return (x,y,w,h)
def convert_annotation(image_id):
#这里改为xml文件夹的路径
in_file = open('Annotations\\%s.xml'%(image_id))
#这里是生成每张图片对应的txt文件的路径
out_file = open('ImageSet\\Main\\labbel\\%s.txt'%(image_id),'w')
tree=ET.parse(in_file)
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)#
for obj in root.iter('object'):
cls = obj.find('name').text
if cls not in classes :
continue
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox')
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
bb = convert((w,h), b)
out_file.write(str(cls_id) + " " +" ".join([str(a) for a in bb]) + '\n')
#这里是train.txt文件的路径
image_ids_train = open('ImageSet\\Main\\train.txt').read().strip().split()
#这里是val.txt文件的路径
image_ids_val = open('ImageSet\\Main\\val.txt').read().strip().split()
list_file_train = open('boat_train.txt', 'w')
list_file_val = open('boat_val.txt', 'w')
for image_id in image_ids_train:
#这里改为样本图片所在文件夹的路径
list_file_train.write('JPEGImages\\%s.jpg\n'%(image_id))
convert_annotation(image_id)
list_file_train.close()
for image_id in image_ids_val:
#这里改为样本图片所在文件夹的路径
list_file_val.write('JPEGImages\\%s.jpg\n'%(image_id))
convert_annotation(image_id)
list_file_val.close()
以上就是我制作数据/数据集的过程,之后我会在另一篇博客中写出我在制作数据、训练数据、测试数据中遇到的一些问题和自己的想法。如果有什么疑问可以在评论中留言。