1import numpy as np 2 3import re 4import math 5import random 6import cv2 7 8from rknn.api import RKNN 9 10INPUT_SIZE = 300 11 12NUM_RESULTS = 1917 13NUM_CLASSES = 91 14 15Y_SCALE = 10.0 16X_SCALE = 10.0 17H_SCALE = 5.0 18W_SCALE = 5.0 19 20 21def expit(x): 22 return 1. / (1. + math.exp(-x)) 23 24 25def unexpit(y): 26 return -1.0 * math.log((1.0 / y) - 1.0) 27 28 29def CalculateOverlap(xmin0, ymin0, xmax0, ymax0, xmin1, ymin1, xmax1, ymax1): 30 w = max(0.0, min(xmax0, xmax1) - max(xmin0, xmin1)) 31 h = max(0.0, min(ymax0, ymax1) - max(ymin0, ymin1)) 32 i = w * h 33 u = (xmax0 - xmin0) * (ymax0 - ymin0) + (xmax1 - xmin1) * (ymax1 - ymin1) - i 34 35 if u <= 0.0: 36 return 0.0 37 38 return i / u 39 40 41def load_box_priors(): 42 box_priors_ = [] 43 fp = open('./box_priors.txt', 'r') 44 ls = fp.readlines() 45 for s in ls: 46 aList = re.findall('([-+]?\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?', s) 47 for ss in aList: 48 aNum = float((ss[0]+ss[2])) 49 box_priors_.append(aNum) 50 fp.close() 51 52 box_priors = np.array(box_priors_) 53 box_priors = box_priors.reshape(4, NUM_RESULTS) 54 55 return box_priors 56 57 58if __name__ == '__main__': 59 60 # Create RKNN object 61 rknn = RKNN(verbose=True) 62 63 # Pre-process config 64 print('--> Config model') 65 rknn.config(mean_values=[127.5, 127.5, 127.5], std_values=[127.5, 127.5, 127.5]) 66 print('done') 67 68 # Load model 69 print('--> Loading model') 70 ret = rknn.load_tensorflow(tf_pb='./ssd_mobilenet_v1_coco_2017_11_17.pb', 71 inputs=['Preprocessor/sub'], 72 outputs=['concat', 'concat_1'], 73 input_size_list=[[1, INPUT_SIZE, INPUT_SIZE, 3]]) 74 if ret != 0: 75 print('Load model failed!') 76 exit(ret) 77 print('done') 78 79 # Build Model 80 print('--> Building model') 81 ret = rknn.build(do_quantization=True, dataset='./dataset.txt') 82 if ret != 0: 83 print('Build model failed!') 84 exit(ret) 85 print('done') 86 87 # Export rknn model 88 print('--> Export rknn model') 89 ret = rknn.export_rknn('./ssd_mobilenet_v1_coco.rknn') 90 if ret != 0: 91 print('Export rknn model failed!') 92 exit(ret) 93 print('done') 94 95 # Set inputs 96 orig_img = cv2.imread('./road.bmp') 97 img = cv2.cvtColor(orig_img, cv2.COLOR_BGR2RGB) 98 img = cv2.resize(img, (INPUT_SIZE, INPUT_SIZE), interpolation=cv2.INTER_CUBIC) 99 100 # Init runtime environment 101 print('--> Init runtime environment') 102 ret = rknn.init_runtime() 103 if ret != 0: 104 print('Init runtime environment failed!') 105 exit(ret) 106 print('done') 107 108 # Inference 109 print('--> Running model') 110 outputs = rknn.inference(inputs=[img]) 111 print('done') 112 113 predictions = outputs[0].reshape((1, NUM_RESULTS, 4)) 114 np.save('./tensorflow_ssd_mobilenet_v1_0.npy', outputs[0]) 115 outputClasses = outputs[1].reshape((1, NUM_RESULTS, NUM_CLASSES)) 116 np.save('./tensorflow_ssd_mobilenet_v1_1.npy', outputs[0]) 117 candidateBox = np.zeros([2, NUM_RESULTS], dtype=int) 118 classScore = [-1000.0] * NUM_RESULTS 119 vaildCnt = 0 120 121 box_priors = load_box_priors() 122 123 # Post Process 124 # got valid candidate box 125 for i in range(0, NUM_RESULTS): 126 topClassScore = -1000 127 topClassScoreIndex = -1 128 129 # Skip the first catch-all class. 130 for j in range(1, NUM_CLASSES): 131 score = expit(outputClasses[0][i][j]) 132 133 if score > topClassScore: 134 topClassScoreIndex = j 135 topClassScore = score 136 137 if topClassScore > 0.4: 138 candidateBox[0][vaildCnt] = i 139 candidateBox[1][vaildCnt] = topClassScoreIndex 140 classScore[vaildCnt] = topClassScore 141 vaildCnt += 1 142 143 # calc position 144 for i in range(0, vaildCnt): 145 if candidateBox[0][i] == -1: 146 continue 147 148 n = candidateBox[0][i] 149 ycenter = predictions[0][n][0] / Y_SCALE * box_priors[2][n] + box_priors[0][n] 150 xcenter = predictions[0][n][1] / X_SCALE * box_priors[3][n] + box_priors[1][n] 151 h = math.exp(predictions[0][n][2] / H_SCALE) * box_priors[2][n] 152 w = math.exp(predictions[0][n][3] / W_SCALE) * box_priors[3][n] 153 154 ymin = ycenter - h / 2. 155 xmin = xcenter - w / 2. 156 ymax = ycenter + h / 2. 157 xmax = xcenter + w / 2. 158 159 predictions[0][n][0] = ymin 160 predictions[0][n][1] = xmin 161 predictions[0][n][2] = ymax 162 predictions[0][n][3] = xmax 163 164 # NMS 165 for i in range(0, vaildCnt): 166 if candidateBox[0][i] == -1: 167 continue 168 169 n = candidateBox[0][i] 170 xmin0 = predictions[0][n][1] 171 ymin0 = predictions[0][n][0] 172 xmax0 = predictions[0][n][3] 173 ymax0 = predictions[0][n][2] 174 175 for j in range(i+1, vaildCnt): 176 m = candidateBox[0][j] 177 178 if m == -1: 179 continue 180 181 xmin1 = predictions[0][m][1] 182 ymin1 = predictions[0][m][0] 183 xmax1 = predictions[0][m][3] 184 ymax1 = predictions[0][m][2] 185 186 iou = CalculateOverlap(xmin0, ymin0, xmax0, ymax0, xmin1, ymin1, xmax1, ymax1) 187 188 if iou >= 0.45: 189 candidateBox[0][j] = -1 190 191 # Draw result 192 for i in range(0, vaildCnt): 193 if candidateBox[0][i] == -1: 194 continue 195 196 n = candidateBox[0][i] 197 198 xmin = max(0.0, min(1.0, predictions[0][n][1])) * INPUT_SIZE 199 ymin = max(0.0, min(1.0, predictions[0][n][0])) * INPUT_SIZE 200 xmax = max(0.0, min(1.0, predictions[0][n][3])) * INPUT_SIZE 201 ymax = max(0.0, min(1.0, predictions[0][n][2])) * INPUT_SIZE 202 203 print("%d @ (%d, %d) (%d, %d) score=%f" % (candidateBox[1][i], xmin, ymin, xmax, ymax, classScore[i])) 204 cv2.rectangle(orig_img, (int(xmin), int(ymin)), (int(xmax), int(ymax)), 205 (random.random()*255, random.random()*255, random.random()*255), 3) 206 207 cv2.imwrite("out.jpg", orig_img) 208 209 rknn.release() 210