首發極術社區
如對Arm相關技術感興趣,歡迎私信aijishu20加入技術微信群,
關于R329開發板給大家介紹了周易 AIPU 部署及仿真教程和實機運行aipu程式,大家應該都完成了在實機上跑單幀圖片預測的任務,本節教程將帶領大家進行實機上的模型實時運行,
本章節網盤資料:
鏈接:https://pan.baidu.com/s/1vpPH_pHKQ_w3Z4DTxJTixg
提取碼:4tni
工程介紹
本節內容旨在實作抓取攝像頭影像,顯示在螢屏上,并實機運行模型,顯示預測結果,
對于linux上的影像處理,我們優先選用了openCV來進行處理,
簡單介紹下網盤上的檔案:
- tina_r329-evb5_uart0_0723.img 鏡像是包含了openCV的linux系統鏡像,燒錄時候可能會出錯,但是不影響系統啟動,
- zhouyi_cam.zip是本專案的工程原始碼,使用cmake構建
- zhouyi_cam 是最終構建的可執行檔案
- rootfs.tar.gz 是構建zhouyi_cam所需要的系統目錄,構建腳本會自行在該目錄尋找庫檔案
- toolchain.tar.gz 是構建所需的工具鏈
代碼介紹
zhouyi_cam 為 演示imagenet分類模型的demo工程,代碼簡單介紹如下,
0. 決議引數
- 第一個引數為需要運行的模型檔案
- 第二個引數為模型檔案最終輸出的prob是int8還是uint8的設定
- 第三個是可選引數,表示輸出的下標需要減的偏移量,默認是減一
1.攝像頭配置
MaixSense標配1280x720解析度的攝像頭,但是螢屏是240x240, 模型輸入為224x224, 所以我們需要先設定下攝像頭,
攝像頭最低可以輸出320x240的影像,我們就按此解析度輸出,
實測在該解析度下得到了被壓縮了4/3的影像,所以我們先截取180x240的影像,再拉伸回240x240給螢屏顯示,
同時注意openCV是BGR格式,需要進行BGR2RGB的轉換,
在螢屏影像的基礎上,我們再進行裁切,得到模型運算所需的224x224影像
最后還要減去各通道的偏置,需要與訓練時的處理一致,得到int8的輸入資料,
代碼如下:
int cap_img(Mat* lcd_frame, Mat* ai_frame)
{
Rect roi(40, 0, 240/4*3, 240); //16/9 -> 4/3
Rect input_roi(8, 8, 224, 224);
Size dsize = Size(240, 240);
if(!capture.read(*lcd_frame))
{
printf("no video frame\r\n");
return -1;
}
*lcd_frame = (*lcd_frame)(roi).clone();
rotate(*lcd_frame, *lcd_frame, ROTATE_180);
resize(*lcd_frame, *lcd_frame, dsize);
cvtColor(*lcd_frame, *lcd_frame, COLOR_BGR2RGB);
*ai_frame = (*lcd_frame)(input_roi).clone() + Scalar(-123, -117,-104);
return 0;
}
2. 初始化運算圖
int init_graph(char* file_model, aipu_ctx_handle_t ** ctx, aipu_graph_desc_t* gdesc, aipu_buffer_alloc_info_t* info)
{
const char* status_msg =NULL;
aipu_status_t status = AIPU_STATUS_SUCCESS;
int ret = 0;
//Step1: init ctx handle
status = AIPU_init_ctx(ctx);
if (status != AIPU_STATUS_SUCCESS) {
AIPU_get_status_msg(status, &status_msg);
printf("[DEMO ERROR] AIPU_init_ctx: %s\n", status_msg);
ret = -1;
//goto out;
}
//Step2: load graph
status = AIPU_load_graph_helper(*ctx, file_model, gdesc);
if (status != AIPU_STATUS_SUCCESS) {
AIPU_get_status_msg(status, &status_msg);
printf("[DEMO ERROR] AIPU_load_graph_helper: %s\n", status_msg);
ret = -2;
//goto deinit_ctx;
}
printf("[DEMO INFO] AIPU load graph successfully.\n");
//Step3: alloc tensor buffers
status = AIPU_alloc_tensor_buffers(*ctx, gdesc, info);
if (status != AIPU_STATUS_SUCCESS) {
AIPU_get_status_msg(status, &status_msg);
printf("[DEMO ERROR] AIPU_alloc_tensor_buffers: %s\n", status_msg);
ret = -3;
//goto unload_graph;
}
return ret;
}
3. 逐幀計算并顯示
while(!exit_flag)
{
//1. cap cam img
if(cap_img(&lcd_frame, &ai_frame) != 0) {
break;
}
//2. infer cam img, get label
gettimeofday(&start, NULL);
ret = infer_img(&ai_frame, &ctx, &gdesc, &info, signed_flag, &label_idx, &label_prob);
if(ret != 0) goto free_tensor_buffers;
gettimeofday(&end, NULL);
//3. draw lcd
putText(lcd_frame, labels[label_idx-label_oft], Point(0, 224), cv::FONT_HERSHEY_PLAIN, 1, Scalar(255,0,0), 2);
float fps = cal_fps(start, end);
char fps_str[16];
sprintf(fps_str, "%.1ffps", fps);
putText(lcd_frame, fps_str, Point(0, 16), cv::FONT_HERSHEY_PLAIN, 1, Scalar(255,0,0), 2);
fb_display(lcd_frame.data, 0, 240, 240, 0, 0, 0, 0);
}
4.退出清理
注意代碼里實作了 SIGINT 的處理,因為當前使用的驅動的清理功能有待完善,如果直接強行退出程式,會導致下次運行時可能出錯,
所以我們檢測 SIGINT 信號,檢測到 CTRL-C后,退出主回圈,執行相關的aipu清理操作,
運行效果
如下圖所示,以運行mobilenet_v2 1.0為例,可見幀率可達20fps以上,

本系列教程由矽速科技撰寫提供,
相關閱讀:
-
R329開發板系列教程之二|實機運行aipu程式
-
R329教程一|周易 AIPU 部署及仿真教程
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/293042.html
標籤:其他
