×¢²á µÇ¼
µç×Ó¹¤³ÌÊÀ½ç-ÂÛ̳ ·µ»ØÊ×Ò³ EEWORLDÊ×Ò³ ƵµÀ EE´óѧÌà ÏÂÔØÖÐÐÄ Datasheet רÌâ
LitchiChengµÄ¸öÈË¿Õ¼ä https://home.eeworld.com.cn/space-uid-1003127.html [ÊÕ²Ø] [¸´ÖÆ] [·ÖÏí] [RSS]
ÈÕÖ¾

#AIÌôÕ½ÓªÖÕµãÕ¾#RV1106ʹÓÃrknn½øÐÐMNIST¶àÊý×Öʵʱʶ±ð

ÒÑÓÐ 450 ´ÎÔĶÁ2024-5-31 23:58 |¸öÈË·ÖÀà:rv1106

 

Ê×Ïȸø³ö¹¤³Ì´ò°ü²Ö¿âµØÖ·£¬²Î¿¼¹ÙÍøyolov5-rtspʾÀý

git@github.com:LitchiCheng/RV1106_Linux.git

°üº¬ÄÚÈÝÈçÏ£º

1. v4l2·â×°µ÷Óÿ⹤³Ì

2. st7735 LCD²¥·Åbadapple¹¤³Ì

3. MNIST¶àÊý×Öʵʱʶ±ð¹¤³Ì

4. rkrtspÍÆÁ÷²âÊÔ¹¤³Ì

5. rkmpi csiÉãÏñÍ·²âÊÔ¹¤³Ì

6. yolov5µ¥Ö¡Ê¶±ð¹¤³Ì

 

ÈçÏÂÖ±½Ó½éÉÜMNIST¶àÊý×Öʵʱʶ±ð˼·£º

  1. ʹÓÃrkmpi¿â½øÐÐframeµÄץȡ
  2. ʹÓÃopencv-mobile¿â½øÐе¥Ö¡frame½øÐд¦Àí£¬Í¨¹ý¶þÖµ»¯¡¢·´Ïà¡¢¸¯Ê´¡¢ÅòÕ͵ȴ¦Àí£¬»ñµÃ¶à¸öÊý×ֵĿòѡλÖÃ
  3. ʹÓÃmnistѵÁ·ÇÒת»»ºóµÄrknnÄ£Ð͵¥¶À¶Ô¿òѡλÖõÄͼƬ½øÐÐÍÆÀí£¬µÃµ½¸Ã¿òѡλÖõĸÅÂÊÒÔ¼°Êý×Ö
  4. ÔÚframeÉÏͨ¹ýopencv-mobile½øÐл­¿òÒÔ¼°±ê¼ÇÊý×Ö¼°¸ÅÂÊ
  5. ʹÓÃrkrtsp½øÐÐÍÆÁ÷

ÈçÏÂΪ´úÂë¹Ø¼ü²¿·Ö

Ò»¡¢»ñÈ¡frame¡¢´¦Àí¡¢ÍÆÀí¡¢±ê¼Ç

void *data = RK_MPI_MB_Handle2VirAddr(stVpssFrame.stVFrame.pMbBlk);  
cv::Mat frame(height,width,CV_8UC3,data);           

std::vector<cv::Rect> rects;
std::vector<detect_result> detect_results;
std::vector<cv::Mat> sub_pics;
rects = find_contour(frame, sub_pics);
for(int i = 0; i < rects.size(); i++){
    if (rects[i].area() > 0){
        inference_mnist_model(&rknn_app_ctx, sub_pics[i], detect_results);
        if (!detect_results.empty()){
            detect_result result = detect_results.back();
            //ÂÌ¿ò£¬thicknessΪ1
            cv::rectangle(frame, rects[i], cv::Scalar(0, 255, 0), 1);
            //ºì×Ö£¬fontscaleΪ1£¬thicknessΪ1
            cv::putText(frame, std::to_string(result.num), cv::Point(rects[i].x, rects[i].y + 10),
                        cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 0, 0), 1);
            //À¶×Ö£¬fontscaleΪ1£¬thicknessΪ1
            cv::putText(frame, std::to_string(result.probability), cv::Point(rects[i].x+ 30, rects[i].y + 10),
                        cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(0, 0, 255), 1);
            detect_results.pop_back();
        }
    }
}

¶þ¡¢µ¥Ö¡Í¼Ïñ´¦Àí

