当前位置:   article > 正文

55、记录使用标注目标检测+关键点检测的数据集,进行训练和部署香橙派芯片_目标检测网络中添加key point

目标检测网络中添加key point

基本思想:进行是数据集的预处理和标注,然后进行分开目标检测训练和关键点训练,然后增加追踪逻辑

一、标注关键点数据,这里标注只是使用标注检测框和关键点即可,在本质上也可以不用标注检测框,因为个人的数据集是鱼类,可以通过全身的关键点拟合成检测框,提供标注数据集,然后进行提取两类数据集一类为关键点数据集(coco),另一类为检测类数据集(yolov5/7)

 标注完数据之后,进行提取目标检测数据集和关键点数据集,(等待第一版模型出现,做自动化标注,全部以python调用onnx完成开发)代码:

  1. import numpy as np
  2. import json
  3. import glob
  4. import codecs
  5. import os
  6. import cv2
  7. import json
  8. import shutil
  9. import os
  10. from xml.dom.minidom import Document
  11. class MyEncoder(json.JSONEncoder):
  12. def default(self, obj):
  13. if isinstance(obj, np.integer):
  14. return int(obj)
  15. elif isinstance(obj, np.floating):
  16. return float(obj)
  17. elif isinstance(obj, np.ndarray):
  18. return obj.tolist()
  19. else:
  20. return super(MyEncoder, self).default(obj)
  21. class Tococo(object):
  22. def __init__(self, Path, save_path, labelimg_path, keypoints, skeleton, label, verify_flag, verify_path,
  23. inital_start_id, verify_labelimg_flag, supercategory):
  24. self.labelimg_path = labelimg_path
  25. self.verify_flag = verify_flag
  26. self.label = label
  27. categories = {}
  28. categories.update({"supercategory": supercategory})
  29. categories.update({"id": 0})
  30. categories.update({"name": label})
  31. categories.update({"keypoints": keypoints})
  32. self.keypoints_length = len(keypoints)
  33. self.inital_start_id = inital_start_id
  34. categories.update({"skeleton": skeleton})
  35. self.categories = [categories]
  36. self.imagePath = None
  37. self.imageData = None
  38. self.imageHeight = None
  39. self.imageWidth = None
  40. self.imageName = None
  41. self.imageName_Noext = None
  42. self.image = []
  43. self.annotations = []
  44. self.jsonfile = glob.glob(os.path.join(Path, "*.json"))
  45. self.ext = "png"
  46. self.imgfile = glob.glob(os.path.join(Path, "*." + self.ext))
  47. if len(self.imgfile) == 0:
  48. self.imgfile = glob.glob(os.path.join(Path, "*.jpeg"))
  49. self.ext = "jpeg"
  50. if len(self.imgfile) == 0:
  51. self.imgfile = glob.glob(os.path.join(Path, "*.jpg"))
  52. self.ext = "jpg"
  53. self.save_path = save_path # 保存json的路径
  54. self.class_id = label
  55. self.coco = {}
  56. self.path = Path
  57. self.verify_path = verify_path
  58. self.min_value_x = self.imageWidth
  59. self.min_value_y = self.imageHeight
  60. self.max_value_x = 0
  61. self.max_value_y = 0
  62. self.verify_labelimg = verify_labelimg_flag
  63. self.full_img = None
  64. self.coco_id=0;
  65. def save_label_img(self, all_object):
  66. m_filename = self.image[-1]['file_name']
  67. print('m_filename=', m_filename)
  68. m_width = self.image[-1]["width"]
  69. print('m_width=', m_width)
  70. m_height = self.image[-1]["height"]
  71. print('m_height=', m_height)
  72. object_name = os.path.splitext(m_filename)[0]
  73. new_object_name = object_name + '.xml'
  74. img_name = object_name + ".jpg"
  75. print(new_object_name)
  76. doc = Document() # 创建DOM文档对象
  77. DOCUMENT = doc.createElement('annotation') # 创建根元素
  78. folder = doc.createElement('folder')
  79. folder_text = doc.createTextNode(m_filename)
  80. folder.appendChild(folder_text)
  81. DOCUMENT.appendChild(folder)
  82. doc.appendChild(DOCUMENT)
  83. filename = doc.createElement('filename')
  84. filename_text = doc.createTextNode(m_filename)
  85. filename.appendChild(filename_text)
  86. DOCUMENT.appendChild(filename)
  87. doc.appendChild(DOCUMENT)
  88. path = doc.createElement('path')
  89. path_text = doc.createTextNode(m_filename)
  90. path.appendChild(path_text)
  91. DOCUMENT.appendChild(path)
  92. doc.appendChild(DOCUMENT)
  93. source = doc.createElement('source')
  94. database = doc.createElement('database')
  95. database_text = doc.createTextNode("Unknown") # 元素内容写入
  96. database.appendChild(database_text)
  97. source.appendChild(database)
  98. DOCUMENT.appendChild(source)
  99. doc.appendChild(DOCUMENT)
  100. size = doc.createElement('size')
  101. width = doc.createElement('width')
  102. width_text = doc.createTextNode(str(m_width)) # 元素内容写入
  103. width.appendChild(width_text)
  104. size.appendChild(width)
  105. height = doc.createElement('height')
  106. height_text = doc.createTextNode(str(m_height))
  107. height.appendChild(height_text)
  108. size.appendChild(height)
  109. depth = doc.createElement('depth')
  110. depth_text = doc.createTextNode(str(3))
  111. depth.appendChild(depth_text)
  112. size.appendChild(depth)
  113. DOCUMENT.appendChild(size)
  114. segmented = doc.createElement('segmented')
  115. segmented_text = doc.createTextNode(str(0))
  116. segmented.appendChild(segmented_text)
  117. DOCUMENT.appendChild(segmented)
  118. doc.appendChild(DOCUMENT)
  119. for item in all_object:
  120. m_xmin_0 = int(item['bbox'][0])
  121. print('m_xmin_0=', m_xmin_0)
  122. m_ymin_0 = int(item['bbox'][1])
  123. print('m_ymin_0=', m_ymin_0)
  124. m_xmax_0 = int(item['bbox'][2])
  125. m_ymax_0 = int(item['bbox'][3])
  126. print('m_ymax_0=', m_ymax_0)
  127. m_name_0 = self.categories[0]["name"]
  128. print('m_name_0=', m_name_0)
  129. object = doc.createElement('object')
  130. name = doc.createElement('name')
  131. name_text = doc.createTextNode(m_name_0)
  132. name.appendChild(name_text)
  133. object.appendChild(name)
  134. pose = doc.createElement('pose')
  135. pose_text = doc.createTextNode('Unspecified')
  136. pose.appendChild(pose_text)
  137. object.appendChild(pose)
  138. truncated = doc.createElement('truncated')
  139. truncated_text = doc.createTextNode(str(0))
  140. truncated.appendChild(truncated_text)
  141. object.appendChild(truncated)
  142. difficult = doc.createElement('difficult')
  143. difficult_text = doc.createTextNode(str(0))
  144. difficult.appendChild(difficult_text)
  145. object.appendChild(difficult)
  146. bndbox = doc.createElement('bndbox')
  147. xmin = doc.createElement('xmin')
  148. xmin_text = doc.createTextNode(str(int(m_xmin_0)))
  149. xmin.appendChild(xmin_text)
  150. bndbox.appendChild(xmin)
  151. ymin = doc.createElement('ymin')
  152. ymin_text = doc.createTextNode(str(int(m_ymin_0)))
  153. ymin.appendChild(ymin_text)
  154. bndbox.appendChild(ymin)
  155. xmax = doc.createElement('xmax')
  156. xmax_text = doc.createTextNode(str(int(m_xmax_0)))
  157. xmax.appendChild(xmax_text)
  158. bndbox.appendChild(xmax)
  159. ymax = doc.createElement('ymax')
  160. ymax_text = doc.createTextNode(str(int(m_ymax_0)))
  161. ymax.appendChild(ymax_text)
  162. bndbox.appendChild(ymax)
  163. object.appendChild(bndbox)
  164. DOCUMENT.appendChild(object)
  165. new_path_filename = os.path.join(self.labelimg_path, new_object_name)
  166. print('new_path_filename=', new_path_filename)
  167. f = open(new_path_filename, 'w')
  168. doc.writexml(f, indent='\t', newl='\n', addindent='\t', encoding='utf-8')
  169. f.close()
  170. def labelme_to_coco(self):
  171. for num, json_file in enumerate(self.jsonfile):
  172. print(json_file)
  173. json_file = os.path.join(self.path, json_file)
  174. full_path, json_file_name = os.path.split(json_file)
  175. json_file_name_Noext, _ = os.path.splitext(json_file_name)
  176. self.full_img = os.path.join(full_path, ".".join([json_file_name_Noext, self.ext]))
  177. data = codecs.open(json_file, 'r')
  178. data = json.load(data)
  179. self.imageHeight, self.imageWidth = data["imageHeight"], data["imageWidth"]
  180. _, self.imageName = os.path.split(data["imagePath"])
  181. self.imageName_Noext, _ = os.path.splitext(self.imageName)
  182. self.imagePath, self.imageData = data["imagePath"], None
  183. self.image.append({"file_name": self.imageName, "width": self.imageWidth, "height": self.imageHeight,
  184. "id": int(json_file_name_Noext)})
  185. shapes = data["shapes"]
  186. segmentations = list(filter(lambda x: x["shape_type"] == "polygon", shapes))
  187. rects = list(filter(lambda x: x["shape_type"] == "rectangle", shapes))
  188. shapes = list(filter(lambda x: x["shape_type"] == "point", shapes))
  189. # print(len(shapes))
  190. if self.verify_flag:
  191. _path, _img_name = os.path.split(self.full_img)
  192. img = cv2.imread(self.full_img)
  193. img_f = os.path.join(self.verify_path, _img_name)
  194. temp_annotations = []
  195. for num_id in range(0, int(len(shapes) / self.keypoints_length)):
  196. num_keypoints = 0
  197. keypoints = [0] * 3 * self.keypoints_length # 这里是我们标注的关节点个数
  198. annotation = {}
  199. print(num_id)
  200. self.min_value_x = self.imageWidth
  201. self.min_value_y = self.imageHeight
  202. self.max_value_x = 0
  203. self.max_value_y = 0
  204. list_shape = shapes[
  205. num_id * self.keypoints_length:num_id * self.keypoints_length + self.keypoints_length]
  206. # print(shapes[num_id*self.keypoints_length:num_id*self.keypoints_length+self.keypoints_length])
  207. segmentation = []
  208. for m_id, shape in enumerate(list_shape):
  209. if shape["shape_type"] == "point":
  210. idx = int(shape['label']) - self.inital_start_id
  211. keypoints[idx * 3 + 0] = int(shape['points'][0][0])
  212. keypoints[idx * 3 + 1] = int(shape['points'][0][1])
  213. keypoints[idx * 3 + 2] = 2
  214. segmentation.extend([shape['points'][0][0], shape['points'][0][1]])
  215. num_keypoints = num_keypoints + 1
  216. self.min_value_x = min(self.min_value_x, shape['points'][0][0])
  217. self.min_value_y = min(self.min_value_y, shape['points'][0][1])
  218. self.max_value_x = max(self.max_value_x, shape['points'][0][0])
  219. self.max_value_y = max(self.max_value_y, shape['points'][0][1])
  220. annotation['bbox'] = [self.min_value_x, self.min_value_y, self.max_value_x, self.max_value_y]
  221. annotation['segmentation'] = [segmentation]
  222. annotation['num_keypoints'] = num_keypoints
  223. annotation['area'] = int(annotation['bbox'][2] - annotation['bbox'][0]) * int(
  224. annotation['bbox'][3] - annotation['bbox'][1])
  225. annotation['iscrowd'] = 0
  226. annotation['keypoints'] = keypoints
  227. if len(rects):
  228. for inclde_item in rects:
  229. x1 = int(min(inclde_item["points"][0][0], inclde_item["points"][1][0]))
  230. y1 = int(min(inclde_item["points"][0][1], inclde_item["points"][1][1]))
  231. x2 = int(max(inclde_item["points"][0][0], inclde_item["points"][1][0]))
  232. y2 = int(max(inclde_item["points"][0][1], inclde_item["points"][1][1]))
  233. include_num = 0
  234. for ii in range(0, self.keypoints_length):
  235. x, y = int(keypoints[ii * 3]), int(keypoints[ii * 3 + 1])
  236. flag = (True if x >= x1 and x <= x2 and y >= y1 and y <= y2 else False)
  237. if flag == True:
  238. include_num = include_num + 1
  239. if include_num == self.keypoints_length:
  240. annotation['bbox'] = [x1, y1, x2, y2]
  241. annotation['image_id'] = int(json_file_name_Noext) # 对应的图片ID
  242. annotation['category_id'] = 0
  243. print("num=",num_id)
  244. annotation['id'] = self.coco_id # 对象id
  245. self.coco_id =self.coco_id +1
  246. self.annotations.append(annotation)
  247. temp_annotations.append(annotation)
  248. self.image_id = int(json_file_name_Noext)
  249. if self.verify_flag:
  250. for item in self.categories[0]["skeleton"]:
  251. idx = item[0]
  252. iddx = item[1]
  253. start_point = (annotation['keypoints'][idx * 3 + 0], annotation['keypoints'][idx * 3 + 1])
  254. end_point = (annotation['keypoints'][iddx * 3 + 0], annotation['keypoints'][iddx * 3 + 1])
  255. rect_start_point = (int(annotation['bbox'][0]), int(annotation['bbox'][1]))
  256. rect_end_point = (int(annotation['bbox'][2]), int(annotation['bbox'][3]))
  257. cv2.rectangle(img, rect_start_point, rect_end_point, (255, 0, 255), 1)
  258. cv2.putText(img, self.label, rect_start_point, cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2)
  259. cv2.circle(img, start_point, 3, (255, 0, 0), 3)
  260. cv2.circle(img, end_point, 3, (255, 0, 0), 3)
  261. cv2.line(img, start_point, end_point, (0, 255, 0), 2)
  262. cv2.putText(img, "{}".format(idx), start_point, cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 28, 0), 2)
  263. cv2.imwrite(img_f, img)
  264. if self.verify_labelimg:
  265. self.save_label_img(temp_annotations)
  266. shutil.copy(self.full_img, self.labelimg_path)
  267. self.coco["images"] = self.image
  268. self.coco["categories"] = self.categories
  269. self.coco["annotations"] = self.annotations
  270. def get_images(self, filename, height, width):
  271. image = {}
  272. image["height"] = height
  273. image['width'] = width
  274. image["id"] = self.imagePath
  275. image["file_name"] = filename
  276. return image
  277. def get_categories(self, name, class_id):
  278. category = {}
  279. category["supercategory"] = self.class_id
  280. category['id'] = class_id
  281. category['name'] = name
  282. return category
  283. def save_coco_json(self):
  284. self.labelme_to_coco()
  285. coco_data = self.coco
  286. # 保存json文件
  287. json.dump(coco_data, open(self.save_path, 'w'), indent=4, cls=MyEncoder) # indent=4 更加美观显示
  288. all_img_json_path = r'/home/ubuntu/Downloads/fish_data/val'
  289. coco_path = r"/home/ubuntu/Downloads/fish_data/val.json"
  290. labelimg_path = r"/home/ubuntu/Downloads/labelimg"
  291. verify_path = r"/home/ubuntu/Downloads/verify"
  292. keypoints = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
  293. 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],
  294. [6, 9], [6, 10]] # 故意写的关键点和关键点骨节数不一样
  295. supercategory = "fish"
  296. label = "fish_tilapia"
  297. verify_flag = False
  298. inital_start_id = 0 # 初始下标开始序号 ,根据标注数据集来确定
  299. verify_labelimg_flag = False
  300. full_path, json_file_name = os.path.split(coco_path)
  301. if not os.path.exists(full_path):
  302. os.mkdir(full_path)
  303. if not os.path.exists(verify_path):
  304. os.mkdir(verify_path)
  305. if not os.path.exists(labelimg_path):
  306. os.mkdir(labelimg_path)
  307. cocoData = Tococo(all_img_json_path, coco_path, labelimg_path, keypoints, skeleton, label, verify_flag, verify_path,
  308. inital_start_id, verify_labelimg_flag, supercategory)
  309. cocoData.save_coco_json()
  310. print("finish")

