以下链接是个人关于LFFD(行人检测)所有见解,如有错误欢迎大家指出,我会第一时间纠正。有兴趣的朋友可以加微信:17575010159 相互讨论技术。若是帮助到了你什么,一定要记得点赞!因为这是对我最大的鼓励,祝你年少且有为! 文 末 附 带 \color{blue}{文末附带} 文末附带 公 众 号 − \color{blue}{公众号 -} 公众号− 海 量 资 源 。 \color{blue}{ 海量资源}。 海量资源。
行人检测0-00:LFFD-史上最新无死角详细解读:https://blog.csdn.net/weixin_43013761/article/details/102592374
思路指导在LFFD这个网络中,数据预处理有着至关重要的作用,所以我们是需要详细的去了解的。其不仅仅是简单的数据增强,下面,大家跟着以下面总结,去阅读源码会比较简单。
负样本采集:
1. 按照10比1的比例,挑选出负样本。
正样本采集:
2. 获得一张正样本图像(正样本最少存在一个box)
4. 随机选择一个正样本中的box,以其为中心点进行随机剪切,然后做数据增强
6. 循环对每个尺寸的box进行处理,其是为了构建对应尺寸的 feature map
8. feature map分为两种:
一种为记录了原图box归一化化的坐标数值,6个通道,前2个标记正负样本,后4个表示左上角和右下角的坐标
一种为mask map,其是一种掩码,也是6个通道,前2个标记正负样本,4四个是一样重复的mask,有box的区域数值为0,没有的区域为1,灰色区域为0~1.
9. 从上面可以知道,一个尺寸的feature map,会对应两个,为源码中的label_batch以及mask_batch
大家大致看一下上面的思路,然后阅读下面的注释(如果不想看代码,也可以直接到末尾看总结)
代码注释该代码的实现文件为pedestrian_detection/data_iterator_farm/multithread_dataiter_for_cross_entropy_v1.py,本人就不粘贴所有代码,大家在看到代码只要关注__prepare_batch()函数就可以了,因为其他的,都是对多进程的处理:
def __prepare_batch(self):
# [batch_size, 3, 480, 480]
im_batch = numpy.zeros((self.batch_size,
self.num_image_channels,
self.net_input_height,
self.net_input_width),
dtype=numpy.float32)
# [(batch_size, 6, 59, 59), (batch_size, 32, 6, 29, 29), (batch_size,, 6, 14, 14), (batch_size, 32, 6, 6, 6)]
label_batch_list = [numpy.zeros((self.batch_size,
self.num_output_channels,
v,
v),
dtype=numpy.float32)
for v in self.feature_map_size_list]
# [(batch_size, 6, 59, 59), (batch_size, 32, 6, 29, 29), (batch_size,, 6, 14, 14), (batch_size, 32, 6, 6, 6)]
mask_batch_list = [numpy.zeros((self.batch_size,
self.num_output_channels,
v,
v),
dtype=numpy.float32)
for v in self.feature_map_size_list]
# 把图像和标签转化为mxnet自带的数据类型
data_batch = DataBatch(self.mxnet_module)
loop = 0
while loop = 0:
# 随机在图片左侧选择一个x值坐标
x_left = random.randint(0, w_interval)
else:
# 要是图片的宽小于480,使用0进行填补
x_pad = int(-w_interval / 2)
# 输入图片初始化为0
im_input = numpy.zeros((self.net_input_height, self.net_input_width, self.num_image_channels),
dtype=numpy.uint8)
# 对于该剪切的图片进行剪切,该填补的的像素使用默认0处理
if h_interval >= 0 and w_interval >= 0:
im_input[:, :, :] = im[y_top:y_top + self.net_input_height, x_left:x_left + self.net_input_width, :]
elif h_interval >= 0 and w_interval 0.5:
im_input = Augmentor.flip(im_input, 'h')
if self.enable_vertical_flip and random.random() > 0.5:
im_input = Augmentor.flip(im_input, 'v')
# 数据增强,对比度,模糊,亮度等等
if random.random() > 0.5:
random.shuffle(self.pixel_augmentor_func_list)
for augmentor in self.pixel_augmentor_func_list:
im_input = augmentor(im_input)
# # display for debug-------------------------------------------------
# cv2.imshow('im', im_input.astype(dtype=numpy.uint8))
# cv2.waitKey()
# 根据mxnet要求进行通道,以及数据类型的转换,
im_input = im_input.astype(numpy.float32)
im_input = im_input.transpose([2, 0, 1])
# 前面都是对一张图片的处理,现在我们要把获得的图像加载到batch_size大小十分之一batch_size中
im_batch[loop] = im_input
# label_batch[(batch_size, 6, 59, 59), (batch_size, 32, 6, 29, 29), (batch_size,, 6, 14, 14), (batch_size, 32, 6, 6, 6)]
for label_batch in label_batch_list:
# 标记为负样本,box以及后面
# 输出的的6个通道,第1个通道标记为1,其余为0
label_batch[loop, 1, :, :] = 1
# mask_batch_list[(batch_size, 6, 59, 59), (batch_size, 32, 6, 29, 29), (batch_size,, 6, 14, 14), (batch_size, 32, 6, 6, 6)]
for mask_batch in mask_batch_list:
# 输出的6个通道,第0和第1个标记为1,其余为0
mask_batch[loop, 0:2, :, :] = 1
else:
# 随机获得一张正样本的图片,以及初始的bboxes
rand_idx = random.choice(self.positive_index)
im, _, bboxes_org = self.data_provider.read_by_index(rand_idx)
# 获得boxes的个数,并且进行一份拷贝
num_bboxes = bboxes_org.shape[0]
bboxes = bboxes_org.copy()
# data augmentation ----
# 如果进行了水平或者或者垂直翻转,则对应的boxes也要进行翻转
if self.enable_horizon_flip and random.random() > 0.5:
im = Augmentor.flip(im, 'h')
bboxes[:, 0] = im.shape[1] - (bboxes[:, 0] + bboxes[:, 2])
if self.enable_vertical_flip and random.random() > 0.5:
im = Augmentor.flip(im, 'v')
bboxes[:, 1] = im.shape[0] - (bboxes[:, 1] + bboxes[:, 3])
# display for debug-------------------------------------------
# im_show = im.copy()
# for n in range(num_bboxes):
# cv2.rectangle(im_show, (int(bboxes[n,0]),int(bboxes[n,1])), (int(bboxes[n,0]+bboxes[n,2]),int(bboxes[n,1]+bboxes[n,3])), (255,255,0), 1)
# cv2.imshow('im_show', im_show)
# cv2.waitKey()
# randomly select a bbox,随机选择一个boxes,这个是为了保证,后续在进行随机剪切的时候,图片中至少存在一个行人box
# 确保其为一个正样本
bbox_idx = random.randint(0, num_bboxes - 1)
# 根据boxes的尺寸大小,选择一个合理的缩放
# randomly select a reasonable scale for the selected bbox (selection strategy may vary from task to task)
target_bbox = bboxes[bbox_idx, :]
# 获得随机选择boxes的长度
longer_side = max(target_bbox[2:])
# 默认bbox_small_list[30, 60, 100, 180]
# 如果小于30则不进行缩放
if longer_side
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?