std::vector<cv::Rect> find_contour(const cv::Mat &image, std::vector<cv::Mat>& sub_pics) {
    // Ô¤´¦ÀíͼÏñ
    cv::Mat gray, edged, org_clone;
    org_clone = image.clone();
    // ת³É»Ò¶Èͼ
    cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
    // ·´Ïà»Ò¶Èͼ
    edged = ~gray;
    cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
    // ±ßÔµÅòÕÍ
    cv::dilate(edged, edged, kernel);
    // ¸¯Ê´
    cv::erode(edged, edged, kernel);
    // ¶þÖµ»¯
    cv::threshold(edged, edged, 127, 0, cv::THRESH_TOZERO);
    // ÓÃÀ´´æÕÒµ½µÄÂÖÀª
    std::vector<std::vector<cv::Point>> contours;
    cv::findContours(edged, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
    std::vector<cv::Rect> borders;
    for(auto contour: contours){
        cv::Rect bounding_box = cv::boundingRect(contour);
        //µ±Ç°¾ØÐοò´óÓÚ30²ÅʹÓÃ
        if (cv::contourArea(contour) > 30) {
            //À©´ó¾ØÐοò£¬ÒÔ·ÀÊý×Ö±»½Ø¶Ï
            bounding_box.x = std::max(0, bounding_box.x - 10);
            bounding_box.y = std::max(0, bounding_box.y - 10);
            bounding_box.width = std::min(image.cols - bounding_box.x, bounding_box.width + 20);
            bounding_box.height = std::min(image.rows - bounding_box.y, bounding_box.height + 20);
            borders.push_back(bounding_box);
            cv::Mat postsub;
            cv::Mat sub = edged(bounding_box);
            // À©´óÊý×ÖÂÖÀª
            cv::threshold(sub, sub, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
            // // ½«Í¼Æ¬´óСµ÷ÕûΪ28
            cv::resize(sub, postsub, cv::Size(28, 28), 0, 0, cv::INTER_AREA);
            sub_pics.push_back(postsub);
        }
    }
    return borders;
}

Èý¡¢ÍÆÀíº¯Êý

static float deqnt_affine_to_f32(int8_t qnt, int32_t zp, float scale) { return ((float)qnt - (float)zp) * scale; }

int inference_mnist_model(rknn_app_context_t* app_ctx, cv::Mat &frame, std::vector<detect_result>& results)
{
    int ret;
    int width = app_ctx->input_attrs[0].dims[2];
    int stride = app_ctx->input_attrs[0].w_stride;

    if (width == stride){
        memcpy(app_ctx->input_mems[0]->virt_addr, frame.data, width * app_ctx->input_attrs[0].dims[1] * app_ctx->input_attrs[0].dims[3]);
    }else{
        int height = app_ctx->input_attrs[0].dims[1];
        int channel = app_ctx->input_attrs[0].dims[3];
        // copy from src to dst with stride
        uint8_t *src_ptr = frame.data;
        uint8_t *dst_ptr = (uint8_t *)app_ctx->input_mems[0]->virt_addr;
        // width-channel elements
        int src_wc_elems = width * channel;
        int dst_wc_elems = stride * channel;
        for (int h = 0; h < height; ++h){
            memcpy(dst_ptr, src_ptr, src_wc_elems);
            src_ptr += src_wc_elems;
            dst_ptr += dst_wc_elems;
        }
    }
   
    ret = rknn_run(app_ctx->rknn_ctx, nullptr);
    if (ret < 0) {
        printf("rknn_run fail! ret=%d\n", ret);
        return -1;
    }

    #define DETECT_NUM_SIZE 10

    // Post Process
    uint8_t  *output= (uint8_t*)malloc(sizeof(uint8_t) * DETECT_NUM_SIZE); 
    float *out_fp32 = (float*)malloc(sizeof(float) * DETECT_NUM_SIZE); 
    output = (uint8_t *)app_ctx->output_mems[0]->virt_addr;

    int32_t zp =  app_ctx->output_attrs[0].zp;
    float scale = app_ctx->output_attrs[0].scale;

    //·´Á¿»¯Îª¸¡µãÊý
    for(int i = 0; i < DETECT_NUM_SIZE; i ++)
        out_fp32[i] = deqnt_affine_to_f32(output[i],zp,scale);

    //¹éÒ»»¯
    float sum = 0;
    for(int i = 0; i < DETECT_NUM_SIZE; i++)
        sum += out_fp32[i] * out_fp32[i];

    float norm = sqrt(sum);
    for(int i = 0; i < DETECT_NUM_SIZE; i++)
        out_fp32[i] /= norm; 

    //¶Ô¸ÅÂʽøÐÐÅÅÐò
    float max_probability = -1.0;
    int detect_num = -1;
    for (int i = 0; i < DETECT_NUM_SIZE; ++i){
        if (out_fp32[i] > max_probability){
            max_probability = out_fp32[i];
            detect_num = i;
        }
    }
    //½á¹ûÈëÁÐ
    results.push_back({detect_num, max_probability});
    return 0;
}

¹¤³Ì±àÒë

cd MNIST
mkdri build
cd build
cmake ..
make
make install
scp -r ../rtsp_mnist_test root@xxx.xxx.xxx.xxx:~

 

Ä¿±ê°åÔËÐÐ

killall rkipc
cd rtsp_mnist_test
./rtsp_mnist model/mnist.rknn

 VLCÀ­Á÷ʵʱÏÔʾ

   

 

 

ÊÓƵµØÖ·

±¾ÎÄÀ´×ÔÂÛ̳£¬µã»÷²é¿´ÍêÕûÌû×ÓÄÚÈÝ¡£

ÆÀÂÛ (0 ¸öÆÀÂÛ)

facelist doodle Í¿Ñ»°å

ÄúÐèÒªµÇ¼ºó²Å¿ÉÒÔÆÀÂÛ µÇ¼ | ×¢²á

ÈÈÃÅÎÄÕÂ