赞
踩
基本思想:进行是数据集的预处理和标注,然后进行分开目标检测训练和关键点训练,然后增加追踪逻辑
一、标注关键点数据,这里标注只是使用标注检测框和关键点即可,在本质上也可以不用标注检测框,因为个人的数据集是鱼类,可以通过全身的关键点拟合成检测框,提供标注数据集,然后进行提取两类数据集一类为关键点数据集(coco),另一类为检测类数据集(yolov5/7)
标注完数据之后,进行提取目标检测数据集和关键点数据集,(等待第一版模型出现,做自动化标注,全部以python调用onnx完成开发)代码:
- import numpy as np
- import json
- import glob
- import codecs
- import os
- import cv2
- import json
- import shutil
- import os
- from xml.dom.minidom import Document
-
-
- class MyEncoder(json.JSONEncoder):
- def default(self, obj):
- if isinstance(obj, np.integer):
- return int(obj)
- elif isinstance(obj, np.floating):
- return float(obj)
- elif isinstance(obj, np.ndarray):
- return obj.tolist()
- else:
- return super(MyEncoder, self).default(obj)
-
-
- class Tococo(object):
- def __init__(self, Path, save_path, labelimg_path, keypoints, skeleton, label, verify_flag, verify_path,
- inital_start_id, verify_labelimg_flag, supercategory):
- self.labelimg_path = labelimg_path
- self.verify_flag = verify_flag
- self.label = label
- categories = {}
- categories.update({"supercategory": supercategory})
- categories.update({"id": 0})
- categories.update({"name": label})
- categories.update({"keypoints": keypoints})
- self.keypoints_length = len(keypoints)
- self.inital_start_id = inital_start_id
- categories.update({"skeleton": skeleton})
- self.categories = [categories]
- self.imagePath = None
- self.imageData = None
- self.imageHeight = None
- self.imageWidth = None
- self.imageName = None
- self.imageName_Noext = None
- self.image = []
- self.annotations = []
- self.jsonfile = glob.glob(os.path.join(Path, "*.json"))
- self.ext = "png"
- self.imgfile = glob.glob(os.path.join(Path, "*." + self.ext))
- if len(self.imgfile) == 0:
- self.imgfile = glob.glob(os.path.join(Path, "*.jpeg"))
- self.ext = "jpeg"
- if len(self.imgfile) == 0:
- self.imgfile = glob.glob(os.path.join(Path, "*.jpg"))
- self.ext = "jpg"
- self.save_path = save_path # 保存json的路径
- self.class_id = label
- self.coco = {}
- self.path = Path
- self.verify_path = verify_path
- self.min_value_x = self.imageWidth
- self.min_value_y = self.imageHeight
- self.max_value_x = 0
- self.max_value_y = 0
- self.verify_labelimg = verify_labelimg_flag
- self.full_img = None
- self.coco_id=0;
-
- def save_label_img(self, all_object):
-
- m_filename = self.image[-1]['file_name']
- print('m_filename=', m_filename)
- m_width = self.image[-1]["width"]
- print('m_width=', m_width)
- m_height = self.image[-1]["height"]
- print('m_height=', m_height)
- object_name = os.path.splitext(m_filename)[0]
- new_object_name = object_name + '.xml'
- img_name = object_name + ".jpg"
-
- print(new_object_name)
- doc = Document() # 创建DOM文档对象
- DOCUMENT = doc.createElement('annotation') # 创建根元素
-
- folder = doc.createElement('folder')
- folder_text = doc.createTextNode(m_filename)
- folder.appendChild(folder_text)
- DOCUMENT.appendChild(folder)
- doc.appendChild(DOCUMENT)
-
- filename = doc.createElement('filename')
- filename_text = doc.createTextNode(m_filename)
- filename.appendChild(filename_text)
- DOCUMENT.appendChild(filename)
- doc.appendChild(DOCUMENT)
-
- path = doc.createElement('path')
- path_text = doc.createTextNode(m_filename)
- path.appendChild(path_text)
- DOCUMENT.appendChild(path)
- doc.appendChild(DOCUMENT)
-
- source = doc.createElement('source')
- database = doc.createElement('database')
- database_text = doc.createTextNode("Unknown") # 元素内容写入
- database.appendChild(database_text)
- source.appendChild(database)
- DOCUMENT.appendChild(source)
- doc.appendChild(DOCUMENT)
-
- size = doc.createElement('size')
- width = doc.createElement('width')
- width_text = doc.createTextNode(str(m_width)) # 元素内容写入
- width.appendChild(width_text)
- size.appendChild(width)
-
- height = doc.createElement('height')
- height_text = doc.createTextNode(str(m_height))
- height.appendChild(height_text)
- size.appendChild(height)
-
- depth = doc.createElement('depth')
- depth_text = doc.createTextNode(str(3))
- depth.appendChild(depth_text)
- size.appendChild(depth)
-
- DOCUMENT.appendChild(size)
-
- segmented = doc.createElement('segmented')
- segmented_text = doc.createTextNode(str(0))
- segmented.appendChild(segmented_text)
- DOCUMENT.appendChild(segmented)
- doc.appendChild(DOCUMENT)
- for item in all_object:
- m_xmin_0 = int(item['bbox'][0])
- print('m_xmin_0=', m_xmin_0)
- m_ymin_0 = int(item['bbox'][1])
- print('m_ymin_0=', m_ymin_0)
- m_xmax_0 = int(item['bbox'][2])
-
- m_ymax_0 = int(item['bbox'][3])
- print('m_ymax_0=', m_ymax_0)
- m_name_0 = self.categories[0]["name"]
- print('m_name_0=', m_name_0)
- object = doc.createElement('object')
- name = doc.createElement('name')
- name_text = doc.createTextNode(m_name_0)
- name.appendChild(name_text)
- object.appendChild(name)
-
- pose = doc.createElement('pose')
- pose_text = doc.createTextNode('Unspecified')
- pose.appendChild(pose_text)
- object.appendChild(pose)
-
- truncated = doc.createElement('truncated')
- truncated_text = doc.createTextNode(str(0))
- truncated.appendChild(truncated_text)
- object.appendChild(truncated)
-
- difficult = doc.createElement('difficult')
- difficult_text = doc.createTextNode(str(0))
- difficult.appendChild(difficult_text)
- object.appendChild(difficult)
-
- bndbox = doc.createElement('bndbox')
- xmin = doc.createElement('xmin')
- xmin_text = doc.createTextNode(str(int(m_xmin_0)))
- xmin.appendChild(xmin_text)
- bndbox.appendChild(xmin)
-
- ymin = doc.createElement('ymin')
- ymin_text = doc.createTextNode(str(int(m_ymin_0)))
- ymin.appendChild(ymin_text)
- bndbox.appendChild(ymin)
-
- xmax = doc.createElement('xmax')
- xmax_text = doc.createTextNode(str(int(m_xmax_0)))
- xmax.appendChild(xmax_text)
- bndbox.appendChild(xmax)
-
- ymax = doc.createElement('ymax')
- ymax_text = doc.createTextNode(str(int(m_ymax_0)))
- ymax.appendChild(ymax_text)
- bndbox.appendChild(ymax)
- object.appendChild(bndbox)
-
- DOCUMENT.appendChild(object)
- new_path_filename = os.path.join(self.labelimg_path, new_object_name)
- print('new_path_filename=', new_path_filename)
- f = open(new_path_filename, 'w')
-
- doc.writexml(f, indent='\t', newl='\n', addindent='\t', encoding='utf-8')
- f.close()
-
- def labelme_to_coco(self):
- for num, json_file in enumerate(self.jsonfile):
- print(json_file)
- json_file = os.path.join(self.path, json_file)
- full_path, json_file_name = os.path.split(json_file)
- json_file_name_Noext, _ = os.path.splitext(json_file_name)
- self.full_img = os.path.join(full_path, ".".join([json_file_name_Noext, self.ext]))
- data = codecs.open(json_file, 'r')
- data = json.load(data)
- self.imageHeight, self.imageWidth = data["imageHeight"], data["imageWidth"]
- _, self.imageName = os.path.split(data["imagePath"])
- self.imageName_Noext, _ = os.path.splitext(self.imageName)
- self.imagePath, self.imageData = data["imagePath"], None
- self.image.append({"file_name": self.imageName, "width": self.imageWidth, "height": self.imageHeight,
- "id": int(json_file_name_Noext)})
- shapes = data["shapes"]
- segmentations = list(filter(lambda x: x["shape_type"] == "polygon", shapes))
- rects = list(filter(lambda x: x["shape_type"] == "rectangle", shapes))
- shapes = list(filter(lambda x: x["shape_type"] == "point", shapes))
-
- # print(len(shapes))
- if self.verify_flag:
- _path, _img_name = os.path.split(self.full_img)
- img = cv2.imread(self.full_img)
- img_f = os.path.join(self.verify_path, _img_name)
- temp_annotations = []
- for num_id in range(0, int(len(shapes) / self.keypoints_length)):
- num_keypoints = 0
- keypoints = [0] * 3 * self.keypoints_length # 这里是我们标注的关节点个数
- annotation = {}
- print(num_id)
- self.min_value_x = self.imageWidth
- self.min_value_y = self.imageHeight
- self.max_value_x = 0
- self.max_value_y = 0
- list_shape = shapes[
- num_id * self.keypoints_length:num_id * self.keypoints_length + self.keypoints_length]
- # print(shapes[num_id*self.keypoints_length:num_id*self.keypoints_length+self.keypoints_length])
- segmentation = []
- for m_id, shape in enumerate(list_shape):
- if shape["shape_type"] == "point":
- idx = int(shape['label']) - self.inital_start_id
- keypoints[idx * 3 + 0] = int(shape['points'][0][0])
- keypoints[idx * 3 + 1] = int(shape['points'][0][1])
- keypoints[idx * 3 + 2] = 2
- segmentation.extend([shape['points'][0][0], shape['points'][0][1]])
- num_keypoints = num_keypoints + 1
- self.min_value_x = min(self.min_value_x, shape['points'][0][0])
- self.min_value_y = min(self.min_value_y, shape['points'][0][1])
- self.max_value_x = max(self.max_value_x, shape['points'][0][0])
- self.max_value_y = max(self.max_value_y, shape['points'][0][1])
- annotation['bbox'] = [self.min_value_x, self.min_value_y, self.max_value_x, self.max_value_y]
- annotation['segmentation'] = [segmentation]
- annotation['num_keypoints'] = num_keypoints
- annotation['area'] = int(annotation['bbox'][2] - annotation['bbox'][0]) * int(
- annotation['bbox'][3] - annotation['bbox'][1])
-
- annotation['iscrowd'] = 0
- annotation['keypoints'] = keypoints
- if len(rects):
- for inclde_item in rects:
- x1 = int(min(inclde_item["points"][0][0], inclde_item["points"][1][0]))
- y1 = int(min(inclde_item["points"][0][1], inclde_item["points"][1][1]))
- x2 = int(max(inclde_item["points"][0][0], inclde_item["points"][1][0]))
- y2 = int(max(inclde_item["points"][0][1], inclde_item["points"][1][1]))
- include_num = 0
- for ii in range(0, self.keypoints_length):
- x, y = int(keypoints[ii * 3]), int(keypoints[ii * 3 + 1])
- flag = (True if x >= x1 and x <= x2 and y >= y1 and y <= y2 else False)
- if flag == True:
- include_num = include_num + 1
- if include_num == self.keypoints_length:
- annotation['bbox'] = [x1, y1, x2, y2]
-
- annotation['image_id'] = int(json_file_name_Noext) # 对应的图片ID
- annotation['category_id'] = 0
- print("num=",num_id)
- annotation['id'] = self.coco_id # 对象id
- self.coco_id =self.coco_id +1
- self.annotations.append(annotation)
- temp_annotations.append(annotation)
- self.image_id = int(json_file_name_Noext)
-
- if self.verify_flag:
- for item in self.categories[0]["skeleton"]:
- idx = item[0]
- iddx = item[1]
- start_point = (annotation['keypoints'][idx * 3 + 0], annotation['keypoints'][idx * 3 + 1])
- end_point = (annotation['keypoints'][iddx * 3 + 0], annotation['keypoints'][iddx * 3 + 1])
- rect_start_point = (int(annotation['bbox'][0]), int(annotation['bbox'][1]))
- rect_end_point = (int(annotation['bbox'][2]), int(annotation['bbox'][3]))
- cv2.rectangle(img, rect_start_point, rect_end_point, (255, 0, 255), 1)
- cv2.putText(img, self.label, rect_start_point, cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2)
-
- cv2.circle(img, start_point, 3, (255, 0, 0), 3)
- cv2.circle(img, end_point, 3, (255, 0, 0), 3)
- cv2.line(img, start_point, end_point, (0, 255, 0), 2)
- cv2.putText(img, "{}".format(idx), start_point, cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 28, 0), 2)
- cv2.imwrite(img_f, img)
- if self.verify_labelimg:
- self.save_label_img(temp_annotations)
- shutil.copy(self.full_img, self.labelimg_path)
- self.coco["images"] = self.image
- self.coco["categories"] = self.categories
- self.coco["annotations"] = self.annotations
-
- def get_images(self, filename, height, width):
- image = {}
- image["height"] = height
- image['width'] = width
- image["id"] = self.imagePath
- image["file_name"] = filename
- return image
-
- def get_categories(self, name, class_id):
- category = {}
- category["supercategory"] = self.class_id
- category['id'] = class_id
- category['name'] = name
- return category
-
- def save_coco_json(self):
- self.labelme_to_coco()
- coco_data = self.coco
- # 保存json文件
- json.dump(coco_data, open(self.save_path, 'w'), indent=4, cls=MyEncoder) # indent=4 更加美观显示
-
-
- all_img_json_path = r'/home/ubuntu/Downloads/fish_data/val'
- coco_path = r"/home/ubuntu/Downloads/fish_data/val.json"
- labelimg_path = r"/home/ubuntu/Downloads/labelimg"
- verify_path = r"/home/ubuntu/Downloads/verify"
- keypoints = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
- skeleton = [[0, 1], [1, 3], [3, 5], [5, 8], [8, 9], [9, 10], [10, 7], [7, 4], [4, 2], [2, 0], [5, 6], [6, 7], [6, 8],
- [6, 9], [6, 10]] # 故意写的关键点和关键点骨节数不一样
- supercategory = "fish"
- label = "fish_tilapia"
- verify_flag = False
- inital_start_id = 0 # 初始下标开始序号 ,根据标注数据集来确定
-
- verify_labelimg_flag = False
-
- full_path, json_file_name = os.path.split(coco_path)
- if not os.path.exists(full_path):
- os.mkdir(full_path)
-
- if not os.path.exists(verify_path):
- os.mkdir(verify_path)
-
- if not os.path.exists(labelimg_path):
- os.mkdir(labelimg_path)
-
- cocoData = Tococo(all_img_json_path, coco_path, labelimg_path, keypoints, skeleton, label, verify_flag, verify_path,
- inital_start_id, verify_labelimg_flag, supercategory)
- cocoData.save_coco_json()
-
- print("finish")

