资料增量 (Data Augmentation) 的部份因为 YOLOV3 可以透过 cfg 档的设定来自动进行资料增量,所以我们就不在这边进行资料增量的前置处理。
接着进行的是图片标签 (Labeling/Annotation) 的动作,这是一个很乏味的动作,主要就是把原始图片中要训练的图片标示出来,并说明标示物件标签,而把这些资讯存成文字档。光是标签就可以分成三类需要考虑的因素:
图 1、 使用边界框来标注物件 (Original Photo by Patricia Jekki on Unsplash)
很明显的,使用关键点和界标的标注对於检测面部特徵、面部表情、情绪、人体部位和姿势很有用。
图 2、 使用关键点和界标来标注物件 (Original Photo from COCO dataset)
COCO format
annotation{
"id" : int,
"image_id": int,
"category_id": int,
"segmentation": RLE or [polygon],
"area": float,
"bbox": [x,y,width,height],
"iscrowd": 0 or 1,
}
categories[{
"id": int,
"name": str,
"supercategory": str,
}]
Pascal VOC
<annotation>
<folder>Train</folder>
<filename>01.png</filename>
<path>/path/Train/01.png</path>
<source>
<database>Unknown</database>
</source>
<size>
<width>224</width>
<height>224</height>
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>36</name>
<pose>Frontal</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<occluded>0</occluded>
<bndbox>
<xmin>90</xmin>
<xmax>190</xmax>
<ymin>54</ymin>
<ymax>70</ymax>
</bndbox>
</object>
</annotation>
而 YOLO 的格式如下所示,每一行代表一个物件,分别表示物件名称 (object-class),物件中心 x 位在整张图片宽 (image_width) 的比例,物件中心 y 位在整张图片高 (image_height) 的比例,物件宽度 (target_width) 占整张图片宽度 (image_width) 的比例,物件长度 (target_height) 占整张图片长度 (image_height) 的比例。物件中心点座标 (x,y),物件的
<object-class> <x_iw_ratio> <y_ih_ratio> <tw_iw_ratio> <th_ih_ratio>
两者的换算公式如下:
# Pascal VOC
ymin, xmin, ymax, xmax, image_w, image_h = PascalVOC
# 将 Pascal VOC 中的资料转换成 YOLO 格式
(x_iw_ratio, y_ih_ratio) = ( ( (xmin + xmax) * 0.5 ) / image_w, ((ymin + ymax) * 0.5 ) / image_h)
tw_iw_ratio = (xmax - xmin) * 1. / image_w
th_ih_ratio = (ymax - ymin) * 1. / image_h
这边就不介绍如何使用 labelImg,可以参阅 目标检测使用LabelImg标注VOC数据格式和YOLO数据格式——LabelImg使用详细教程,这边先测试当取得标签档时,如何确认标签档是否可以正确的在图片上生成边界框。
下图是我们标签了下方的两只鱼,而 YOLO 标签内容如下,通常我们不会把物件名称直接打出来,因为这只是对应之用,所以我们给定标签为 0。
00-frame-0001.txt
0 0.962963 0.447917 0.414815 0.137500
0 0.263889 0.422917 0.416667 0.122917
图 3、标签後的图片
接着我们试着根据 YOLO 的标签内容,将 YOLO 格式转换成边界框的左上角 (min_x, min_y) 和右下角 (max_x, max_y),重新画上边界框,以确保标签内容的正确性。
./utils/yoloDrawLabel.py
import cv2
# 设定输入与输出
inputLabelPath = '../labels/00-frame-0001.txt'
inputImgPath = '../images/00-frame-608x608-0001.jpg'
outputImgPath = '../labels/00-frame-608x608-0001.jpg'
# 图片大小固定为 608*608
img_w= img_h = 608
# 载入图片
cv2image = cv2.imread(inputImgPath)
with open(inputLabelPath) as f:
for line in f:
line = line.strip() # 删除多余的空白
data = line.split() # 将 YOLO 一列的内容转成一维阵列
# 将 YOLO 格式转换为边界框的左上角和右下角座标
bbox_width = float(data[3]) * img_w
bbox_height = float(data[4]) * img_h
center_x = float(data[1]) * img_w
center_y = float(data[2]) * img_h
min_x, min_y = center_x - (bbox_width / 2), center_y - (bbox_height / 2)
max_x, max_y = center_x + (bbox_width / 2), center_y + (bbox_height / 2)
print(min_x,min_y,max_x,max_y)
# 在图片上写上物件名称
cv2.putText(cv2image, 'Altolamprologus compressiceps', (int(min_x), int(min_y-6)), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 1, cv2.LINE_AA)
# 画出边界框
cv2.rectangle(cv2image, (int(min_x),int(min_y)), (int(max_x),int(max_y)), (0,255,255), 2)
# 将档案另存新图片档
cv2.imwrite(r'{}'.format(outputImgPath), cv2image)
f.close()
下图为输出结果,可以确认 YOLO 文字档中的内容是正确的。
图 4、读取 YOLO 文件档验证标签是否正确的图片
<<: Day 8 - 拯救落後的专案能撑一天是一天(後端篇)
>>: 新新新手阅读 Angular 文件 - Get data from a server(3) - Day12
直接安装postgres 选择电脑系统,我这边使用win10 按下紫字 选择最新版本 开始安装一直按...
在Java程序设计中,有一个较为快速创造阵列的方法ArrayList,有别於固定大小的Array,A...
缘由: 因Jcenter将不再对一般客户端提供服务,官方建议将远程仓库迁移至mavenCenter,...
影片损毁发生的原因很多,尤其是在视频拷贝和视频录制的过程中,意外总是偷偷的就发生了。一般情况下,一但...
所有的问题都不简单 在你所有认为很基本的问题,对实习生来说都不简单。想想我之所以会认为理所当然很简单...