4151|3

84

帖子

0

TA的资源

一粒金砂(高级)

楼主
 

AI挑战营(进阶):3. onnx2rknn [复制链接]

在上一节中,我们获得了retinaface和facenet的onnx模型,在这一节中我们将其转换为RKNPU能够识别并运行的rknn格式。

环境安装

参考我之前写的一篇博客:https://bbs.elecfans.com/jishu_2454118_1_1.html

模型转换

retinaface

数据集准备

首先上传一张包含人脸的校准数据集,并将其路径存放至retinaface_dataset.txt文件中。

retinaface_dataset.txt内容如下:

  1. ../../img/detection/face.jpg

模型转换

编写模型转换脚本:

  1. import sys
  2. from rknn.api import RKNN
  3. def parse_arg():
  4. if len(sys.argv) < 5:
  5. print("Usage: python3 {} [onnx_model_path] [dataset_path] [output_rknn_path] [model_type]".format(sys.argv[0]));
  6. exit(1)
  7. model_path = sys.argv[1]
  8. dataset_path= sys.argv[2]
  9. output_path = sys.argv[3]
  10. model_type = sys.argv[4]
  11. return model_path, dataset_path, output_path,model_type
  12. if __name__ == '__main__':
  13. model_path, dataset_path, output_path, model_type= parse_arg()
  14. # Create RKNN object
  15. rknn = RKNN(verbose=False)
  16. # Pre-process config
  17. print('--> Config model')
  18. if model_type == 'Retinaface':
  19. rknn.config(mean_values=[[104, 117, 123]], std_values=[[1, 1, 1]], target_platform='rv1103',
  20. quantized_algorithm="normal", quant_img_RGB2BGR=True,optimization_level=0)
  21. print("Use retinaface mode")
  22. else:
  23. rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]], target_platform='rv1103')
  24. print('done')
  25. # Load model
  26. print('--> Loading model')
  27. ret = rknn.load_onnx(model=model_path)
  28. if ret != 0:
  29. print('Load model failed!')
  30. exit(ret)
  31. print('done')
  32. # Build model
  33. print('--> Building model')
  34. ret = rknn.build(do_quantization=True, dataset=dataset_path)
  35. if ret != 0:
  36. print('Build model failed!')
  37. exit(ret)
  38. print('done')
  39. # Export rknn model
  40. print('--> Export rknn model')
  41. ret = rknn.export_rknn(output_path)
  42. if ret != 0:
  43. print('Export rknn model failed!')
  44. exit(ret)
  45. print('done')
  46. # Release
  47. rknn.release()

执行convert.py进行模型转换:

  1. python convert.py ../model_zoo/export/retinaface.onnx ./dataset/retinaface_dataset.txt ../model_zoo/retinaface.rknn Retinaface

facenet

数据集准备

首先上传一张包含人脸的校准数据集,并将其路径存放至facenet_dataset.txt文件中。

facenet_dataset.txt内容如下:

  1. ../../img/recongnition/calib.jpg

模型转换

执行convert.py进行模型转换:

  1. python convert.py ../model_zoo/export/facenet.onnx ./dataset/facenet_dataset.txt ../model_zoo/facenet.rknn Facenet

转换完成后,就能够分别得到两个相应的rknn模型文件于model_zoo目录下:

模型评估

数据集准备

首先准备验证数据集:

目录结构如下:

  1. eval
  2. ├── dataset
  3. │ ├── facenet
  4. │ │ ├── 1_001.jpg
  5. │ │ ├── 1_002.jpg
  6. │ │ └── 2_001.jpg
  7. │ └── retinaface
  8. │ └── j1.jpg
  9. ├── facenet.py
  10. └── retinaface.py

retinaface

  1. import os
  2. import sys
  3. import urllib
  4. import urllib.request
  5. import time
  6. import numpy as np
  7. import cv2
  8. from math import ceil
  9. from itertools import product as product
  10. from rknn.api import RKNN
  11. DATASET_PATH = '../dataset/retinaface_dataset.txt'
  12. DEFAULT_QUANT = True
  13. def letterbox_resize(image, size, bg_color):
  14. """
  15. letterbox_resize the image according to the specified size
  16. :param image: input image, which can be a NumPy array or file path
  17. :param size: target size (width, height)
  18. :param bg_color: background filling data
  19. :return: processed image
  20. """
  21. if isinstance(image, str):
  22. image = cv2.imread(image)
  23. target_width, target_height = size
  24. image_height, image_width, _ = image.shape
  25. # 计算调整后的图像尺寸
  26. aspect_ratio = min(target_width / image_width, target_height / image_height)
  27. new_width = int(image_width * aspect_ratio)
  28. new_height = int(image_height * aspect_ratio)
  29. # 使用 cv2.resize() 进行等比缩放
  30. image = cv2.resize(image, (new_width, new_height), interpolation=cv2.INTER_AREA)
  31. # 创建新的画布并进行填充
  32. result_image = np.ones((target_height, target_width, 3), dtype=np.uint8) * bg_color
  33. offset_x = (target_width - new_width) // 2
  34. offset_y = (target_height - new_height) // 2
  35. result_image[offset_y:offset_y + new_height, offset_x:offset_x + new_width] = image
  36. return result_image, aspect_ratio, offset_x, offset_y
  37. def PriorBox(image_size): #image_size Support (320,320) and (640,640)
  38. anchors = []
  39. min_sizes = [[16, 32], [64, 128], [256, 512]]
  40. steps = [8, 16, 32]
  41. feature_maps = [[ceil(image_size[0] / step), ceil(image_size[1] / step)] for step in steps]
  42. for k, f in enumerate(feature_maps):
  43. min_sizes_ = min_sizes[k]
  44. for i, j in product(range(f[0]), range(f[1])):
  45. for min_size in min_sizes_:
  46. s_kx = min_size / image_size[1]
  47. s_ky = min_size / image_size[0]
  48. dense_cx = [x * steps[k] / image_size[1] for x in [j + 0.5]]
  49. dense_cy = [y * steps[k] / image_size[0] for y in [i + 0.5]]
  50. for cy, cx in product(dense_cy, dense_cx):
  51. anchors += [cx, cy, s_kx, s_ky]
  52. output = np.array(anchors).reshape(-1, 4)
  53. print("image_size:",image_size," num_priors=",output.shape[0])
  54. return output
  55. def box_decode(loc, priors):
  56. """Decode locations from predictions using priors to undo
  57. the encoding we did for offset regression at train time.
  58. Args:
  59. loc (tensor): location predictions for loc layers,
  60. Shape: [num_priors,4]
  61. priors (tensor): Prior boxes in center-offset form.
  62. Shape: [num_priors,4].
  63. variances: (list[float]) Variances of priorboxes
  64. Return:
  65. decoded bounding box predictions
  66. """
  67. variances = [0.1, 0.2]
  68. boxes = np.concatenate((
  69. priors[:, :2] + loc[:, :2] * variances[0] * priors[:, 2:],
  70. priors[:, 2:] * np.exp(loc[:, 2:] * variances[1])), axis=1)
  71. boxes[:, :2] -= boxes[:, 2:] / 2
  72. boxes[:, 2:] += boxes[:, :2]
  73. return boxes
  74. def decode_landm(pre, priors):
  75. """Decode landm from predictions using priors to undo
  76. the encoding we did for offset regression at train time.
  77. Args:
  78. pre (tensor): landm predictions for loc layers,
  79. Shape: [num_priors,10]
  80. priors (tensor): Prior boxes in center-offset form.
  81. Shape: [num_priors,4].
  82. variances: (list[float]) Variances of priorboxes
  83. Return:
  84. decoded landm predictions
  85. """
  86. variances = [0.1, 0.2]
  87. landmarks = np.concatenate((
  88. priors[:, :2] + pre[:, :2] * variances[0] * priors[:, 2:],
  89. priors[:, :2] + pre[:, 2:4] * variances[0] * priors[:, 2:],
  90. priors[:, :2] + pre[:, 4:6] * variances[0] * priors[:, 2:],
  91. priors[:, :2] + pre[:, 6:8] * variances[0] * priors[:, 2:],
  92. priors[:, :2] + pre[:, 8:10] * variances[0] * priors[:, 2:]
  93. ), axis=1)
  94. return landmarks
  95. def nms(dets, thresh):
  96. """Pure Python NMS baseline."""
  97. x1 = dets[:, 0]
  98. y1 = dets[:, 1]
  99. x2 = dets[:, 2]
  100. y2 = dets[:, 3]
  101. scores = dets[:, 4]
  102. areas = (x2 - x1 + 1) * (y2 - y1 + 1)
  103. order = scores.argsort()[::-1]
  104. keep = []
  105. while order.size > 0:
  106. i = order[0]
  107. keep.append(i)
  108. xx1 = np.maximum(x1<i>, x1[order[1:]])
  109. yy1 = np.maximum(y1<i>, y1[order[1:]])
  110. xx2 = np.minimum(x2<i>, x2[order[1:]])
  111. yy2 = np.minimum(y2<i>, y2[order[1:]])
  112. w = np.maximum(0.0, xx2 - xx1 + 1)
  113. h = np.maximum(0.0, yy2 - yy1 + 1)
  114. inter = w * h
  115. ovr = inter / (areas<i> + areas[order[1:]] - inter)
  116. inds = np.where(ovr <= thresh)[0]
  117. order = order[inds + 1]
  118. return keep
  119. if __name__ == '__main__':
  120. # 创建RKNN对象
  121. rknn = RKNN()
  122. # 预处理设置
  123. print('--> Config model')
  124. rknn.config(mean_values=[[104, 117, 123]], std_values=[[1, 1, 1]], target_platform="rv1106",
  125. quantized_algorithm="normal", quant_img_RGB2BGR=True) # mmse
  126. print('done')
  127. # 载入模型
  128. print('--> Loading model')
  129. ret = rknn.load_onnx(model="../../model_zoo/export/retinaface.onnx")
  130. if ret != 0:
  131. print('Load model failed!')
  132. exit(ret)
  133. print('done')
  134. # 创建模型
  135. print('--> Building model')
  136. ret = rknn.build(do_quantization=True, dataset=DATASET_PATH)
  137. if ret != 0:
  138. print('Build model failed!')
  139. exit(ret)
  140. print('done')
  141. # 输入图像
  142. img = cv2.imread('./dataset/retinaface/j1.jpg')
  143. img_height, img_width, _ = img.shape
  144. model_height, model_width = (640, 640)
  145. letterbox_img, aspect_ratio, offset_x, offset_y = letterbox_resize(img, (model_height,model_width), 114) # letterbox缩放
  146. infer_img = letterbox_img[..., ::-1] # BGR2RGB
  147. # 初始化运行时环境
  148. print('--> Init runtime environment')
  149. ret = rknn.init_runtime()
  150. if ret != 0:
  151. print('Init runtime environment failed!')
  152. exit(ret)
  153. print('done')
  154. # 运行
  155. print('--> Running model')
  156. outputs = rknn.inference(inputs=[infer_img])
  157. loc, conf, landmarks = outputs #获取输出数据
  158. priors = PriorBox(image_size=(model_height, model_width)) # 获取先验框
  159. boxes = box_decode(loc.squeeze(0), priors) # 解码输出数据
  160. # letterbox
  161. scale = np.array([model_width, model_height,
  162. model_width, model_height])
  163. boxes = boxes * scale // 1 # face box
  164. boxes[...,0::2] =np.clip((boxes[...,0::2] - offset_x) / aspect_ratio, 0, img_width) #letterbox
  165. boxes[...,1::2] =np.clip((boxes[...,1::2] - offset_y) / aspect_ratio, 0, img_height) #letterbox
  166. scores = conf.squeeze(0)[:, 1] # 人脸检测的置信度
  167. landmarks = decode_landm(landmarks.squeeze(
  168. 0), priors) # face keypoint data
  169. scale_landmarks = np.array([model_width, model_height, model_width, model_height,
  170. model_width, model_height, model_width, model_height,
  171. model_width, model_height])
  172. landmarks = landmarks * scale_landmarks // 1
  173. landmarks[...,0::2] = np.clip((landmarks[...,0::2] - offset_x) / aspect_ratio, 0, img_width) #letterbox
  174. landmarks[...,1::2] = np.clip((landmarks[...,1::2] - offset_y) / aspect_ratio, 0, img_height) #letterbox
  175. # 丢弃置信度过低的部分
  176. inds = np.where(scores > 0.5)[0]
  177. boxes = boxes[inds]
  178. landmarks = landmarks[inds]
  179. scores = scores[inds]
  180. order = scores.argsort()[::-1]
  181. boxes = boxes[order]
  182. landmarks = landmarks[order]
  183. scores = scores[order]
  184. # 非极大值抑制
  185. dets = np.hstack((boxes, scores[:, np.newaxis])).astype(
  186. np.float32, copy=False)
  187. keep = nms(dets, 0.2)
  188. dets = dets[keep, :]
  189. landmarks = landmarks[keep]
  190. dets = np.concatenate((dets, landmarks), axis=1)
  191. # 画框标记
  192. for data in dets:
  193. if data[4] < 0.5:
  194. continue
  195. print("face @ (%d %d %d %d) %f"%(data[0], data[1], data[2], data[3], data[4]))
  196. text = "{:.4f}".format(data[4])
  197. data = list(map(int, data))
  198. cv2.rectangle(img, (data[0], data[1]),
  199. (data[2], data[3]), (0, 0, 255), 2)
  200. cx = data[0]
  201. cy = data[1] + 12
  202. cv2.putText(img, text, (cx, cy),
  203. cv2.FONT_HERSHEY_DUPLEX, 0.5, (255, 255, 255))
  204. # landmarks
  205. cv2.circle(img, (data[5], data[6]), 1, (0, 0, 255), 5)
  206. cv2.circle(img, (data[7], data[8]), 1, (0, 255, 255), 5)
  207. cv2.circle(img, (data[9], data[10]), 1, (255, 0, 255), 5)
  208. cv2.circle(img, (data[11], data[12]), 1, (0, 255, 0), 5)
  209. cv2.circle(img, (data[13], data[14]), 1, (255, 0, 0), 5)
  210. img_path = './result.jpg'
  211. cv2.imwrite(img_path, img)
  212. print("save image in", img_path)
  213. # 释放
  214. rknn.release()

