ARM RK1808
上一篇关于在ARM上搭载环境的帖子莫名其妙没了,郁闷,不知道是不是因为用了友商的板子(哭),可是虚拟机真的没办法读摄像头啊……为此我双十一搞了台Deepin系统的笔记本专门测试。
DEEPIN是基于debain的,直接运行install_rknn_api.sh是会报错的,因此要用我修改过的脚本:
工程文件:
下面就分析怎么如何获取识别后的信息:
(一)rknn_test的detect_img检测过程
几乎每一层封装都有一个与检测有关的函数,而距离我们用户最近的一层,无疑就是rknn_test的detect_img函数。
detect_img函数三个传入参数:
void *ctx, cv::Mat & img, struct rknn_out_data *out_data
第一个——无名指针,实际上是rknn_test类对象的指针,由于多线程中可能并不只初始化一个对象,因此用this指针是不安全的。
第二个——img,传入图像
第三个——out_data,输出的数据
函数执行
1-把rknn_test类对象的指针付给要用的函数内的rknn_test *test_ctx
2-把out_data清空
3-调用rknn_api(一个rknn类对象)的set_input函数把img及相关参数输入
4-调用rknn_api的run函数,运行
调用rknn_api的get_outputs_data函数,获取输出数据,并将之塞入传入结构体out_data中
这里设计一个数据量的问题,这个数据量由test_ctx->num_output(test_ctx是个rknn_test类对象,如1中描述),这个num_output是在以前的一个初始化函数里面,随着in_out_num(rknn_input_output_num结构体,这个结构体里面只有两个32位uint32_t对象)被传进rknn_api(一个rknn类对象)里面。num_output就是一个32位对象,说到底,就是传输一些32位数据,后面才会对这些数据进行整理。
5-然后就没有然后了,数据都被传进out_data中,就要在show_img里面处理了
(二)rknn_test的show_img检测过程
1-把rknn_test类对象的指针付给要用的函数内的rknn_test *test_ctx
2-调用一个post_process指针函数,这个指针函数实在main函数里面调用rknn_test类对象的run函数时传进来的并初始化的,也就是说,这是个main文件里面的函数。我找了下main文件,发现了:
int post_process(void *data, cv::Mat & img, float fps,
struct rknn_out_data *out_data)
(三)post_process指针函数
结果都保存在out_data内。
通过decodeCenterSizeBoxes函数和nms函数,提取出一个predictions的浮点指针,里面保存的就是要画的框框的左下、右上点。
ssd->labels保存模型的标签,从out_data里面提取出预测标签的下标,从ssd->labels里面找它的名字来。
PS:题外话,我们看下这个结构体:
struct ssd_data {
float boxPriors[4][NUM_RESULTS];
string labels[91];
};
再看看rknn_test类里面调用post_process()的传入参数,是rknn_test类的user_data成员变量
这个结构体初始化的路径是:main(main.c)->run(rknn_test.c)->common_run(rknn_test.c)
(四)搞事情
所以,要想搞事情,就在post_process函数里面就行了,比如我们标示一下识别物体的中点,识别到之后停止程序:
1-为了识别之后停止,首先要考虑如何停止,最简单的方式就是把is_running=false。但是is_running是rknn-opencv对象的成员变量,还是私有的,它的传递情况如下:
Main->rknn_test->rknn_opencv
几乎每一个类都是局部变量,为了不产生大变动,我不得不在main里面加一个rknn_test的全局变量指针,在rknn_test里面加一个rknn_opencv的类指针,在rknn_opencv加一个可以修改is_running的执行函数,相当于一层一层地凿孔,从地表控制地下。
2-标识函数简单,不作详细说明:
- int JudgeDect(cv::Mat img, string label, int x1, int y1, int x2, int y2)
- {
- if(label.find("cup")!=string::npos || label.find("bottle")!=string::npos){
- int middle_x = (x1+x2)/2;
- int middle_y = (y1+y2)/2;
- cout << "(x,y):t(" << middle_x << "," << middle_y <<")"<
- // counter++;
- // obj.push_back(Point(x*frame.cols,y*frame.rows));
- Mat t_imgDect;
- img.copyTo(t_imgDect);
- rectangle(t_imgDect, Point(middle_x-5, middle_y-5), Point(middle_x+5, middle_y+5),
- Scalar(255, 255, 255), CV_FILLED);
- imshow("dect img", t_imgDect);
- g_rknnTest->m_rknn_opencv_interface->setIsRunning();
- }
- }
回帖(1)
2020-2-26 12:23:36
楼主这个项目什么时候可以完工啊 期待
楼主这个项目什么时候可以完工啊 期待
举报
更多回帖