246 lines
7.4 KiB
C++
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;
|
|
} |