执行结果如下:

facenet

  1. import numpy as np
  2. import cv2
  3. import os
  4. from rknn.api import RKNN
  5. from PIL import Image
  6. from sklearn import preprocessing
  7. from scipy.spatial.distance import pdist
  8. os.environ['RKNN_DRAW_DATA_DISTRIBUTE']="1"
  9. if __name__ == '__main__':
  10. BUILD_QUANT = True
  11. # Create RKNN object
  12. rknn = RKNN()
  13. print('--> config model')
  14. rknn.config(mean_values=[[0, 0, 0]], std_values=[[255, 255, 255]], target_platform='rv1103')
  15. print('done')
  16. # Load model
  17. print('--> Lccoading model')
  18. ret = rknn.load_onnx(model='../../model_zoo/export/facenet.onnx')
  19. if ret != 0:
  20. print('Load facenet failed!')
  21. exit(ret)
  22. print('done')
  23. # Build model
  24. print('--> Building model')
  25. ret = rknn.build(do_quantization=True, dataset='../dataset/facenet_dataset.txt')
  26. if ret != 0:
  27. print('Build model failed!')
  28. exit(ret)
  29. print('done')
  30. # Init runtime
  31. print('--> Init runtime environment')
  32. ret = rknn.init_runtime()
  33. if ret != 0:
  34. print('Init runtime environment failed')
  35. exit(ret)
  36. print('done')
  37. # Set inputs and inference
  38. image_1 = Image.open("./dataset/facenet/1_001.jpg")
  39. image_1 = image_1.resize((160,160), Image.BICUBIC)
  40. img1 = np.asarray(image_1, np.uint8)
  41. outputs1 = np.array(rknn.inference(data_format='nhwc', inputs=[img1])[0])
  42. outputs1 = preprocessing.normalize(outputs1, norm='l2')
  43. image_2 = Image.open("./dataset/facenet/1_002.jpg")
  44. image_2 = image_2.resize((160,160), Image.BICUBIC)
  45. img2 = np.asarray(image_2, np.uint8)
  46. outputs2 = np.array(rknn.inference(data_format='nhwc', inputs=[img2])[0])
  47. outputs2 = preprocessing.normalize(outputs2, norm='l2')
  48. # Get distance
  49. distance = np.linalg.norm(outputs2 - outputs1, axis=1)
  50. print("distance:", distance)
  51. rknn.release()

执行结果如下:

工程文件在附录中。

最新回复

大佬大佬   详情 回复 发表于 2024-12-6 15:32
点赞 关注

回复
举报

3

帖子

0

TA的资源

一粒金砂(初级)

沙发
 

这群人真酷

 

点评

必须的  详情 回复 发表于 2024-12-5 22:17
 
 

回复

84

帖子

0

TA的资源

一粒金砂(高级)

板凳
 

必须的

 
 
 

回复

37

帖子

2

TA的资源

一粒金砂(中级)

4
 

大佬大佬

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
有奖直播 | AI之眼——安森美图像传感器 报名中
直播时间:2025年4月25日(周五)上午10:00-11:30
直播主题:AI之眼——安森美图像传感器
报名观看直播、直播间提问、填写问卷均有机会获得精美礼品!

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 10

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表