onnx-rknn


一,對模型進行轉化

from rknn.api import RKNN
import cv2
import time
import numpy as np

if __name__ == '__main__':

    # Create RKNN object
    rknn = RKNN(verbose=True)
    
    # pre-process config
    print('--> config model')
    # 配置模型輸入,用於NPU對數據輸入的預處理
    # channel_mean_value='0 0 0 255',那么模型推理時,將會對RGB數據做如下轉換
    # (R - 0)/255, (G - 0)/255, (B - 0)/255。推理時,RKNN模型會自動做均值和歸一化處理
    # reorder_channel=’0 1 2’用於指定是否調整RBG順序,設置成0 1 2即按輸入的RGB順序不做調整
    # reorder_channel=’2 1 0’表示交換0和2通道,如果輸入是RGB,將會被調整為BGR。如果是BGR將會被
    # 調整為BGR    
    rknn.config(channel_mean_value='0 0 0 1', reorder_channel='0 1 2')
    print('done')

    # Load tensorflow model
    ret = rknn.load_onnx(model = './centerface_1088_1920.onnx')
    if ret != 0:
        print('Load model failed!')
        exit(ret)
    print('done')

    # Build model
    print('--> Building model')

    #ret = rknn.build(do_quantization=False)
    ret = rknn.build(do_quantization=True, dataset='./datasets.txt')
    if ret != 0:
        print('Build model failed!')
        exit(ret)
    print('done')
    # Export rknn model
    print('--> Export RKNN model')
    ret = rknn.export_rknn('./centerface_quantization_1088_1920.rknn')
    if ret != 0:
        print('Export model failed!')
        exit(ret)
    print('done')

    rknn.release()

二.對模型進行推理

import cv2
import time
import numpy as np
#import toybrick as toy
from random import randint
from rknn.api import RKNN




def decode( heatmap, scale, offset, landmark, size, threshold=0.1,landmarks = False):
    heatmap = np.squeeze(heatmap)
    scale0, scale1 = scale[0, 0, :, :], scale[0, 1, :, :]
    offset0, offset1 = offset[0, 0, :, :], offset[0, 1, :, :]
    c0, c1 = np.where(heatmap > threshold)
    if landmarks:
        boxes, lms = [], []
    else:
        boxes = []
    if len(c0) > 0:
        for i in range(len(c0)):
            s0, s1 = np.exp(scale0[c0[i], c1[i]]) * 4, np.exp(scale1[c0[i], c1[i]]) * 4
            o0, o1 = offset0[c0[i], c1[i]], offset1[c0[i], c1[i]]
            s = heatmap[c0[i], c1[i]]
            x1, y1 = max(0, (c1[i] + o1 + 0.5) * 4 - s1 / 2), max(0, (c0[i] + o0 + 0.5) * 4 - s0 / 2)
            x1, y1 = min(x1, size[1]), min(y1, size[0])
            boxes.append([x1, y1, min(x1 + s1, size[1]), min(y1 + s0, size[0]), s])
            if landmarks:
                lm = []
                for j in range(5):
                    lm.append(landmark[0, j * 2 + 1, c0[i], c1[i]] * s1 + x1)
                    lm.append(landmark[0, j * 2, c0[i], c1[i]] * s0 + y1)
                lms.append(lm)
        boxes = np.asarray(boxes, dtype=np.float32)
        keep = nms(boxes[:, :4], boxes[:, 4], 0.3)
        boxes = boxes[keep, :]
        if landmarks:
            lms = np.asarray(lms, dtype=np.float32)
            lms = lms[keep, :]
    if landmarks:
        return boxes, lms
    else:
        return boxes

def nms(boxes, scores, nms_thresh):
    x1 = boxes[:, 0]
    y1 = boxes[:, 1]
    x2 = boxes[:, 2]
    y2 = boxes[:, 3]
    areas = (x2 - x1 + 1) * (y2 - y1 + 1)
    order = np.argsort(scores)[::-1]
    num_detections = boxes.shape[0]
    suppressed = np.zeros((num_detections,), dtype=np.bool)

    keep = []
    for _i in range(num_detections):
        i = order[_i]
        if suppressed[i]:
            continue
        keep.append(i)

        ix1 = x1[i]
        iy1 = y1[i]
        ix2 = x2[i]
        iy2 = y2[i]
        iarea = areas[i]

        for _j in range(_i + 1, num_detections):
            j = order[_j]
            if suppressed[j]:
                continue

            xx1 = max(ix1, x1[j])
            yy1 = max(iy1, y1[j])
            xx2 = min(ix2, x2[j])
            yy2 = min(iy2, y2[j])
            w = max(0, xx2 - xx1 + 1)
            h = max(0, yy2 - yy1 + 1)

            inter = w * h
            ovr = inter / (iarea + areas[j] - inter)
            if ovr >= nms_thresh:
                suppressed[j] = True

    return keep 
       


def main():

    input_size = (1920,1088)
    decode_input_size = (1088,1920)
   
    
    #導入模型
    rknn = RKNN()
    #非量化模型
    #rknn.load_rknn('./centerface_1088_1920.rknn')
    #量化模型
    rknn.load_rknn('./centerface_quantization_1088_1920.rknn')
    ret = rknn.init_runtime(target='rk1808', target_sub_class='AICS')
    if ret != 0:
        print('Init runtime environment failed')
        exit(ret)
    print('done')
    
    #在圖片上進行檢測
    while True:
        img = cv2.imread('C:\\Users\\Administrator\\Desktop\\1.jpg')
        #模型需要的寬度有所變化
        img = cv2.resize(img,(1920,1088))
        frame = img.copy()
        #增加一個維度
        frame = frame[:, :, :, np.newaxis]
        #轉換為模型需要的輸入維度(1, 3, 1088, 1920)
        frame = frame.transpose([3, 2, 0, 1])
        print(frame.shape)
        
        t = time.time()
        output = rknn.inference(inputs=[frame], data_format="nchw")
        print("time:", time.time()-t)
        
        heatmap = output[0].reshape(1, 1, 272, 480)
        scale   = output[1].reshape(1, 2, 272, 480)
        offset  = output[2].reshape(1, 2, 272, 480)
        lms     = output[3].reshape(1, 10,272, 480)
        
        dets , lms = decode(heatmap, scale, offset, lms, decode_input_size, threshold=0.58,landmarks = True)
        print("檢測到人臉數%d" %(len(dets),))
        for det in dets:
            boxes, score = det[:4], det[4]
            cv2.rectangle(img, (int(boxes[0]), int(boxes[1])), (int(boxes[2]), int(boxes[3])), (2, 255, 0), 1)
        for lm in lms:
            cv2.circle(img, (int(lm[0]), int(lm[1])), 2, (0, 0, 255), -1)
            cv2.circle(img, (int(lm[2]), int(lm[3])), 2, (0, 0, 255), -1)
            cv2.circle(img, (int(lm[4]), int(lm[5])), 2, (0, 0, 255), -1)
            cv2.circle(img, (int(lm[6]), int(lm[7])), 2, (0, 0, 255), -1)
            cv2.circle(img, (int(lm[8]), int(lm[9])), 2, (0, 0, 255), -1)
        cv2.imshow('out',img)
        # Press Q on keyboard to stop recording
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    cap.release()
    rknn.release()

if __name__ == "__main__":
    main()

三.運行效果

 

對比原始模型,檢測效果差點,后續提高方法:怎加量化圖片。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM