当前位置:   article > 正文

yolov5行人检测算法_prepare_yolo_data.sh

prepare_yolo_data.sh

PaddleDetection/pphuman_mot.md at release/2.6 · PaddlePaddle/PaddleDetection · GitHubObject Detection toolkit based on PaddlePaddle. It supports object detection, instance segmentation, multiple object tracking and real-time multi-person keypoint detection. - PaddleDetection/pphuman_mot.md at release/2.6 · PaddlePaddle/PaddleDetectionhttps://github.com/PaddlePaddle/PaddleDetection/blob/release/2.6/deploy/pipeline/docs/tutorials/pphuman_mot.mdGitHub - JialeCao001/PedSurvey: From Handcrafted to Deep Features for Pedestrian Detection: A Survey (TPAMI 2021)From Handcrafted to Deep Features for Pedestrian Detection: A Survey (TPAMI 2021) - GitHub - JialeCao001/PedSurvey: From Handcrafted to Deep Features for Pedestrian Detection: A Survey (TPAMI 2021)https://github.com/JialeCao001/PedSurvey行人检测综述_denghe1122的博客-CSDN博客PART Ifrom: http://www.cnblogs.com/molakejin/p/5708791.html行人检测具有极其广泛的应用:智能辅助驾驶,智能监控,行人分析以及智能机器人等领域。从2005年以来行人检测进入了一个快速的发展阶段,但是也存在很多问题还有待解决,主要还是在性能和速度方面还不能达到一个权衡。近年,以谷歌为首的自动驾驶技术的研发正如火如荼的进行,这也迫https://blog.csdn.net/denghecsdn/article/details/77987627基于FairMOT实现人流量统计 - 飞桨AI Studio本项目基于PaddleDetection FairMOT实现动态场景和静态场景下的人流量统计,提供从 “模型选择→模型优化→模型部署” 的全流程指导,模型可以直接或经过少量数据微调后用于相关任务。 - 飞桨AI Studiohttps://aistudio.baidu.com/aistudio/projectdetail/2421822?channelType=0&channel=0VOC-COCO-MOT20 - 飞桨AI StudioVOC-COCO-MOT20 - 飞桨AI Studiohttps://aistudio.baidu.com/aistudio/datasetdetail/47128

时耕科技-中国领先的商业数智化服务提供商 - 时耕科技时耕科技-中国领先的商业数智化服务提供商https://www.timework.cn/col.jsp?id=157YOLOv5训练自己的数据集(超详细)_yolo数据集_AI追随者的博客-CSDN博客一、准备深度学习环境本人的笔记本电脑系统是:Windows10首先进入YOLOv5开源网址,手动下载zip或是git clone 远程仓库,本人下载的是YOLOv5的5.0版本代码,代码文件夹中会有requirements.txt文件,里面描述了所需要的安装包。本文最终安装的pytorch版本是1.8.1,torchvision版本是0.9.1,python是3.7.10,其他的依赖库按照requirements.txt文件安装即可。...https://blog.csdn.net/qq_40716944/article/details/118188085

yolov5 训练crowded human 【visible body detection】_yolov5训练crowdh_CV-杨帆的博客-CSDN博客使用yolov5训练crowded human中的head与visible bodyhttps://blog.csdn.net/WhiffeYF/article/details/124502681本项目来源于明厨亮灶这样一个背景的视频监控项目,对厨房中是否存在有人场景做一个识别,打算使用yolov5算法。

1.数据集

目前行人检测的数据集包括coco_person,voc_person,mot20/16、17,CrowdHuman , HIEVE,Caltech Pedestrian,CityPersons, CHUK-SYSU,PRW,ETHZ。

2.数据处理

采用coco-voc-mot20数据集,一共是41856张图,其中训练数据37736张图,验证数据3282张图,测试数据838张。