二、测试mmpose得数据集
修改配置文件一/home/ubuntu/mmpose/configs/_base_/datasets/animalpose.py
- dataset_info = dict(
- dataset_name='animalpose',
- paper_info=dict(
- author='Cao, Jinkun and Tang, Hongyang and Fang, Hao-Shu and '
- 'Shen, Xiaoyong and Lu, Cewu and Tai, Yu-Wing',
- title='Cross-Domain Adaptation for Animal Pose Estimation',
- container='The IEEE International Conference on '
- 'Computer Vision (ICCV)',
- year='2019',
- homepage='https://sites.google.com/view/animal-pose/',
- ),
- keypoint_info={
- 0:
- dict(
- name='0', id=0, color=[0, 255, 0], type='upper', swap=''),
- 1:
- dict(
- name='1',
- id=1,
- color=[255, 128, 0],
- type='upper',
- swap=''),
- 2:
- dict(
- name='2',
- id=2,
- color=[0, 255, 0],
- type='upper',
- swap=''),
- 3:
- dict(
- name='3',
- id=3,
- color=[255, 128, 0],
- type='upper',
- swap=''),
- 4:
- dict(name='4', id=4, color=[51, 153, 255], type='upper', swap=''),
- 5:
- dict(name='5', id=5, color=[51, 153, 255], type='upper', swap=''),
- 6:
- dict(
- name='6', id=6, color=[51, 153, 255], type='lower',
- swap=''),
- 7:
- dict(
- name='7', id=7, color=[51, 153, 255], type='upper', swap=''),
- 8:
- dict(
- name='8',
- id=8,
- color=[0, 255, 0],
- type='upper',
- swap=''),
- 9:
- dict(
- name='9',
- id=9,
- color=[255, 128, 0],
- type='upper',
- swap=''),
- 10:
- dict(
- name='10',
- id=10,
- color=[0, 255, 0],
- type='lower',
- swap='')
- },
- skeleton_info={
- 0: dict(link=('0', '1'), id=0, color=[51, 153, 255]),
- 1: dict(link=('1', '3'), id=1, color=[0, 255, 0]),
- 2: dict(link=('3', '5'), id=2, color=[255, 128, 0]),
- 3: dict(link=('5', '8'), id=3, color=[0, 255, 0]),
- 4: dict(link=('6', '9'), id=4, color=[255, 128, 0]),
- 5: dict(link=('9', '10'), id=5, color=[51, 153, 255]),
- 6: dict(link=('10', '7'), id=6, color=[51, 153, 255]),
- 7: dict(link=('7', '4'), id=7, color=[51, 153, 255]),
- 8: dict(link=('4', '2'), id=8, color=[0, 255, 0]),
- 9: dict(link=('2', '0'), id=9, color=[0, 255, 0]),
- 10: dict(link=('5', '6'), id=10, color=[0, 255, 0]),
- 11: dict(link=('6', '7'), id=11, color=[0, 255, 0]),
- 12: dict(link=('6', '10'), id=12, color=[0, 255, 0]),
- 13: dict(link=('6', '9'), id=13, color=[0, 255, 0]),
- 14: dict(link=('6', '8'), id=14, color=[0, 255, 0]),
- 15: dict(link=('8', '9'), id=11, color=[0, 255, 0]),
-
- },
- joint_weights=[
- 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,1
- ],
-
- # Note: The original paper did not provide enough information about
- # the sigmas. We modified from 'https://github.com/cocodataset/'
- # 'cocoapi/blob/master/PythonAPI/pycocotools/cocoeval.py#L523'
- sigmas=[
- 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.
- ])

修改配置文件二/home/ubuntu/mmpose/configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py
- _base_ = ['../../../_base_/default_runtime.py']
-
- # runtime
- train_cfg = dict(max_epochs=1000, val_interval=50)
-
- # optimizer
- optim_wrapper = dict(optimizer=dict(
- type='Adam',
- lr=5e-4,
- ))
-
- # learning policy
- param_scheduler = [
- dict(
- type='LinearLR', begin=0, end=500, start_factor=0.001,
- by_epoch=False), # warm-up
- dict(
- type='MultiStepLR',
- begin=0,
- end=210,
- milestones=[170, 200],
- gamma=0.1,
- by_epoch=True)
- ]
-
- # automatically scaling LR based on the actual training batch size
- auto_scale_lr = dict(base_batch_size=512)
-
- # hooks
- default_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))
-
- # codec settings
- codec = dict(
- type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)
-
- # model settings
- model = dict(
- type='TopdownPoseEstimator',
- data_preprocessor=dict(
- type='PoseDataPreprocessor',
- mean=[123.675, 116.28, 103.53],
- std=[58.395, 57.12, 57.375],
- bgr_to_rgb=True),
- backbone=dict(
- type='HRNet',
- in_channels=3,
- extra=dict(
- stage1=dict(
- num_modules=1,
- num_branches=1,
- block='BOTTLENECK',
- num_blocks=(4, ),
- num_channels=(64, )),
- stage2=dict(
- num_modules=1,
- num_branches=2,
- block='BASIC',
- num_blocks=(4, 4),
- num_channels=(32, 64)),
- stage3=dict(
- num_modules=4,
- num_branches=3,
- block='BASIC',
- num_blocks=(4, 4, 4),
- num_channels=(32, 64, 128)),
- stage4=dict(
- num_modules=3,
- num_branches=4,
- block='BASIC',
- num_blocks=(4, 4, 4, 4),
- num_channels=(32, 64, 128, 256))),
- init_cfg=dict(
- type='Pretrained',
- checkpoint='https://download.openmmlab.com/mmpose/'
- 'pretrain_models/hrnet_w32-36af842e.pth'),
- ),
- head=dict(
- type='HeatmapHead',
- in_channels=32,
- out_channels=11,
- deconv_out_channels=None,
- loss=dict(type='KeypointMSELoss', use_target_weight=True),
- decoder=codec),
- test_cfg=dict(
- flip_test=True,
- flip_mode='heatmap',
- shift_heatmap=True,
- ))
-
- # base dataset settings
- dataset_type = 'AnimalPoseDataset'
- data_mode = 'topdown'
- data_root = '/home/ubuntu/mmpose/fish_data/'
-
- # pipelines
- train_pipeline = [
- dict(type='LoadImage'),
- dict(type='GetBBoxCenterScale'),
- dict(type='RandomFlip', direction='horizontal'),
- dict(type='RandomHalfBody'),
- dict(type='RandomBBoxTransform'),
- dict(type='TopdownAffine', input_size=codec['input_size']),
- dict(type='GenerateTarget', encoder=codec),
- dict(type='PackPoseInputs')
- ]
- val_pipeline = [
- dict(type='LoadImage'),
- dict(type='GetBBoxCenterScale'),
- dict(type='TopdownAffine', input_size=codec['input_size']),
- dict(type='PackPoseInputs')
- ]
-
- # data loaders
- train_dataloader = dict(
- batch_size=32,
- num_workers=1,
- persistent_workers=True,
- sampler=dict(type='DefaultSampler', shuffle=True),
- dataset=dict(
- type=dataset_type,
- data_root=data_root,
- data_mode=data_mode,
- ann_file='train.json',
- data_prefix=dict(img='train/'),
- pipeline=train_pipeline,
- ))
- val_dataloader = dict(
- batch_size=32,
- num_workers=1,
- persistent_workers=True,
- drop_last=False,
- sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),
- dataset=dict(
- type=dataset_type,
- data_root=data_root,
- data_mode=data_mode,
- ann_file='val.json',
- data_prefix=dict(img='val/'),
- test_mode=True,
- pipeline=val_pipeline,
- ))
- test_dataloader = val_dataloader
-
- # evaluators
- val_evaluator = dict(
- type='CocoMetric', ann_file=data_root + 'val.json')
- test_evaluator = val_evaluator