二、测试mmpose得数据集

修改配置文件一/home/ubuntu/mmpose/configs/_base_/datasets/animalpose.py

  1. dataset_info = dict(
  2. dataset_name='animalpose',
  3. paper_info=dict(
  4. author='Cao, Jinkun and Tang, Hongyang and Fang, Hao-Shu and '
  5. 'Shen, Xiaoyong and Lu, Cewu and Tai, Yu-Wing',
  6. title='Cross-Domain Adaptation for Animal Pose Estimation',
  7. container='The IEEE International Conference on '
  8. 'Computer Vision (ICCV)',
  9. year='2019',
  10. homepage='https://sites.google.com/view/animal-pose/',
  11. ),
  12. keypoint_info={
  13. 0:
  14. dict(
  15. name='0', id=0, color=[0, 255, 0], type='upper', swap=''),
  16. 1:
  17. dict(
  18. name='1',
  19. id=1,
  20. color=[255, 128, 0],
  21. type='upper',
  22. swap=''),
  23. 2:
  24. dict(
  25. name='2',
  26. id=2,
  27. color=[0, 255, 0],
  28. type='upper',
  29. swap=''),
  30. 3:
  31. dict(
  32. name='3',
  33. id=3,
  34. color=[255, 128, 0],
  35. type='upper',
  36. swap=''),
  37. 4:
  38. dict(name='4', id=4, color=[51, 153, 255], type='upper', swap=''),
  39. 5:
  40. dict(name='5', id=5, color=[51, 153, 255], type='upper', swap=''),
  41. 6:
  42. dict(
  43. name='6', id=6, color=[51, 153, 255], type='lower',
  44. swap=''),
  45. 7:
  46. dict(
  47. name='7', id=7, color=[51, 153, 255], type='upper', swap=''),
  48. 8:
  49. dict(
  50. name='8',
  51. id=8,
  52. color=[0, 255, 0],
  53. type='upper',
  54. swap=''),
  55. 9:
  56. dict(
  57. name='9',
  58. id=9,
  59. color=[255, 128, 0],
  60. type='upper',
  61. swap=''),
  62. 10:
  63. dict(
  64. name='10',
  65. id=10,
  66. color=[0, 255, 0],
  67. type='lower',
  68. swap='')
  69. },
  70. skeleton_info={
  71. 0: dict(link=('0', '1'), id=0, color=[51, 153, 255]),
  72. 1: dict(link=('1', '3'), id=1, color=[0, 255, 0]),
  73. 2: dict(link=('3', '5'), id=2, color=[255, 128, 0]),
  74. 3: dict(link=('5', '8'), id=3, color=[0, 255, 0]),
  75. 4: dict(link=('6', '9'), id=4, color=[255, 128, 0]),
  76. 5: dict(link=('9', '10'), id=5, color=[51, 153, 255]),
  77. 6: dict(link=('10', '7'), id=6, color=[51, 153, 255]),
  78. 7: dict(link=('7', '4'), id=7, color=[51, 153, 255]),
  79. 8: dict(link=('4', '2'), id=8, color=[0, 255, 0]),
  80. 9: dict(link=('2', '0'), id=9, color=[0, 255, 0]),
  81. 10: dict(link=('5', '6'), id=10, color=[0, 255, 0]),
  82. 11: dict(link=('6', '7'), id=11, color=[0, 255, 0]),
  83. 12: dict(link=('6', '10'), id=12, color=[0, 255, 0]),
  84. 13: dict(link=('6', '9'), id=13, color=[0, 255, 0]),
  85. 14: dict(link=('6', '8'), id=14, color=[0, 255, 0]),
  86. 15: dict(link=('8', '9'), id=11, color=[0, 255, 0]),
  87. },
  88. joint_weights=[
  89. 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,1
  90. ],
  91. # Note: The original paper did not provide enough information about
  92. # the sigmas. We modified from 'https://github.com/cocodataset/'
  93. # 'cocoapi/blob/master/PythonAPI/pycocotools/cocoeval.py#L523'
  94. sigmas=[
  95. 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.
  96. ])