2.1 将上述数据中的train/val/test转成包含图片的txt。

  1. # coding:utf-8
  2. import os
  3. import random
  4. import argparse
  5. parser = argparse.ArgumentParser()
  6. # xml文件的地址,根据自己的数据进行修改 xml一般存放在Annotations下
  7. parser.add_argument('--xml_path', default='/home/imcs/local_disk/D0011/Annotations', type=str, help='input xml label path')
  8. # 数据集的划分,地址选择自己数据下的ImageSets/Main
  9. parser.add_argument('--txt_path', default='dataSet', type=str, help='output txt label path')
  10. opt = parser.parse_args([])
  11. trainval_percent = 0.98 # 剩下的0.02就是测试集
  12. train_percent = 0.9
  13. xmlfilepath = opt.xml_path
  14. txtsavepath = opt.txt_path
  15. total_xml = os.listdir(xmlfilepath)
  16. if not os.path.exists(txtsavepath):
  17. os.makedirs(txtsavepath)
  18. num = len(total_xml)
  19. list_index = range(num)
  20. tv = int(num * trainval_percent)
  21. tr = int(tv * train_percent)
  22. trainval = random.sample(list_index, tv)
  23. train = random.sample(trainval, tr)
  24. file_trainval = open(txtsavepath + '/trainval.txt', 'w')
  25. file_test = open(txtsavepath + '/test.txt', 'w')
  26. file_train = open(txtsavepath + '/train.txt', 'w')
  27. file_val = open(txtsavepath + '/val.txt', 'w')
  28. for i in tqdm(list_index):
  29. # import pdb;pdb.set_trace()
  30. name = Path(total_xml[i]).stem + '\n'
  31. if i in trainval:
  32. file_trainval.write(name)
  33. if i in train:
  34. file_train.write(name)
  35. else:
  36. file_val.write(name)
  37. else:
  38. file_test.write(name)
  39. file_trainval.close()
  40. file_train.close()
  41. file_val.close()
  42. file_test.close()

2.2 将xml数据转成yolo数据格式

  1. sets = ['train', 'val', 'test']
  2. classes = ["person"] # 改成自己的类别
  3. abs_path = os.getcwd()
  4. print(abs_path)
  5. def convert(size, box):
  6. dw = 1. / (size[0])
  7. dh = 1. / (size[1])
  8. x = (box[0] + box[1]) / 2.0 - 1
  9. y = (box[2] + box[3]) / 2.0 - 1
  10. w = box[1] - box[0]
  11. h = box[3] - box[2]
  12. x = x * dw
  13. w = w * dw
  14. y = y * dh
  15. h = h * dh
  16. return x, y, w, h
  17. def convert_annotation(image_id):
  18. in_file = open(abs_path+'/Annotations/%s.xml' % (image_id), encoding='UTF-8')
  19. out_file = open(abs_path+'/Yolo/%s.txt' % (image_id), 'w')
  20. tree = ET.parse(in_file)
  21. root = tree.getroot()
  22. size = root.find('size')
  23. w = int(size.find('width').text)
  24. h = int(size.find('height').text)
  25. for obj in root.iter('object'):
  26. # difficult = obj.find('difficult').text
  27. try:
  28. difficult = obj.find('Difficult').text
  29. except:
  30. difficult = 0
  31. cls = obj.find('name').text
  32. if cls not in classes or int(difficult) == 1:
  33. continue
  34. cls_id = classes.index(cls)
  35. xmlbox = obj.find('bndbox')
  36. b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
  37. float(xmlbox.find('ymax').text))
  38. b1, b2, b3, b4 = b
  39. # 标注越界修正
  40. if b2 > w:
  41. b2 = w
  42. if b4 > h:
  43. b4 = h
  44. b = (b1, b2, b3, b4)
  45. bb = convert((w, h), b)
  46. out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
  47. wd = getcwd()
  48. for image_set in tqdm(sets):
  49. image_ids = [line.strip() for line in open('./dataSet/%s.txt' % (image_set)).readlines()]
  50. list_file = open('%s_yolo.txt' % (image_set), 'w')
  51. for image_id in image_ids:
  52. try:
  53. list_file.write(abs_path + '/JPEGImages/%s.jpg\n' % (image_id))
  54. convert_annotation(image_id)
  55. except:
  56. continue
  57. list_file.close()

2.3 更改数据集名称

../datasets/coco128/images/im0.jpg  # image
../datasets/coco128/labels/im0.txt  # label

yolo会自动的把image换成labels,去找标签名,因此数据集名称要换成labels和images。

2.5 crownhuman数据

使用YOLOv5-Tools中的CrowHuman2YOLO中代码

bash ./prepare_data.sh 608x608

生成了crownhuman-608x608,里面已经是yolo格式了,但是添加到上面的数据集里,还需要一些操作。这其中图片数据:19370,文本数据:19370,其中test数据:4370,train数据:15000.