测试数据集是否正确
ubuntu@ubuntu:~/mmpose$ python3 tools/misc/browse_dataset.py /home/ubuntu/mmpose/configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py --phase val --mode original
三、训练数据集
ubuntu@ubuntu:~/mmpose$ python3 tools/train.py /home/ubuntu/mmpose/configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py
四、是用mmdeploy转模型
- ubuntu@ubuntu:~/mmdeploy$ python3 tools/torch2onnx.py configs/mmpose/pose-detection_onnxruntime_static.py ../mmpose/configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py ../mmpose/work_dirs/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256/epoch_670.pth ../mmpose/tests/data/animalpose/ca110.jpeg
- 04/24 17:19:28 - mmengine - INFO - torch2onnx:
- model_cfg: ../mmpose/configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py
- deploy_cfg: configs/mmpose/pose-detection_onnxruntime_static.py
- 04/24 17:19:29 - mmengine - WARNING - Failed to search registry with scope "mmpose" in the "Codebases" registry tree. As a workaround, the current "Codebases" registry in "mmdeploy" is used to build instance. This may cause unexpected failure when running the built modules. Please check whether "mmpose" is a correct scope, or whether the registry is initialized.
- 04/24 17:19:29 - mmengine - WARNING - Failed to search registry with scope "mmpose" in the "mmpose_tasks" registry tree. As a workaround, the current "mmpose_tasks" registry in "mmdeploy" is used to build instance. This may cause unexpected failure when running the built modules. Please check whether "mmpose" is a correct scope, or whether the registry is initialized.
- Loads checkpoint by local backend from path: ../mmpose/work_dirs/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256/epoch_670.pth
- /home/ubuntu/mmpose/mmpose/datasets/datasets/utils.py:102: UserWarning: The metainfo config file "configs/_base_/datasets/animalpose.py" does not exist. A matched config file "/home/ubuntu/mmpose/mmpose/.mim/configs/_base_/datasets/animalpose.py" will be used instead.
- warnings.warn(
- 04/24 17:19:31 - mmengine - WARNING - DeprecationWarning: get_onnx_config will be deprecated in the future.
- 04/24 17:19:31 - mmengine - INFO - Export PyTorch model to ONNX: ./work-dir/end2end.onnx.
- 04/24 17:19:31 - mmengine - WARNING - Can not find torch._C._jit_pass_onnx_autograd_function_process, function rewrite will not be applied
- 04/24 17:20:10 - mmengine - INFO - Execute onnx optimize passes.
- 04/24 17:20:10 - mmengine - WARNING - Can not optimize model, please build torchscipt extension.
- More details: https://github.com/open-mmlab/mmdeploy/tree/1.x/docs/en/experimental/onnx_optimizer.md
- 04/24 17:20:10 - mmengine - INFO - torch2onnx finished. Results saved to ./work-dir

转ncnn
ubuntu@ubuntu:~/ncnn/build/install/bin$ ./onnx2ncnn /home/ubuntu/mmdeploy/work-dir/end2end.onnx /home/ubuntu/mmdeploy/work-dir/end2end.param /home/ubuntu/mmdeploy/work-dir/end2end.bin
五、转rk3588,产生txt
ubuntu@ubuntu:~/mmpose$ find /home/ubuntu/mmpose/fish_data -name "*.jpg" > a.txt
转模型
- from rknn.api import RKNN
-
- ONNX_MODEL = '/home/ubuntu/mmdeploy/work-dir/end2end.onnx'
- RKNN_MODEL = '/home/ubuntu/mmdeploy/work-dir/end2end.rknn'
-
- if __name__ == '__main__':
-
- # Create RKNN object
- rknn = RKNN(verbose=True)
-
- # pre-process config
- print('--> config model')
- rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]],
- target_platform='rk3588',
- quantized_dtype='asymmetric_quantized-8', optimization_level=3)
- print('done')
-
- print('--> Loading model')
- ret = rknn.load_onnx(model=ONNX_MODEL)
- if ret != 0:
- print('Load model failed!')
- exit(ret)
- print('done')
-
- # Build model
- print('--> Building model')
- ret = rknn.build(do_quantization=True, dataset='dataset.txt') # ,pre_compile=True
- if ret != 0:
- print('Build end2end failed!')
- exit(ret)
- print('done')
-
- # Export rknn model
- print('--> Export RKNN model')
- ret = rknn.export_rknn(RKNN_MODEL)
- if ret != 0:
- print('Export end2end.rknn failed!')
- exit(ret)
- print('done')
-
- rknn.release()

