RT-AK+RT-THREAD+ART-PI的人检测入侵检测摄像头
-
简介:该项目基于ART-PI+RT-THREAD平台开发了一套基于人检测AI的网络摄像头,当遥控开启时将自动检测人的特征并判断,若有人则将图片数据自动上传网络并报警。
-
硬件部分
ART-PI开发版,OV2640摄像头,红外接收头与遥控器 -
软件部分
RT-THREAD操作系统,图像处理,AI模型的C语言应用,红外遥控部分,网络传输部分下面以实现顺序教学此项目的实现(预计分三期)
一、AI部分的实现
在计划这个项目之前还没有了解到RT-AK,只知道CubeMx里的Ai模型转换,也试了一下,核心函数是模型的查找初始化等等,RT-AK进一步将这些函数集成,最后产生几个应用函数,在后面会提到。RT-AK的使用在其他文章里可以找到详细用法,这里就放几张关键步骤图带过一下
导入成功后我们进入项目里看一看,APP里会多出
项目文件会多出
下面介绍通用的应用层代码
AI部分代码逻辑为:
1.给模型分配空间
rt_ai_buffer_t *work_buffer = rt_malloc(RT_AI_你设置的模型名称(默认network)_WORK_BUFFER_BYTES+RT_AI_你设置的模型名称_IN_TOTAL_SIZE_BYTES+RT_AI_你设置的模型名称_OUT_TOTAL_SIZE_BYTES);
2.查找模型
model = rt_ai_find(RT_AI_你设置的模型名称_MODEL_NAME);
3.初始化模型
result = rt_ai_init(model, work_buffer);
4.向模型传入参数(一般是数组,我这里是50*50的数组)
rt_memcpy(model->input[0], &array_out_50X50[0][0], RT_AI_IFPERSON_IN_1_SIZE_BYTES);
5.模型运行
result = rt_ai_run(model, ai_run_complete, &ai_run_complete_flag);
6.得到输出
uint8_t *out = (uint8_t *)rt_ai_output(model, 0);
以下是我自己编写的应用层,即在上面基础的详细代码,希望之后的人可以以此为模板找到方法
#include <rt_ai_ifperson_model.h>
#include <rt_ai.h>
#include <rt_ai_log.h>
#include <math.h>
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_common.h"
void ai_run_complete(void *arg){
*(int*)arg = 1;
}
int ifperson_app(rt_uint8_t array_in_320X240[][320])
{
rt_uint8_t array_out_50X50[50][50]={0};
/*数据预处理*/
Bilinear_interpolation_algorithm(array_in_320X240,array_out_50X50);
/*end*/
rt_err_t result = RT_EOK;
uint8_t answer=0;
int ai_run_complete_flag = 0;//定义两个状态量
rt_ai_buffer_t *work_buffer = rt_malloc(RT_AI_IFPERSON_WORK_BUFFER_BYTES+RT_AI_IFPERSON_IN_TOTAL_SIZE_BYTES+RT_AI_IFPERSON_OUT_TOTAL_SIZE_BYTES);//
if(!work_buffer) {rt_kprintf("malloc err\n");return -1;}
//else rt_kprintf("malloc done\n");
model = rt_ai_find(RT_AI_IFPERSON_MODEL_NAME);
if(model == RT_AI_NULL){
return -1;
} //找到模型
result = rt_ai_init(model, work_buffer);
//rt_kprintf("ai_init done\n");
//init the model handle
if(result != 0){
return -1;
}
//prepare input data
rt_memcpy(model->input[0], &array_out_50X50[0][0], RT_AI_IFPERSON_IN_1_SIZE_BYTES);
//rt_kprintf("memcpy done\n");
result = rt_ai_run(model, ai_run_complete, &ai_run_complete_flag);
//rt_kprintf("ai_run done\n");
//process the inference data
if(ai_run_complete_flag){
//get inference data
uint8_t *out = (uint8_t *)rt_ai_output(model, 0);
answer=out[0];
//get argmax
rt_kprintf("person prediction: %d\n",answer);
if(answer>160) person=1;
else person=0;
if(person ) {
rt_pin_write(FM_PIN, PIN_LOW);
web_post_pic(array_in_320X240, 0);
}
else rt_pin_write(FM_PIN, PIN_HIGH);
}
rt_free(work_buffer);
return 0;
}
//MSH_CMD_EXPORT(ifperson_app, person detection demo);
编写完代码框架之后,你的AI模型不一定能跑起来,这是因为AI模型在这里的量级必须足够小,做到这一点,需要减少激活层,减少输入量,尽可能减少层数,然后转为U8格式输入(量化),U8输出。要想知道这些参数,就需要看转C的report文件
,最后贴一张我的模型参数作为参考(这中间为了减小模型真的可能不断试错)
主要看RAM(total) ,它反映的是运行时会占用的内存,最好不要超过100kb级别。
下一章我们继续讲图像的处理,如何让图像传输和AI模型对接起来,所有代码会在最后一章附上github地址