#include "rknn.h" #include #include #include "rknn_api.h" #include #include #include #include #include #include #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; }