cmakelists.txt
- cmake_minimum_required(VERSION 3.16)
- project(untitled10)
- set(CMAKE_CXX_FLAGS "-std=c++11")
- set(CMAKE_CXX_STANDARD 11)
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ")
-
- include_directories(${CMAKE_SOURCE_DIR})
- include_directories(${CMAKE_SOURCE_DIR}/include)
- find_package(OpenCV REQUIRED)
- #message(STATUS ${OpenCV_INCLUDE_DIRS})
- #添加头文件
- include_directories(${OpenCV_INCLUDE_DIRS})
- #链接Opencv库
- add_library(librknn_api SHARED IMPORTED)
- set_target_properties(librknn_api PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/lib/librknn_api.so)
- #官方的zoo社区或者参考前几篇博客寻找其so出处
-
- add_executable(untitled10 main.cpp)
- target_link_libraries(untitled10 ${OpenCV_LIBS} librknn_api )

main.cpp
- #include <stdio.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <queue>
- #include "rknn_api.h"
- #include "opencv2/core/core.hpp"
- #include "opencv2/imgproc/imgproc.hpp"
- #include "opencv2/highgui/highgui.hpp"
- #include <chrono>
- #include <iostream>
-
- using namespace std;
-
- struct Keypoints {
- float x;
- float y;
- float score;
-
- Keypoints() : x(0), y(0), score(0) {}
-
- Keypoints(float x, float y, float score) : x(x), y(y), score(score) {}
- };
-
- struct Box {
- float center_x;
- float center_y;
- float scale_x;
- float scale_y;
- float scale_prob;
- float score;
-
- Box() : center_x(0), center_y(0), scale_x(0), scale_y(0), scale_prob(0), score(0) {}
-
- Box(float center_x, float center_y, float scale_x, float scale_y, float scale_prob, float score) :
- center_x(center_x), center_y(center_y), scale_x(scale_x), scale_y(scale_y), scale_prob(scale_prob),
- score(score) {}
- };
-
- void bbox_xywh2cs(float bbox[], float aspect_ratio, float padding, float pixel_std, float *center, float *scale) {
- float x = bbox[0];
- float y = bbox[1];
- float w = bbox[2];
- float h = bbox[3];
- *center = x + w * 0.5;
- *(center + 1) = y + h * 0.5;
- if (w > aspect_ratio * h)
- h = w * 1.0 / aspect_ratio;
- else if (w < aspect_ratio * h)
- w = h * aspect_ratio;
-
-
- *scale = (w / pixel_std) * padding;
- *(scale + 1) = (h / pixel_std) * padding;
- }
-
- void rotate_point(float *pt, float angle_rad, float *rotated_pt) {
- float sn = sin(angle_rad);
- float cs = cos(angle_rad);
- float new_x = pt[0] * cs - pt[1] * sn;
- float new_y = pt[0] * sn + pt[1] * cs;
- rotated_pt[0] = new_x;
- rotated_pt[1] = new_y;
-
- }
-
- void _get_3rd_point(cv::Point2f a, cv::Point2f b, float *direction) {
-
- float direction_0 = a.x - b.x;
- float direction_1 = a.y - b.y;
- direction[0] = b.x - direction_1;
- direction[1] = b.y + direction_0;
-
-
- }
-
- void get_affine_transform(float *center, float *scale, float rot, float *output_size, float *shift, bool inv,
- cv::Mat &trans) {
- float scale_tmp[] = {0, 0};
- scale_tmp[0] = scale[0] * 200.0;
- scale_tmp[1] = scale[1] * 200.0;
- float src_w = scale_tmp[0];
- float dst_w = output_size[0];
- float dst_h = output_size[1];
- float rot_rad = M_PI * rot / 180;
- float pt[] = {0, 0};
- pt[0] = 0;
- pt[1] = src_w * (-0.5);
- float src_dir[] = {0, 0};
- rotate_point(pt, rot_rad, src_dir);
- float dst_dir[] = {0, 0};
- dst_dir[0] = 0;
- dst_dir[1] = dst_w * (-0.5);
- cv::Point2f src[3] = {cv::Point2f(0, 0), cv::Point2f(0, 0), cv::Point2f(0, 0)};
- src[0] = cv::Point2f(center[0] + scale_tmp[0] * shift[0], center[1] + scale_tmp[1] * shift[1]);
- src[1] = cv::Point2f(center[0] + src_dir[0] + scale_tmp[0] * shift[0],
- center[1] + src_dir[1] + scale_tmp[1] * shift[1]);
- float direction_src[] = {0, 0};
- _get_3rd_point(src[0], src[1], direction_src);
- src[2] = cv::Point2f(direction_src[0], direction_src[1]);
- cv::Point2f dst[3] = {cv::Point2f(0, 0), cv::Point2f(0, 0), cv::Point2f(0, 0)};
- dst[0] = cv::Point2f(dst_w * 0.5, dst_h * 0.5);
- dst[1] = cv::Point2f(dst_w * 0.5 + dst_dir[0], dst_h * 0.5 + dst_dir[1]);
- float direction_dst[] = {0, 0};
- _get_3rd_point(dst[0], dst[1], direction_dst);
- dst[2] = cv::Point2f(direction_dst[0], direction_dst[1]);
-
- if (inv) {
- trans = cv::getAffineTransform(dst, src);
- } else {
- trans = cv::getAffineTransform(src, dst);
- }
-
-
- }
-
- void
- transform_preds(std::vector<cv::Point2f> coords, std::vector<Keypoints> &target_coords, float *center, float *scale,
- int w, int h, bool use_udp = false) {
- float scale_x[] = {0, 0};
- float temp_scale[] = {scale[0] * 200, scale[1] * 200};
- if (use_udp) {
- scale_x[0] = temp_scale[0] / (w - 1);
- scale_x[1] = temp_scale[1] / (h - 1);
- } else {
- scale_x[0] = temp_scale[0] / w;
- scale_x[1] = temp_scale[1] / h;
- }
- for (int i = 0; i < coords.size(); i++) {
- target_coords[i].x = coords[i].x * scale_x[0] + center[0] - temp_scale[0] * 0.5;
- target_coords[i].y = coords[i].y * scale_x[1] + center[1] - temp_scale[1] * 0.5;
- }
-
- }
-
-
- void letterbox(cv::Mat rgb, cv::Mat &img_resize, int target_width, int target_height) {
-
- float shape_0 = rgb.rows;
- float shape_1 = rgb.cols;
- float new_shape_0 = target_height;
- float new_shape_1 = target_width;
- float r = std::min(new_shape_0 / shape_0, new_shape_1 / shape_1);
- float new_unpad_0 = int(round(shape_1 * r));
- float new_unpad_1 = int(round(shape_0 * r));
- float dw = new_shape_1 - new_unpad_0;
- float dh = new_shape_0 - new_unpad_1;
- dw = dw / 2;
- dh = dh / 2;
- cv::Mat copy_rgb = rgb.clone();
- if (int(shape_0) != int(new_unpad_0) && int(shape_1) != int(new_unpad_1)) {
- cv::resize(copy_rgb, img_resize, cv::Size(new_unpad_0, new_unpad_1));
- copy_rgb = img_resize;
- }
- int top = int(round(dh - 0.1));
- int bottom = int(round(dh + 0.1));
- int left = int(round(dw - 0.1));
- int right = int(round(dw + 0.1));
- cv::copyMakeBorder(copy_rgb, img_resize, top, bottom, left, right, cv::BORDER_CONSTANT, cv::Scalar(0, 0, 0));
-
- }
-
- void printRKNNTensor(rknn_tensor_attr *attr) {
- printf("index=%d name=%s n_dims=%d dims=[%d %d %d %d] n_elems=%d size=%d "
- "fmt=%d type=%d qnt_type=%d fl=%d zp=%d scale=%f\n",
- attr->index, attr->name, attr->n_dims, attr->dims[3], attr->dims[2],
- attr->dims[1], attr->dims[0], attr->n_elems, attr->size, 0, attr->type,
- attr->qnt_type, attr->fl, attr->zp, attr->scale);
- }
-
- int post_process_u8(uint8_t *input0, int model_in_h, int model_in_w) {
-
-
- return 0;
- }
-
- int main(int argc, char **argv) {
- float keypoint_score = 0.1f;
- cv::Mat bgr = cv::imread("../7.jpg");
- cv::Mat rgb;
- cv::cvtColor(bgr, rgb, cv::COLOR_BGR2RGB);
- float image_target_w = 256;
- float image_target_h = 256;
- float padding = 1.25;
- float pixel_std = 200;
- float aspect_ratio = image_target_h / image_target_w;
- float bbox[] = {516,210,516+702,210+468,
- 9.995332e-01};// 需要检测框架 这个矩形框来自检测框架的坐标 x y w h score 这里来自我自己标注的检测框
- // bbox[2] = bbox[2] - bbox[0];
- // bbox[3] = bbox[3] - bbox[1];
- float center[2] = {0, 0};
- float scale[2] = {0, 0};
- bbox_xywh2cs(bbox, aspect_ratio, padding, pixel_std, center, scale);
- float rot = 0;
- float shift[] = {0, 0};
- bool inv = false;
- float output_size[] = {image_target_h, image_target_w};
- cv::Mat trans;
- get_affine_transform(center, scale, rot, output_size, shift, inv, trans);
- std::cout << trans << std::endl;
- cv::Mat detect_image;//= cv::Mat::zeros(image_target_w ,image_target_h, CV_8UC3);
- cv::warpAffine(rgb, detect_image, trans, cv::Size(image_target_h, image_target_w), cv::INTER_LINEAR);
- const char *model_path = "../end2end_3588.rknn";
- // Load model
- FILE *fp = fopen(model_path, "rb");
- if (fp == NULL) {
- printf("fopen %s fail!\n", model_path);
- return -1;
- }
- fseek(fp, 0, SEEK_END);
- int model_len = ftell(fp);
- void *model = malloc(model_len);
- fseek(fp, 0, SEEK_SET);
- if (model_len != fread(model, 1, model_len, fp)) {
- printf("fread %s fail!\n", model_path);
- free(model);
- return -1;
- }
-
-
- rknn_context ctx = 0;
-
- int ret = rknn_init(&ctx, model, model_len, 0,NULL);
- if (ret < 0) {
- printf("rknn_init fail! ret=%d\n", ret);
- return -1;
- }
-
- /* Query sdk version */
- rknn_sdk_version version;
- ret = rknn_query(ctx, RKNN_QUERY_SDK_VERSION, &version,
- sizeof(rknn_sdk_version));
- if (ret < 0) {
- printf("rknn_init error ret=%d\n", ret);
- return -1;
- }
- printf("sdk version: %s driver version: %s\n", version.api_version,
- version.drv_version);
-
-
- /* Get input,output attr */
- rknn_input_output_num io_num;
- ret = rknn_query(ctx, RKNN_QUERY_IN_OUT_NUM, &io_num, sizeof(io_num));
- if (ret < 0) {
- printf("rknn_init error ret=%d\n", ret);
- return -1;
- }
- printf("model input num: %d, output num: %d\n", io_num.n_input,
- io_num.n_output);
-
- rknn_tensor_attr input_attrs[io_num.n_input];
- memset(input_attrs, 0, sizeof(input_attrs));
- for (int i = 0; i < io_num.n_input; i++) {
- input_attrs[i].index = i;
- ret = rknn_query(ctx, RKNN_QUERY_INPUT_ATTR, &(input_attrs[i]),
- sizeof(rknn_tensor_attr));
- if (ret < 0) {
- printf("rknn_init error ret=%d\n", ret);
- return -1;
- }
- printRKNNTensor(&(input_attrs[i]));
- }
-
- rknn_tensor_attr output_attrs[io_num.n_output];
- memset(output_attrs, 0, sizeof(output_attrs));
- for (int i = 0; i < io_num.n_output; i++) {
- output_attrs[i].index = i;
- ret = rknn_query(ctx, RKNN_QUERY_OUTPUT_ATTR, &(output_attrs[i]),
- sizeof(rknn_tensor_attr));
- printRKNNTensor(&(output_attrs[i]));
- }
-
- int input_channel = 3;
- int input_width = 0;
- int input_height = 0;
- if (input_attrs[0].fmt == RKNN_TENSOR_NCHW) {
- printf("model is NCHW input fmt\n");
- input_width = input_attrs[0].dims[0];
- input_height = input_attrs[0].dims[1];
- printf("input_width=%d input_height=%d\n", input_width, input_height);
- } else {
- printf("model is NHWC input fmt\n");
- input_width = input_attrs[0].dims[1];
- input_height = input_attrs[0].dims[2];
- printf("input_width=%d input_height=%d\n", input_width, input_height);
- }
-
- printf("model input height=%d, width=%d, channel=%d\n", input_height, input_width,
- input_channel);
-
-
- /* Init input tensor */
- rknn_input inputs[1];
- memset(inputs, 0, sizeof(inputs));
- inputs[0].index = 0;
- inputs[0].buf = detect_image.data;
- inputs[0].type = RKNN_TENSOR_UINT8;
- inputs[0].size = input_width * input_height * input_channel;
- inputs[0].fmt = RKNN_TENSOR_NHWC;
- inputs[0].pass_through = 0;
-
- /* Init output tensor */
- rknn_output outputs[io_num.n_output];
- memset(outputs, 0, sizeof(outputs));
- for (int i = 0; i < io_num.n_output; i++) {
- outputs[i].want_float = 1;
- }
- printf("img.cols: %d, img.rows: %d\n", detect_image.cols, detect_image.rows);
- auto t1 = std::chrono::steady_clock::now();
- rknn_inputs_set(ctx, io_num.n_input, inputs);
- std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
-
- ret = rknn_run(ctx, NULL);
- if (ret < 0) {
- printf("ctx error ret=%d\n", ret);
- return -1;
- }
- auto t2 = std::chrono::steady_clock::now();
- std::chrono::duration<double> time_span = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - now);
- std::cout << "It took me " << time_span.count()*1000 << " ms."<<std::endl;
- ret = rknn_outputs_get(ctx, io_num.n_output, outputs, NULL);
- if (ret < 0) {
- printf("outputs error ret=%d\n", ret);
- return -1;
- }
- int shape_b = 0;
- int shape_c = 0;
- int shape_w = 0;;
- int shape_h = 0;;
- for (int i = 0; i < io_num.n_output; ++i) {
- shape_b = output_attrs[i].dims[0];
- shape_c = output_attrs[i].dims[1];
- shape_h = output_attrs[i].dims[2];;
- shape_w = output_attrs[i].dims[3];;
- }
- printf("batch=%d channel=%d width=%d height= %d\n", shape_b, shape_c, shape_w, shape_h);
- std::vector<float> vec_result_heap;
- float *output = (float *) outputs[0].buf;
- for (int i = 0; i < shape_c; i++) {
- for (int j = 0; j < shape_h; j++) {
- for (int k = 0; k < shape_w; k++) {
- float elements = output[i * shape_w * shape_h + j * shape_w + k];
- vec_result_heap.emplace_back(elements);
- }
- }
-
- }
-
- std::vector<Keypoints> all_preds;
- std::vector<int> idx;
- for (int i = 0; i < shape_c; i++) {
- auto begin = vec_result_heap.begin() + i * shape_w * shape_h;
- auto end = vec_result_heap.begin() + (i + 1) * shape_w * shape_h;
- float maxValue = *max_element(begin, end);
- int maxPosition = max_element(begin, end) - begin;
- all_preds.emplace_back(Keypoints(0, 0, maxValue));
- idx.emplace_back(maxPosition);
- }
- std::vector<cv::Point2f> vec_point;
- for (int i = 0; i < idx.size(); i++) {
- int x = idx[i] % shape_w;
- int y = idx[i] / shape_w;
- vec_point.emplace_back(cv::Point2f(x, y));
- }
-
- for (int i = 0; i < shape_c; i++) {
- int px = vec_point[i].x;
- int py = vec_point[i].y;
- if (px > 1 && px < shape_w - 1 && py > 1 && py < shape_h - 1) {
- float diff_0 = vec_result_heap[py * shape_w + px + 1] - vec_result_heap[py * shape_w + px - 1];
- float diff_1 = vec_result_heap[(py + 1) * shape_w + px] - vec_result_heap[(py - 1) * shape_w + px];
- vec_point[i].x += diff_0 == 0 ? 0 : (diff_0 > 0) ? 0.25 : -0.25;
- vec_point[i].y += diff_1 == 0 ? 0 : (diff_1 > 0) ? 0.25 : -0.25;
- }
- }
- std::vector<Box> all_boxes;
- bool heap_map = false;
- if (heap_map) {
- all_boxes.emplace_back(Box(center[0], center[1], scale[0], scale[1], scale[0] * scale[1] * 400, bbox[4]));
- }
- transform_preds(vec_point, all_preds, center, scale, shape_w, shape_h);
- int skeleton[15][2] = {{0, 1},{1, 3},{3, 5},{5, 8},
- {8, 9},{9, 10},{10, 7},{7,4},{4, 2},
- {2, 0},{5, 6},
- {6, 7},{6, 10},{6, 8},{6, 9}};
-
- cv::rectangle(bgr, cv::Point(bbox[0], bbox[1]), cv::Point(bbox[0] + bbox[2], bbox[1] + bbox[3]),
- cv::Scalar(255, 0, 0));
- for (int i = 0; i < all_preds.size(); i++) {
- if (all_preds[i].score > keypoint_score) {
- cv::circle(bgr, cv::Point(all_preds[i].x, all_preds[i].y), 3, cv::Scalar(0, 255, 120), -1);//画点,其实就是实心圆
- }
- }
- for (int i = 0; i < sizeof(skeleton) / sizeof(sizeof(skeleton[1])); i++) {
- int x0 = all_preds[skeleton[i][0]].x;
- int y0 = all_preds[skeleton[i][0]].y;
- int x1 = all_preds[skeleton[i][1]].x;
- int y1 = all_preds[skeleton[i][1]].y;
-
- cv::line(bgr, cv::Point(x0, y0), cv::Point(x1, y1),
- cv::Scalar(0, 255, 0), 1);
- }
- cv::imwrite("../image.jpg", bgr);
- ret = rknn_outputs_release(ctx, io_num.n_output, outputs);
-
- if (ret < 0) {
- printf("rknn_query fail! ret=%d\n", ret);
- goto Error;
- }
-
- Error:
- if (ctx > 0)
- ret=rknn_destroy(ctx);
- printf("%d \n",ret);
- //感觉官方固件有问题,销毁对象存在问题,或许是我的固件有问题 https://t.rock-chips.com/forum.php?mod=viewthread&tid=2365
- if (model)
- free(model);
- if (fp)
- fclose(fp);
- return 0;
- }

测试结果
附录 mp4转h264(瑞芯微用第二种)
- ubuntu@ubuntu:~/aaa$ ffmpeg -i people.mp4 -codec copy -bsf: hevc_mp4toannexb -f h264 sample.h264
- ubuntu@ubuntu:~/aaa$ ffmpeg -i people.mp4 -vcodec h264 people.h264
参考
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。