2.5.1 将image和txt分别提取

  1. import os
  2. import shutil
  3. # 源文件夹路径
  4. source_folder = "/home/imcs/local_disk/crownhuman/crowdhuman-608x608/"
  5. # 目标文件夹路径
  6. target_folder = "/home/imcs/local_disk/crownhuman/images"
  7. # 遍历源文件夹中的所有文件
  8. for filename in os.listdir(source_folder):
  9. file_path = os.path.join(source_folder, filename)
  10. # 如果这是一张图片,则迁移该图片到目标文件夹
  11. if os.path.isfile(file_path) and filename.lower().endswith(('.jpg', '.jpeg', '.png', '.gif')):
  12. shutil.move(file_path, target_folder)
  13. print('Moved image:', file_path)
  14. import os
  15. import shutil
  16. # 源文件夹路径
  17. source_folder = "/home/imcs/local_disk/crownhuman/crowdhuman-608x608/"
  18. # 目标文件夹路径
  19. target_folder = "/home/imcs/local_disk/crownhuman/labels"
  20. # 遍历源文件夹中的所有文件
  21. for filename in os.listdir(source_folder):
  22. file_path = os.path.join(source_folder, filename)
  23. # 如果这是一个txt文件,则迁移该文件到目标文件夹
  24. if os.path.isfile(file_path) and filename.lower().endswith('.txt'):
  25. shutil.move(file_path, target_folder)
  26. # print('Moved txt file:', file_path)

2.5.2 对路径进行更新

  1. import os
  2. # 源 txt 文件路径
  3. source_file = "/home/imcs/local_disk/crownhuman/train.txt"
  4. # 目标 txt 文件路径
  5. target_file = "/home/imcs/local_disk/crownhuman/train_yolo.txt"
  6. # 图片路径前缀(例如:原图路径为 "/path/to/image.jpg",更新后的路径为 "/new_path/to/image.jpg")
  7. prefix = "/home/imcs/local_disk/crownhuman/images"
  8. # 打开源 txt 文件和目标 txt 文件
  9. with open(source_file, 'r') as f, open(target_file, 'w') as t:
  10. # import pdb;pdb.set_trace()
  11. # 逐行读取源 txt 文件中的内容
  12. for line in f:
  13. # 删除每行末尾的换行符
  14. line = line.strip()
  15. # 如果该行内容是一个图片路径,则更新该路径并写入目标 txt 文件
  16. if line.lower().endswith(('.jpg', '.jpeg', '.png', '.gif')):
  17. new_line = os.path.join(prefix, os.path.basename(line))
  18. t.write(new_line + '\n')
  19. print('Updated image path:', line, '->', new_line)
  20. else:
  21. t.write(line + '\n')

2.5.3 对labels中的0标签进行修改,0 表示head,1表示person

  1. import os
  2. input_dir_path = '/home/imcs/local_disk/crownhuman/labels_all'
  3. output_dir_path = '/home/imcs/local_disk/crownhuman/labels'
  4. for filename in os.listdir(input_dir_path):
  5. if not filename.endswith('.txt'):
  6. continue
  7. input_file_path = os.path.join(input_dir_path, filename)
  8. # output_file_path = os.path.join(output_dir_path, filename.replace('.txt', '_processed.txt'))
  9. output_file_path = os.path.join(output_dir_path, filename)
  10. with open(input_file_path) as input_file, open(output_file_path, 'w') as output_file:
  11. for line in input_file:
  12. row = line.strip().split()
  13. label = int(row[0])
  14. if label == 1:
  15. output_file.write(' '.join([row[0].replace("1","0")]+row[1:]) + '\n')
  16. print('Done!')

3.环境安装

python3.7 cuda10.1  

pip install -r requirements

torch==1.8.1_cu101

torchvision==0.9.1_cu101

tqdm==4.64.0

thop==0.1.1.post2207130030

matplotlib==3.2.2

numpy==1.18.5

opencv-python==4.1.1

pillow==7.1.2

pyyaml==5.3.1

requests==2.23.0

scipy==1.4.1

tqdm==4.64.0

tensorboard==2.4.1

pandas==1.1.4

seaborn==0.11.0

升级glic/libstdc++.so.6

Downloading https://ultralytics.com/assets/Arial.ttf to /home/imcs/.config/Ultralytics/Arial.ttf

4.模型

yolov5的官方参数表

 一般考虑在端侧部署的话就用yolov5s,和大模型不少于1b的参数量相比,检测模型的参数量缺少很少。

