Files
yolov5-inferrence/rknn.cpp
T

246 lines
7.4 KiB
C++

#include "rknn.h"
#include <stdio.h>
#include <stdlib.h>
#include "rknn_api.h"
#include <string.h>
#include <pthread.h>
#include <vector>
#include <set>
#include <math.h>
#include <sys/time.h>
#include "MppDecode.h"
#include "cJSON.h"
#include "pose_body.h"
#include "yolov5.h"
#include "common.h"
#include "postprocess.h"
#include "vertix.h"
void *upload_info(void *arg);
// #define LABEL_NALE_TXT_PATH "./model/coco_80_labels_list.txt"
static int pre_change_frames[OBJ_CLASS_MAX] = {0};
// static int last_objects[OBJ_NUMB_MAX_SIZE] = {0};
static int pre_change_objects[OBJ_CLASS_MAX] = {0};
static int size_of_last_objects = 0;
static int size_of_pre_changed = 0;
char *CameraID = NULL;
int TypeID = 0;
int UploadPort = 0;
static char is_uploading = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// rknn_t *rk = NULL;
char *global_model = NULL;
float conf_threshold;
const float nms_threshold = 0.4;
static int init = -1;
#ifdef DUMP_FIRST_FRAME
#include "rga.h"
volatile char save_flag = 1;
#endif
int process_a_frame(char *buf, int sw, int sh)
{
// pthread_mutex_lock(&frame_mutex);
// int ret = pose_body(buf, sw, sh, 0);
struct timeval tpend1, tpend2;
long usec1 = 0;
gettimeofday(&tpend1, NULL);
int ret;
if (pthread_mutex_trylock(&mutex) == 0)
{
image_buffer_t src_img = {0};
src_img.format = IMAGE_FORMAT_RGB888;
src_img.height = sh;
src_img.width = sw;
src_img.height_stride = 0;
src_img.width_stride = 0;
src_img.virt_addr = (unsigned char *)buf;
src_img.size = sw * sh * 3;
object_detect_result_list od_results;
memset(&od_results, 0, sizeof(object_detect_result_list));
ret = inference_yolov5_model(&rknn_app_ctx, &src_img, &od_results);
if (rknn_app_ctx.callback != NULL) {
rknn_app_ctx.callback(&rknn_app_ctx, &od_results, (unsigned char*)buf);
} else {
free(buf);
}
// printf("detect result: %d, %s\n", od_results.count, coco_cls_to_name(0));
/*
for (int i = 0; i < od_results.count; i++) {
object_detect_result *det_result = &(od_results.results[i]);
printf("(%d)[%s] @ (%d %d %d %d) %.3f\n", det_result->cls_id, coco_cls_to_name(det_result->cls_id),
det_result->box.left, det_result->box.top,
det_result->box.right, det_result->box.bottom,
det_result->prop);
}
*/
pthread_mutex_unlock(&mutex);
}
else
{
ret = -1;
free(buf);
printf("skipped judge\n");
}
// free(buf);
gettimeofday(&tpend2, NULL);
usec1 = 1000 * (tpend2.tv_sec - tpend1.tv_sec) + (tpend2.tv_usec - tpend1.tv_usec) / 1000;
printf("rknn cost_time=%ld ms\n", usec1);
pthread_mutex_unlock(&frame_mutex);
return ret;
}
int print_object_detect_result(rknn_app_context_t *rknn, object_detect_result_list *group, unsigned char *buff)
{
int need_upload_info[OBJ_CLASS_MAX] = {-1};
int current_objects[OBJ_CLASS_MAX] = {0};
char need_upload = 0;
for (int i = 0; i < group->count; i++)
{
if (group->results[i].cls_id >= OBJ_CLASS_REAL_NUM)
{
printf("skip clsid > OBJ_CLASS_NUM: %d\n", group->results[i].cls_id);
continue;
}
char *label = labels[group->results[i].cls_id];
if (group->results[i].prop < conf_threshold) {
printf("skip prop = %f for class %s\n", group->results[i].prop, label);
continue;
}
int left = group->results[i].box.left;
int top = group->results[i].box.top;
int right = group->results[i].box.right;
int bottom = group->results[i].box.bottom;
if (is_point_in_workspace(left, top, right, bottom))
{
printf("in ");
current_objects[group->results[i].cls_id] += 1;
}
else
{
printf("not in ");
}
// char *label = labels[group->results[i].cls_id];
printf("result %2d: (%3d %3d %3d %3d) %f, %s\n", i, group->results[i].box.left, group->results[i].box.top,
group->results[i].box.right, group->results[i].box.bottom, group->results[i].prop, label);
// current_objects[group->results[i].cls_id] += 1;
}
for (int i = 0; i < OBJ_CLASS_REAL_NUM; i++)
{
if (current_objects[i] != pre_change_objects[i])
{
pre_change_frames[i] = 1;
pre_change_objects[i] = current_objects[i];
}
// 个数相同, 并且在数帧数
else if (pre_change_frames[i] != 0)
{
pre_change_frames[i] += 1;
if (pre_change_frames[i] >= 3)
{
need_upload = 1;
pre_change_frames[i] = 0;
// last_objects[i] = pre_change_objects[i];
need_upload_info[i] = pre_change_objects[i];
// change to current, need upload
}
}
}
if (need_upload && is_uploading == 0)
{
int *need_upload_copy = (int *)malloc(sizeof(int) * OBJ_CLASS_REAL_NUM);
for (int i = 0; i < OBJ_CLASS_REAL_NUM; i++)
{
need_upload_copy[i] = need_upload_info[i];
}
pthread_t uploadth;
pthread_create(&uploadth, NULL, upload_info, (void *)need_upload_copy);
pthread_detach(uploadth);
}
free(buff);
}
void *upload_info(void *arg)
{
int *need_upload_info = (int *)arg;
if (is_uploading != 0)
{
free(need_upload_info);
return NULL;
}
is_uploading = 1;
char need_uploading = 0;
cJSON *array = cJSON_CreateArray();
for (int i = 0; i < OBJ_CLASS_REAL_NUM; i++)
{
if ((need_upload_info[i] != -1) && codes[i] != 0)
{
need_uploading = 1;
int total_number = need_upload_info[i];
for (int j = i+1; j < OBJ_CLASS_REAL_NUM; j++) {
if (codes[i] == codes[j]) {
printf("merge %s(No: %d) to %s", labels[j], need_upload_info[j], labels[i]);
total_number += need_upload_info[j];
need_upload_info[j] = 0;
}
}
printf("xxxxxxx class idx = %d\n", codes[i]);
cJSON *obj = cJSON_CreateObject();
// 事件编码,外部事件编码
cJSON_AddNumberToObject(obj, "class_idx", codes[i]);
cJSON_AddStringToObject(obj, "name", labels[i]);
cJSON_AddNumberToObject(obj, "number", total_number);
cJSON_AddItemToArray(array, obj);
// do upload
}
}
if (!need_uploading)
{
cJSON_Delete(array);
free(need_upload_info);
is_uploading = 0;
printf("no need to upload\n");
return NULL;
}
cJSON *uploadinfo = cJSON_CreateObject();
cJSON_AddStringToObject(uploadinfo, "serial", CameraID);
// 内部事件编码,因为没法表示多个,所以,即将废弃
cJSON_AddNumberToObject(uploadinfo, "type", TypeID);
cJSON_AddNumberToObject(uploadinfo, "at", current_time_stamp());
cJSON_AddItemToObject(uploadinfo, "params", array);
time_t now;
now = time(NULL);
post_json("127.0.0.1", UploadPort, "localhost", "/video/post", uploadinfo);
cJSON_Delete(uploadinfo);
free(need_upload_info);
// int resgap = now % TIMEGAP;
// printf("sleep for %d seconds", (2 * TIMEGAP - resgap));
// sleep(2 * (TIMEGAP - resgap));
is_uploading = 0;
}