修改配置文件二/home/ubuntu/mmpose/configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py

  1. _base_ = ['../../../_base_/default_runtime.py']
  2. # runtime
  3. train_cfg = dict(max_epochs=1000, val_interval=50)
  4. # optimizer
  5. optim_wrapper = dict(optimizer=dict(
  6. type='Adam',
  7. lr=5e-4,
  8. ))
  9. # learning policy
  10. param_scheduler = [
  11. dict(
  12. type='LinearLR', begin=0, end=500, start_factor=0.001,
  13. by_epoch=False), # warm-up
  14. dict(
  15. type='MultiStepLR',
  16. begin=0,
  17. end=210,
  18. milestones=[170, 200],
  19. gamma=0.1,
  20. by_epoch=True)
  21. ]
  22. # automatically scaling LR based on the actual training batch size
  23. auto_scale_lr = dict(base_batch_size=512)
  24. # hooks
  25. default_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))
  26. # codec settings
  27. codec = dict(
  28. type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)
  29. # model settings
  30. model = dict(
  31. type='TopdownPoseEstimator',
  32. data_preprocessor=dict(
  33. type='PoseDataPreprocessor',
  34. mean=[123.675, 116.28, 103.53],
  35. std=[58.395, 57.12, 57.375],
  36. bgr_to_rgb=True),
  37. backbone=dict(
  38. type='HRNet',
  39. in_channels=3,
  40. extra=dict(
  41. stage1=dict(
  42. num_modules=1,
  43. num_branches=1,
  44. block='BOTTLENECK',
  45. num_blocks=(4, ),
  46. num_channels=(64, )),
  47. stage2=dict(
  48. num_modules=1,
  49. num_branches=2,
  50. block='BASIC',
  51. num_blocks=(4, 4),
  52. num_channels=(32, 64)),
  53. stage3=dict(
  54. num_modules=4,
  55. num_branches=3,
  56. block='BASIC',
  57. num_blocks=(4, 4, 4),
  58. num_channels=(32, 64, 128)),
  59. stage4=dict(
  60. num_modules=3,
  61. num_branches=4,
  62. block='BASIC',
  63. num_blocks=(4, 4, 4, 4),
  64. num_channels=(32, 64, 128, 256))),
  65. init_cfg=dict(
  66. type='Pretrained',
  67. checkpoint='https://download.openmmlab.com/mmpose/'
  68. 'pretrain_models/hrnet_w32-36af842e.pth'),
  69. ),
  70. head=dict(
  71. type='HeatmapHead',
  72. in_channels=32,
  73. out_channels=11,
  74. deconv_out_channels=None,
  75. loss=dict(type='KeypointMSELoss', use_target_weight=True),
  76. decoder=codec),
  77. test_cfg=dict(
  78. flip_test=True,
  79. flip_mode='heatmap',
  80. shift_heatmap=True,
  81. ))
  82. # base dataset settings
  83. dataset_type = 'AnimalPoseDataset'
  84. data_mode = 'topdown'
  85. data_root = '/home/ubuntu/mmpose/fish_data/'
  86. # pipelines
  87. train_pipeline = [
  88. dict(type='LoadImage'),
  89. dict(type='GetBBoxCenterScale'),
  90. dict(type='RandomFlip', direction='horizontal'),
  91. dict(type='RandomHalfBody'),
  92. dict(type='RandomBBoxTransform'),
  93. dict(type='TopdownAffine', input_size=codec['input_size']),
  94. dict(type='GenerateTarget', encoder=codec),
  95. dict(type='PackPoseInputs')
  96. ]
  97. val_pipeline = [
  98. dict(type='LoadImage'),
  99. dict(type='GetBBoxCenterScale'),
  100. dict(type='TopdownAffine', input_size=codec['input_size']),
  101. dict(type='PackPoseInputs')
  102. ]
  103. # data loaders
  104. train_dataloader = dict(
  105. batch_size=32,
  106. num_workers=1,
  107. persistent_workers=True,
  108. sampler=dict(type='DefaultSampler', shuffle=True),
  109. dataset=dict(
  110. type=dataset_type,
  111. data_root=data_root,
  112. data_mode=data_mode,
  113. ann_file='train.json',
  114. data_prefix=dict(img='train/'),
  115. pipeline=train_pipeline,
  116. ))
  117. val_dataloader = dict(
  118. batch_size=32,
  119. num_workers=1,
  120. persistent_workers=True,
  121. drop_last=False,
  122. sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),
  123. dataset=dict(
  124. type=dataset_type,
  125. data_root=data_root,
  126. data_mode=data_mode,
  127. ann_file='val.json',
  128. data_prefix=dict(img='val/'),
  129. test_mode=True,
  130. pipeline=val_pipeline,
  131. ))
  132. test_dataloader = val_dataloader
  133. # evaluators
  134. val_evaluator = dict(
  135. type='CocoMetric', ann_file=data_root + 'val.json')
  136. 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转模型

  1. 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
  2. 04/24 17:19:28 - mmengine - INFO - torch2onnx:
  3. model_cfg: ../mmpose/configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py
  4. deploy_cfg: configs/mmpose/pose-detection_onnxruntime_static.py
  5. 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.
  6. 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.
  7. Loads checkpoint by local backend from path: ../mmpose/work_dirs/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256/epoch_670.pth
  8. /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.
  9. warnings.warn(
  10. 04/24 17:19:31 - mmengine - WARNING - DeprecationWarning: get_onnx_config will be deprecated in the future.
  11. 04/24 17:19:31 - mmengine - INFO - Export PyTorch model to ONNX: ./work-dir/end2end.onnx.
  12. 04/24 17:19:31 - mmengine - WARNING - Can not find torch._C._jit_pass_onnx_autograd_function_process, function rewrite will not be applied
  13. 04/24 17:20:10 - mmengine - INFO - Execute onnx optimize passes.
  14. 04/24 17:20:10 - mmengine - WARNING - Can not optimize model, please build torchscipt extension.
  15. More details: https://github.com/open-mmlab/mmdeploy/tree/1.x/docs/en/experimental/onnx_optimizer.md
  16. 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

转模型

  1. from rknn.api import RKNN
  2. ONNX_MODEL = '/home/ubuntu/mmdeploy/work-dir/end2end.onnx'
  3. RKNN_MODEL = '/home/ubuntu/mmdeploy/work-dir/end2end.rknn'
  4. if __name__ == '__main__':
  5. # Create RKNN object
  6. rknn = RKNN(verbose=True)
  7. # pre-process config
  8. print('--> config model')
  9. rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]],
  10. target_platform='rk3588',
  11. quantized_dtype='asymmetric_quantized-8', optimization_level=3)
  12. print('done')
  13. print('--> Loading model')
  14. ret = rknn.load_onnx(model=ONNX_MODEL)
  15. if ret != 0:
  16. print('Load model failed!')
  17. exit(ret)
  18. print('done')
  19. # Build model
  20. print('--> Building model')
  21. ret = rknn.build(do_quantization=True, dataset='dataset.txt') # ,pre_compile=True
  22. if ret != 0:
  23. print('Build end2end failed!')
  24. exit(ret)
  25. print('done')
  26. # Export rknn model
  27. print('--> Export RKNN model')
  28. ret = rknn.export_rknn(RKNN_MODEL)
  29. if ret != 0:
  30. print('Export end2end.rknn failed!')
  31. exit(ret)
  32. print('done')
  33. rknn.release()