yolov5代码写的还是很好的,到目前为止,能在k80上分布式DDP无痛跑起来的代码可不多,mm系列都需要稍微改一下。

  1. main->
  2. resume->torch.load(last,map_location='cpu')
  3. DDP->
  4. device=select_device(device)->
  5. dist=init_process_group(backend='nccl' if dist.is_nccl_available else 'gloo')->
  6. train->
  7. callbacks.run('on_pretrain_routine_start')->
  8. model=Model(cfg or ckpt['model'].yaml,ch=3,nc=nc,anchors=hyp.get('anchor')),
  9. to(device)->
  10. = DetectionModel->model=parse_model(yaml)->
  11. = initialize_weights()->
  12. freeze->
  13. optimizer=smart_optimizer(model,opt.optimizer,hyp['lr0'],hyp['momentum'],
  14. hyp['weight_decay'])->
  15. scheduler=lr_scheduler.LambdaLR(optimizer)->
  16. ema=ModelEMA(model)->
  17. train_loader,dataset=create_dataloader(train_pathm...)->
  18. callbacks.run('on_pretrain_routine_end')->
  19. stopper,stop=EarlyStopping()->
  20. compute_loss=ComputeLoss(model)->
  21. callbacks.run('on_train_start')->
  22. callbacks.run('on_train_epoch_start')->
  23. model.train()->
  24. optimizer.zero_grad()->
  25. callbacks.run('on_train_batch_start')->
  26. pred=model(imgs)->
  27. loss,loss_items=compute_loss(pred,target)->
  28. = tcls,tbox,indices,anchor=build_targets(p,target)->
  29. loss.backward()->
  30. callbacks.run('on_train_batch_end')->
  31. scheduler.step()->
  32. callbacks.run('on_train_epoch_end')

4.1 在data下新建一个person.yaml

  1. # Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
  2. path: /home/imcs/local_disk/D0011 # dataset root dir
  3. train: train_yolo.txt # train images (relative to 'path') 118287 images
  4. val: val_yolo.txt # val images (relative to 'path') 5000 images
  5. test: test_yolo.txt # 20288 of 40670 images, submit to https://competitions.codalab.org/competitions/20794
  6. # Classes
  7. nc: 1 # number of classes
  8. names: ['person'] # class names

4.2 在models更新yolov5s.yaml中,把nc改成类别。

4.3 分布式训练

改一下代码中的device参数,0,1,2,3

python -m torch.distributed.launch --nproc_per_node 4 train.py

batch_size=32,yolov5的代码这块写的很好,即便在k80上也不需要很大的改动。

在8卡k80上,上面这种写法出现了问题,在4卡k80上没有错,很奇怪。

在train.py中添加:

  1. import torch.distributed as dist
  2. dist.init_process_group(backend='gloo', init_method='env://')

 在527行注释掉,不让dist初始化两次

# dist.init_process_group(backend="nccl" if dist.is_nccl_available() else "gloo")

在utils的torch_utils.py中

  1. @contextmanager
  2. def torch_distributed_zero_first(local_rank: int):
  3. """
  4. Decorator to make all processes in distributed training wait for each local_master to do something.
  5. """
  6. if local_rank not in [-1, 0]:
  7. torch.distributed.barrier()
  8. yield
  9. if local_rank == 0:
  10. torch.distributed.barrier()

换成torch.distibuted.barrier()

最终运行:

python -m torch.distributed.launch --nproc_per_node=8 --nnodes=1 --node_rank=0 --master_addr=localhost --master_port=22222 train.py 

5. 测试

detect.py

  1. weights/source(支持视频图片url图片集合)/data/imgsz...->
  2. device=select_device()->
  3. model=DetectMultiBackend(weights)->
  4. imgsz=check_img_size(imgsz,stride)->
  5. dataset=LoadImages()->
  6. model.warmup()->
  7. for path,im,im0s,vid_cap,s in dataset->
  8. = path=files[count]->
  9. = cv2.imread/cap_read()->
  10. = letterbox(img0,img_size,stride,auto)[0]->
  11. = img=img.transpose((2,0,1))[::-1]->
  12. = img=np.ascontiguousarray(img)->
  13. pred=model(im,augment)->
  14. pred=non_max_suppression(pred,conf_thres,iou_thres,classes,agnostic_nms,max_det)->
  15. annotator=Annotator()->
  16. annotator.box_label()->
  17. annotator.result()

300轮:metrics/precision:0.83757,metrics/recall:0.749,map_0.5:0.84328,map_0.5:0.95:0.56934

6.部署(c++)

windows/linux(x86)/linux(arm)树莓派

libtorch/openvino/ncnn/onnxruntime/rknn

https://github.com/leeguandong/Yolov5_rknnlite2icon-default.png?t=N6B9https://github.com/leeguandong/Yolov5_rknnlite2 这是我在paddledetection和rknn官方基础上改的,用yolov5在rk3588,使用rknnlite2部署。

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号