cmakelists.txt

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

main.cpp

  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <queue>
  5. #include "rknn_api.h"
  6. #include "opencv2/core/core.hpp"
  7. #include "opencv2/imgproc/imgproc.hpp"
  8. #include "opencv2/highgui/highgui.hpp"
  9. #include <chrono>
  10. #include <iostream>
  11. using namespace std;
  12. struct Keypoints {
  13. float x;
  14. float y;
  15. float score;
  16. Keypoints() : x(0), y(0), score(0) {}
  17. Keypoints(float x, float y, float score) : x(x), y(y), score(score) {}
  18. };
  19. struct Box {
  20. float center_x;
  21. float center_y;
  22. float scale_x;
  23. float scale_y;
  24. float scale_prob;
  25. float score;
  26. Box() : center_x(0), center_y(0), scale_x(0), scale_y(0), scale_prob(0), score(0) {}
  27. Box(float center_x, float center_y, float scale_x, float scale_y, float scale_prob, float score) :
  28. center_x(center_x), center_y(center_y), scale_x(scale_x), scale_y(scale_y), scale_prob(scale_prob),
  29. score(score) {}
  30. };
  31. void bbox_xywh2cs(float bbox[], float aspect_ratio, float padding, float pixel_std, float *center, float *scale) {
  32. float x = bbox[0];
  33. float y = bbox[1];
  34. float w = bbox[2];
  35. float h = bbox[3];
  36. *center = x + w * 0.5;
  37. *(center + 1) = y + h * 0.5;
  38. if (w > aspect_ratio * h)
  39. h = w * 1.0 / aspect_ratio;
  40. else if (w < aspect_ratio * h)
  41. w = h * aspect_ratio;
  42. *scale = (w / pixel_std) * padding;
  43. *(scale + 1) = (h / pixel_std) * padding;
  44. }
  45. void rotate_point(float *pt, float angle_rad, float *rotated_pt) {
  46. float sn = sin(angle_rad);
  47. float cs = cos(angle_rad);
  48. float new_x = pt[0] * cs - pt[1] * sn;
  49. float new_y = pt[0] * sn + pt[1] * cs;
  50. rotated_pt[0] = new_x;
  51. rotated_pt[1] = new_y;
  52. }
  53. void _get_3rd_point(cv::Point2f a, cv::Point2f b, float *direction) {
  54. float direction_0 = a.x - b.x;
  55. float direction_1 = a.y - b.y;
  56. direction[0] = b.x - direction_1;
  57. direction[1] = b.y + direction_0;
  58. }
  59. void get_affine_transform(float *center, float *scale, float rot, float *output_size, float *shift, bool inv,
  60. cv::Mat &trans) {
  61. float scale_tmp[] = {0, 0};
  62. scale_tmp[0] = scale[0] * 200.0;
  63. scale_tmp[1] = scale[1] * 200.0;
  64. float src_w = scale_tmp[0];
  65. float dst_w = output_size[0];
  66. float dst_h = output_size[1];
  67. float rot_rad = M_PI * rot / 180;
  68. float pt[] = {0, 0};
  69. pt[0] = 0;
  70. pt[1] = src_w * (-0.5);
  71. float src_dir[] = {0, 0};
  72. rotate_point(pt, rot_rad, src_dir);
  73. float dst_dir[] = {0, 0};
  74. dst_dir[0] = 0;
  75. dst_dir[1] = dst_w * (-0.5);
  76. cv::Point2f src[3] = {cv::Point2f(0, 0), cv::Point2f(0, 0), cv::Point2f(0, 0)};
  77. src[0] = cv::Point2f(center[0] + scale_tmp[0] * shift[0], center[1] + scale_tmp[1] * shift[1]);
  78. src[1] = cv::Point2f(center[0] + src_dir[0] + scale_tmp[0] * shift[0],
  79. center[1] + src_dir[1] + scale_tmp[1] * shift[1]);
  80. float direction_src[] = {0, 0};
  81. _get_3rd_point(src[0], src[1], direction_src);
  82. src[2] = cv::Point2f(direction_src[0], direction_src[1]);
  83. cv::Point2f dst[3] = {cv::Point2f(0, 0), cv::Point2f(0, 0), cv::Point2f(0, 0)};
  84. dst[0] = cv::Point2f(dst_w * 0.5, dst_h * 0.5);
  85. dst[1] = cv::Point2f(dst_w * 0.5 + dst_dir[0], dst_h * 0.5 + dst_dir[1]);
  86. float direction_dst[] = {0, 0};
  87. _get_3rd_point(dst[0], dst[1], direction_dst);
  88. dst[2] = cv::Point2f(direction_dst[0], direction_dst[1]);
  89. if (inv) {
  90. trans = cv::getAffineTransform(dst, src);
  91. } else {
  92. trans = cv::getAffineTransform(src, dst);
  93. }
  94. }
  95. void
  96. transform_preds(std::vector<cv::Point2f> coords, std::vector<Keypoints> &target_coords, float *center, float *scale,
  97. int w, int h, bool use_udp = false) {
  98. float scale_x[] = {0, 0};
  99. float temp_scale[] = {scale[0] * 200, scale[1] * 200};
  100. if (use_udp) {
  101. scale_x[0] = temp_scale[0] / (w - 1);
  102. scale_x[1] = temp_scale[1] / (h - 1);
  103. } else {
  104. scale_x[0] = temp_scale[0] / w;
  105. scale_x[1] = temp_scale[1] / h;
  106. }
  107. for (int i = 0; i < coords.size(); i++) {
  108. target_coords[i].x = coords[i].x * scale_x[0] + center[0] - temp_scale[0] * 0.5;
  109. target_coords[i].y = coords[i].y * scale_x[1] + center[1] - temp_scale[1] * 0.5;
  110. }
  111. }
  112. void letterbox(cv::Mat rgb, cv::Mat &img_resize, int target_width, int target_height) {
  113. float shape_0 = rgb.rows;
  114. float shape_1 = rgb.cols;
  115. float new_shape_0 = target_height;
  116. float new_shape_1 = target_width;
  117. float r = std::min(new_shape_0 / shape_0, new_shape_1 / shape_1);
  118. float new_unpad_0 = int(round(shape_1 * r));
  119. float new_unpad_1 = int(round(shape_0 * r));
  120. float dw = new_shape_1 - new_unpad_0;
  121. float dh = new_shape_0 - new_unpad_1;
  122. dw = dw / 2;
  123. dh = dh / 2;
  124. cv::Mat copy_rgb = rgb.clone();
  125. if (int(shape_0) != int(new_unpad_0) && int(shape_1) != int(new_unpad_1)) {
  126. cv::resize(copy_rgb, img_resize, cv::Size(new_unpad_0, new_unpad_1));
  127. copy_rgb = img_resize;
  128. }
  129. int top = int(round(dh - 0.1));
  130. int bottom = int(round(dh + 0.1));
  131. int left = int(round(dw - 0.1));
  132. int right = int(round(dw + 0.1));
  133. cv::copyMakeBorder(copy_rgb, img_resize, top, bottom, left, right, cv::BORDER_CONSTANT, cv::Scalar(0, 0, 0));
  134. }
  135. void printRKNNTensor(rknn_tensor_attr *attr) {
  136. printf("index=%d name=%s n_dims=%d dims=[%d %d %d %d] n_elems=%d size=%d "
  137. "fmt=%d type=%d qnt_type=%d fl=%d zp=%d scale=%f\n",
  138. attr->index, attr->name, attr->n_dims, attr->dims[3], attr->dims[2],
  139. attr->dims[1], attr->dims[0], attr->n_elems, attr->size, 0, attr->type,
  140. attr->qnt_type, attr->fl, attr->zp, attr->scale);
  141. }
  142. int post_process_u8(uint8_t *input0, int model_in_h, int model_in_w) {
  143. return 0;
  144. }
  145. int main(int argc, char **argv) {
  146. float keypoint_score = 0.1f;
  147. cv::Mat bgr = cv::imread("../7.jpg");
  148. cv::Mat rgb;
  149. cv::cvtColor(bgr, rgb, cv::COLOR_BGR2RGB);
  150. float image_target_w = 256;
  151. float image_target_h = 256;
  152. float padding = 1.25;
  153. float pixel_std = 200;
  154. float aspect_ratio = image_target_h / image_target_w;
  155. float bbox[] = {516,210,516+702,210+468,
  156. 9.995332e-01};// 需要检测框架 这个矩形框来自检测框架的坐标 x y w h score 这里来自我自己标注的检测框
  157. // bbox[2] = bbox[2] - bbox[0];
  158. // bbox[3] = bbox[3] - bbox[1];
  159. float center[2] = {0, 0};
  160. float scale[2] = {0, 0};
  161. bbox_xywh2cs(bbox, aspect_ratio, padding, pixel_std, center, scale);
  162. float rot = 0;
  163. float shift[] = {0, 0};
  164. bool inv = false;
  165. float output_size[] = {image_target_h, image_target_w};
  166. cv::Mat trans;
  167. get_affine_transform(center, scale, rot, output_size, shift, inv, trans);
  168. std::cout << trans << std::endl;
  169. cv::Mat detect_image;//= cv::Mat::zeros(image_target_w ,image_target_h, CV_8UC3);
  170. cv::warpAffine(rgb, detect_image, trans, cv::Size(image_target_h, image_target_w), cv::INTER_LINEAR);
  171. const char *model_path = "../end2end_3588.rknn";
  172. // Load model
  173. FILE *fp = fopen(model_path, "rb");
  174. if (fp == NULL) {
  175. printf("fopen %s fail!\n", model_path);
  176. return -1;
  177. }
  178. fseek(fp, 0, SEEK_END);
  179. int model_len = ftell(fp);
  180. void *model = malloc(model_len);
  181. fseek(fp, 0, SEEK_SET);
  182. if (model_len != fread(model, 1, model_len, fp)) {
  183. printf("fread %s fail!\n", model_path);
  184. free(model);
  185. return -1;
  186. }
  187. rknn_context ctx = 0;
  188. int ret = rknn_init(&ctx, model, model_len, 0,NULL);
  189. if (ret < 0) {
  190. printf("rknn_init fail! ret=%d\n", ret);
  191. return -1;
  192. }
  193. /* Query sdk version */
  194. rknn_sdk_version version;
  195. ret = rknn_query(ctx, RKNN_QUERY_SDK_VERSION, &version,
  196. sizeof(rknn_sdk_version));
  197. if (ret < 0) {
  198. printf("rknn_init error ret=%d\n", ret);
  199. return -1;
  200. }
  201. printf("sdk version: %s driver version: %s\n", version.api_version,
  202. version.drv_version);
  203. /* Get input,output attr */
  204. rknn_input_output_num io_num;
  205. ret = rknn_query(ctx, RKNN_QUERY_IN_OUT_NUM, &io_num, sizeof(io_num));
  206. if (ret < 0) {
  207. printf("rknn_init error ret=%d\n", ret);
  208. return -1;
  209. }
  210. printf("model input num: %d, output num: %d\n", io_num.n_input,
  211. io_num.n_output);
  212. rknn_tensor_attr input_attrs[io_num.n_input];
  213. memset(input_attrs, 0, sizeof(input_attrs));
  214. for (int i = 0; i < io_num.n_input; i++) {
  215. input_attrs[i].index = i;
  216. ret = rknn_query(ctx, RKNN_QUERY_INPUT_ATTR, &(input_attrs[i]),
  217. sizeof(rknn_tensor_attr));
  218. if (ret < 0) {
  219. printf("rknn_init error ret=%d\n", ret);
  220. return -1;
  221. }
  222. printRKNNTensor(&(input_attrs[i]));
  223. }
  224. rknn_tensor_attr output_attrs[io_num.n_output];
  225. memset(output_attrs, 0, sizeof(output_attrs));
  226. for (int i = 0; i < io_num.n_output; i++) {
  227. output_attrs[i].index = i;
  228. ret = rknn_query(ctx, RKNN_QUERY_OUTPUT_ATTR, &(output_attrs[i]),
  229. sizeof(rknn_tensor_attr));
  230. printRKNNTensor(&(output_attrs[i]));
  231. }
  232. int input_channel = 3;
  233. int input_width = 0;
  234. int input_height = 0;
  235. if (input_attrs[0].fmt == RKNN_TENSOR_NCHW) {
  236. printf("model is NCHW input fmt\n");
  237. input_width = input_attrs[0].dims[0];
  238. input_height = input_attrs[0].dims[1];
  239. printf("input_width=%d input_height=%d\n", input_width, input_height);
  240. } else {
  241. printf("model is NHWC input fmt\n");
  242. input_width = input_attrs[0].dims[1];
  243. input_height = input_attrs[0].dims[2];
  244. printf("input_width=%d input_height=%d\n", input_width, input_height);
  245. }
  246. printf("model input height=%d, width=%d, channel=%d\n", input_height, input_width,
  247. input_channel);
  248. /* Init input tensor */
  249. rknn_input inputs[1];
  250. memset(inputs, 0, sizeof(inputs));
  251. inputs[0].index = 0;
  252. inputs[0].buf = detect_image.data;
  253. inputs[0].type = RKNN_TENSOR_UINT8;
  254. inputs[0].size = input_width * input_height * input_channel;
  255. inputs[0].fmt = RKNN_TENSOR_NHWC;
  256. inputs[0].pass_through = 0;
  257. /* Init output tensor */
  258. rknn_output outputs[io_num.n_output];
  259. memset(outputs, 0, sizeof(outputs));
  260. for (int i = 0; i < io_num.n_output; i++) {
  261. outputs[i].want_float = 1;
  262. }
  263. printf("img.cols: %d, img.rows: %d\n", detect_image.cols, detect_image.rows);
  264. auto t1 = std::chrono::steady_clock::now();
  265. rknn_inputs_set(ctx, io_num.n_input, inputs);
  266. std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
  267. ret = rknn_run(ctx, NULL);
  268. if (ret < 0) {
  269. printf("ctx error ret=%d\n", ret);
  270. return -1;
  271. }
  272. auto t2 = std::chrono::steady_clock::now();
  273. std::chrono::duration<double> time_span = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - now);
  274. std::cout << "It took me " << time_span.count()*1000 << " ms."<<std::endl;
  275. ret = rknn_outputs_get(ctx, io_num.n_output, outputs, NULL);
  276. if (ret < 0) {
  277. printf("outputs error ret=%d\n", ret);
  278. return -1;
  279. }
  280. int shape_b = 0;
  281. int shape_c = 0;
  282. int shape_w = 0;;
  283. int shape_h = 0;;
  284. for (int i = 0; i < io_num.n_output; ++i) {
  285. shape_b = output_attrs[i].dims[0];
  286. shape_c = output_attrs[i].dims[1];
  287. shape_h = output_attrs[i].dims[2];;
  288. shape_w = output_attrs[i].dims[3];;
  289. }
  290. printf("batch=%d channel=%d width=%d height= %d\n", shape_b, shape_c, shape_w, shape_h);
  291. std::vector<float> vec_result_heap;
  292. float *output = (float *) outputs[0].buf;
  293. for (int i = 0; i < shape_c; i++) {
  294. for (int j = 0; j < shape_h; j++) {
  295. for (int k = 0; k < shape_w; k++) {
  296. float elements = output[i * shape_w * shape_h + j * shape_w + k];
  297. vec_result_heap.emplace_back(elements);
  298. }
  299. }
  300. }
  301. std::vector<Keypoints> all_preds;
  302. std::vector<int> idx;
  303. for (int i = 0; i < shape_c; i++) {
  304. auto begin = vec_result_heap.begin() + i * shape_w * shape_h;
  305. auto end = vec_result_heap.begin() + (i + 1) * shape_w * shape_h;
  306. float maxValue = *max_element(begin, end);
  307. int maxPosition = max_element(begin, end) - begin;
  308. all_preds.emplace_back(Keypoints(0, 0, maxValue));
  309. idx.emplace_back(maxPosition);
  310. }
  311. std::vector<cv::Point2f> vec_point;
  312. for (int i = 0; i < idx.size(); i++) {
  313. int x = idx[i] % shape_w;
  314. int y = idx[i] / shape_w;
  315. vec_point.emplace_back(cv::Point2f(x, y));
  316. }
  317. for (int i = 0; i < shape_c; i++) {
  318. int px = vec_point[i].x;
  319. int py = vec_point[i].y;
  320. if (px > 1 && px < shape_w - 1 && py > 1 && py < shape_h - 1) {
  321. float diff_0 = vec_result_heap[py * shape_w + px + 1] - vec_result_heap[py * shape_w + px - 1];
  322. float diff_1 = vec_result_heap[(py + 1) * shape_w + px] - vec_result_heap[(py - 1) * shape_w + px];
  323. vec_point[i].x += diff_0 == 0 ? 0 : (diff_0 > 0) ? 0.25 : -0.25;
  324. vec_point[i].y += diff_1 == 0 ? 0 : (diff_1 > 0) ? 0.25 : -0.25;
  325. }
  326. }
  327. std::vector<Box> all_boxes;
  328. bool heap_map = false;
  329. if (heap_map) {
  330. all_boxes.emplace_back(Box(center[0], center[1], scale[0], scale[1], scale[0] * scale[1] * 400, bbox[4]));
  331. }
  332. transform_preds(vec_point, all_preds, center, scale, shape_w, shape_h);
  333. int skeleton[15][2] = {{0, 1},{1, 3},{3, 5},{5, 8},
  334. {8, 9},{9, 10},{10, 7},{7,4},{4, 2},
  335. {2, 0},{5, 6},
  336. {6, 7},{6, 10},{6, 8},{6, 9}};
  337. cv::rectangle(bgr, cv::Point(bbox[0], bbox[1]), cv::Point(bbox[0] + bbox[2], bbox[1] + bbox[3]),
  338. cv::Scalar(255, 0, 0));
  339. for (int i = 0; i < all_preds.size(); i++) {
  340. if (all_preds[i].score > keypoint_score) {
  341. cv::circle(bgr, cv::Point(all_preds[i].x, all_preds[i].y), 3, cv::Scalar(0, 255, 120), -1);//画点,其实就是实心圆
  342. }
  343. }
  344. for (int i = 0; i < sizeof(skeleton) / sizeof(sizeof(skeleton[1])); i++) {
  345. int x0 = all_preds[skeleton[i][0]].x;
  346. int y0 = all_preds[skeleton[i][0]].y;
  347. int x1 = all_preds[skeleton[i][1]].x;
  348. int y1 = all_preds[skeleton[i][1]].y;
  349. cv::line(bgr, cv::Point(x0, y0), cv::Point(x1, y1),
  350. cv::Scalar(0, 255, 0), 1);
  351. }
  352. cv::imwrite("../image.jpg", bgr);
  353. ret = rknn_outputs_release(ctx, io_num.n_output, outputs);
  354. if (ret < 0) {
  355. printf("rknn_query fail! ret=%d\n", ret);
  356. goto Error;
  357. }
  358. Error:
  359. if (ctx > 0)
  360. ret=rknn_destroy(ctx);
  361. printf("%d \n",ret);
  362. //感觉官方固件有问题,销毁对象存在问题,或许是我的固件有问题 https://t.rock-chips.com/forum.php?mod=viewthread&tid=2365
  363. if (model)
  364. free(model);
  365. if (fp)
  366. fclose(fp);
  367. return 0;
  368. }

测试结果

附录 mp4转h264(瑞芯微用第二种)

  1. ubuntu@ubuntu:~/aaa$ ffmpeg -i people.mp4 -codec copy -bsf: hevc_mp4toannexb -f h264 sample.h264
  2. ubuntu@ubuntu:~/aaa$ ffmpeg -i people.mp4 -vcodec h264 people.h264

参考

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/842692
推荐阅读
相关标签
  

闽ICP备14008679号