上传文件至 /
parent
4317aa00da
commit
f1a813048e
|
@ -0,0 +1,186 @@
|
||||||
|
// Copyright (c) 2021 by Rockchip Electronics Co., Ltd. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "drm_func.h"
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
int drm_init(drm_context *drm_ctx)
|
||||||
|
{
|
||||||
|
static const char *card = "/dev/dri/card0";
|
||||||
|
int flag = O_RDWR;
|
||||||
|
int drm_fd = -1;
|
||||||
|
|
||||||
|
drm_fd = open(card, flag);
|
||||||
|
if (drm_fd < 0)
|
||||||
|
{
|
||||||
|
printf("failed to open %s\n", card);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
drm_ctx->drm_handle = dlopen("libdrm.so", RTLD_LAZY);
|
||||||
|
|
||||||
|
if (!drm_ctx->drm_handle)
|
||||||
|
{
|
||||||
|
printf("failed to dlopen libdrm.so\n");
|
||||||
|
printf("dlopen error: %s\n", dlerror());
|
||||||
|
drm_deinit(drm_ctx, drm_fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
drm_ctx->io_func = (FUNC_DRM_IOCTL)dlsym(drm_ctx->drm_handle, "drmIoctl");
|
||||||
|
if (drm_ctx->io_func == NULL)
|
||||||
|
{
|
||||||
|
dlclose(drm_ctx->drm_handle);
|
||||||
|
drm_ctx->drm_handle = NULL;
|
||||||
|
drm_deinit(drm_ctx, drm_fd);
|
||||||
|
printf("failed to dlsym drmIoctl\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return drm_fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drm_deinit(drm_context *drm_ctx, int drm_fd)
|
||||||
|
{
|
||||||
|
if (drm_ctx->drm_handle)
|
||||||
|
{
|
||||||
|
dlclose(drm_ctx->drm_handle);
|
||||||
|
drm_ctx->drm_handle = NULL;
|
||||||
|
}
|
||||||
|
if (drm_fd > 0)
|
||||||
|
{
|
||||||
|
close(drm_fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void *drm_buf_alloc(drm_context *drm_ctx, int drm_fd, int TexWidth, int TexHeight, int bpp, int *fd, unsigned int *handle, size_t *actual_size)
|
||||||
|
{
|
||||||
|
// printf("0: Width %d, Heigh %d, bpp %d\n", TexWidth, TexHeight, bpp);
|
||||||
|
// printf("fd: %d, handle: %d, size: %d\n", fd, handle, actual_size);
|
||||||
|
int ret;
|
||||||
|
if (drm_ctx == NULL)
|
||||||
|
{
|
||||||
|
printf("drm context is unvalid\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
char *map = NULL;
|
||||||
|
|
||||||
|
// printf("Width %d, Heigh %d\n", TexWidth, TexHeight);
|
||||||
|
|
||||||
|
void *vir_addr = NULL;
|
||||||
|
struct drm_prime_handle fd_args;
|
||||||
|
struct drm_mode_map_dumb mmap_arg;
|
||||||
|
struct drm_mode_destroy_dumb destory_arg;
|
||||||
|
|
||||||
|
struct drm_mode_create_dumb alloc_arg;
|
||||||
|
|
||||||
|
memset(&alloc_arg, 0, sizeof(alloc_arg));
|
||||||
|
alloc_arg.bpp = bpp;
|
||||||
|
alloc_arg.width = TexWidth;
|
||||||
|
alloc_arg.height = TexHeight;
|
||||||
|
// alloc_arg.flags = ROCKCHIP_BO_CONTIG;
|
||||||
|
|
||||||
|
// printf("2: Width %d, Heigh %d\n", TexWidth, TexHeight);
|
||||||
|
|
||||||
|
//获取handle和size
|
||||||
|
ret = drm_ctx->io_func(drm_fd, DRM_IOCTL_MODE_CREATE_DUMB, &alloc_arg);
|
||||||
|
// printf("3: Width %d, Heigh %d\n", TexWidth, TexHeight);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
printf("failed to create dumb buffer: %s\n", strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// printf("4: Width %d, Heigh %d\n", TexWidth, TexHeight);
|
||||||
|
if (handle != NULL)
|
||||||
|
{
|
||||||
|
*handle = alloc_arg.handle;
|
||||||
|
}
|
||||||
|
// printf("5: Width %d, Heigh %d\n", TexWidth, TexHeight);
|
||||||
|
if (actual_size != NULL)
|
||||||
|
{
|
||||||
|
*actual_size = alloc_arg.size;
|
||||||
|
}
|
||||||
|
// printf("create width=%u, height=%u, bpp=%u, size=%lu dumb buffer\n",alloc_arg.width,alloc_arg.height,alloc_arg.bpp,alloc_arg.size);
|
||||||
|
// printf("out handle= %d\n",alloc_arg.handle);
|
||||||
|
|
||||||
|
//获取fd
|
||||||
|
memset(&fd_args, 0, sizeof(fd_args));
|
||||||
|
fd_args.fd = -1;
|
||||||
|
fd_args.handle = alloc_arg.handle;
|
||||||
|
;
|
||||||
|
fd_args.flags = 0;
|
||||||
|
ret = drm_ctx->io_func(drm_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &fd_args);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
printf("rk-debug handle_to_fd failed ret=%d,err=%s, handle=%x \n", ret, strerror(errno), fd_args.handle);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
// printf("out fd = %d, drm fd: %d\n",fd_args.fd,drm_fd);
|
||||||
|
if (fd != NULL)
|
||||||
|
{
|
||||||
|
*fd = fd_args.fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取虚拟地址
|
||||||
|
memset(&mmap_arg, 0, sizeof(mmap_arg));
|
||||||
|
mmap_arg.handle = alloc_arg.handle;
|
||||||
|
|
||||||
|
ret = drm_ctx->io_func(drm_fd, DRM_IOCTL_MODE_MAP_DUMB, &mmap_arg);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
printf("failed to create map dumb: %s\n", strerror(errno));
|
||||||
|
vir_addr = NULL;
|
||||||
|
goto destory_dumb;
|
||||||
|
}
|
||||||
|
vir_addr = map = mmap(0, alloc_arg.size, PROT_READ | PROT_WRITE, MAP_SHARED, drm_fd, mmap_arg.offset);
|
||||||
|
if (map == MAP_FAILED)
|
||||||
|
{
|
||||||
|
printf("failed to mmap buffer: %s\n", strerror(errno));
|
||||||
|
vir_addr = NULL;
|
||||||
|
goto destory_dumb;
|
||||||
|
}
|
||||||
|
// printf("alloc map=%x \n",map);
|
||||||
|
return vir_addr;
|
||||||
|
destory_dumb:
|
||||||
|
memset(&destory_arg, 0, sizeof(destory_arg));
|
||||||
|
destory_arg.handle = alloc_arg.handle;
|
||||||
|
ret = drm_ctx->io_func(drm_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destory_arg);
|
||||||
|
if (ret)
|
||||||
|
printf("failed to destory dumb %d\n", ret);
|
||||||
|
return vir_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int drm_buf_destroy(drm_context *drm_ctx, int drm_fd, int buf_fd, int handle, void *drm_buf, size_t size)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
if (drm_buf == NULL)
|
||||||
|
{
|
||||||
|
printf("drm buffer is NULL\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
munmap(drm_buf, size);
|
||||||
|
|
||||||
|
struct drm_mode_destroy_dumb destory_arg;
|
||||||
|
memset(&destory_arg, 0, sizeof(destory_arg));
|
||||||
|
destory_arg.handle = handle;
|
||||||
|
ret = drm_ctx->io_func(drm_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destory_arg);
|
||||||
|
if (ret)
|
||||||
|
printf("failed to destory dumb %d, error=%s\n", ret, strerror(errno));
|
||||||
|
if (buf_fd > 0)
|
||||||
|
{
|
||||||
|
close(buf_fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
#ifndef _ATK_YOLOV5_OBJECT_RECOGNIZE_H
|
||||||
|
#define _ATK_YOLOV5_OBJECT_RECOGNIZE_H
|
||||||
|
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
|
#define _BASETSD_H
|
||||||
|
|
||||||
|
#include "im2d.h"
|
||||||
|
#include "rga.h"
|
||||||
|
#include "drm_func.h"
|
||||||
|
#include "rga_func.h"
|
||||||
|
#include "rknn_api.h"
|
||||||
|
#include "rkmedia_api.h"
|
||||||
|
#include "rkmedia_venc.h"
|
||||||
|
#include "sample_common.h"
|
||||||
|
#include "opencv2/opencv.hpp"
|
||||||
|
|
||||||
|
#include "librtsp/rtsp_demo.h"
|
||||||
|
#include "rk_aiq_user_api_sysctl.h"
|
||||||
|
#include "rk_aiq_user_api_afec.h"
|
||||||
|
// #include "rk_aiq_uapi_afec_int.h"
|
||||||
|
|
||||||
|
#include <opencv2/core.hpp>
|
||||||
|
#include <opencv2/imgproc.hpp>
|
||||||
|
#include "opencv2/imgcodecs.hpp"
|
||||||
|
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
RK_U32 video_width = 1920;
|
||||||
|
RK_U32 video_height = 1072;
|
||||||
|
// RK_U32 video_height = 720;
|
||||||
|
int disp_width = 720;
|
||||||
|
int disp_height = 1280;
|
||||||
|
|
||||||
|
static bool quit = false;
|
||||||
|
rtsp_demo_handle g_rtsplive = NULL;
|
||||||
|
static rtsp_session_handle g_rtsp_session;
|
||||||
|
|
||||||
|
int rgb24_resize(unsigned char *input_rgb, unsigned char *output_rgb, int width,int height, int outwidth, int outheight);
|
||||||
|
|
||||||
|
static unsigned char *load_model(const char *filename, int *model_size);
|
||||||
|
|
||||||
|
static void printRKNNTensor(rknn_tensor_attr *attr);
|
||||||
|
|
||||||
|
void *rkmedia_rknn_thread(void *args);
|
||||||
|
void *venc_rtsp_tidp(void *args);
|
||||||
|
void *upload_message(void *args); //上传检测信息与截取的图片
|
||||||
|
void *upload_message_controller(void *args);
|
||||||
|
void *heart_beat(void *args); //上传心跳检测
|
||||||
|
void *distortion(void *args); //矫正
|
||||||
|
void *read_serial_thread(void *args); //读取串口传来的红外温度数据
|
||||||
|
|
||||||
|
struct Alarm {
|
||||||
|
int ifalarm;
|
||||||
|
int ifwarn;
|
||||||
|
std::string alarmMsg;
|
||||||
|
std::string alarmType;
|
||||||
|
std::string alarmBase64;
|
||||||
|
std::string alarmCoverage;
|
||||||
|
float alarmprop;
|
||||||
|
};
|
||||||
|
|
||||||
|
void initializeAlarm(Alarm* Alarm) {
|
||||||
|
// 初始化结构体成员
|
||||||
|
Alarm->ifalarm = 0;
|
||||||
|
Alarm->ifwarn = 0;
|
||||||
|
Alarm->alarmMsg = "无";
|
||||||
|
Alarm->alarmType = "无";
|
||||||
|
Alarm->alarmBase64 = "无";
|
||||||
|
Alarm->alarmCoverage = "无";
|
||||||
|
Alarm->alarmprop = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NV12ToRGB(int width, int height, unsigned char* nv12, Mat& rgb) {
|
||||||
|
// Step 1: Create a cv::Mat object for NV12 data
|
||||||
|
Mat nv12Mat(height + height / 2, width, CV_8UC1, nv12);
|
||||||
|
|
||||||
|
// Step 2: Convert NV12 to RGB
|
||||||
|
cvtColor(nv12Mat, rgb, COLOR_YUV2RGB_NV12);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,129 @@
|
||||||
|
// Copyright (c) 2021 by Rockchip Electronics Co., Ltd. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "rga_func.h"
|
||||||
|
|
||||||
|
int RGA_init(rga_context *rga_ctx)
|
||||||
|
{
|
||||||
|
rga_ctx->rga_handle = dlopen("librga.so", RTLD_LAZY);
|
||||||
|
if (!rga_ctx->rga_handle)
|
||||||
|
{
|
||||||
|
printf("dlopen librga.so failed\n");
|
||||||
|
printf("dlopen error: %s\n", dlerror());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
rga_ctx->init_func = (FUNC_RGA_INIT)dlsym(rga_ctx->rga_handle, "c_RkRgaInit");
|
||||||
|
rga_ctx->deinit_func = (FUNC_RGA_DEINIT)dlsym(rga_ctx->rga_handle, "c_RkRgaDeInit");
|
||||||
|
rga_ctx->blit_func = (FUNC_RGA_BLIT)dlsym(rga_ctx->rga_handle, "c_RkRgaBlit");
|
||||||
|
rga_ctx->init_func();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void img_resize_fast(rga_context *rga_ctx, int src_fd, int src_w, int src_h, uint64_t dst_phys, int dst_w, int dst_h)
|
||||||
|
{
|
||||||
|
// printf("rga use fd, src(%dx%d) -> dst(%dx%d)\n", src_w, src_h, dst_w, dst_h);
|
||||||
|
|
||||||
|
if (rga_ctx->rga_handle)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
rga_info_t src, dst;
|
||||||
|
|
||||||
|
memset(&src, 0, sizeof(rga_info_t));
|
||||||
|
src.fd = src_fd;
|
||||||
|
src.mmuFlag = 1;
|
||||||
|
// src.virAddr = (void *)psrc;
|
||||||
|
|
||||||
|
memset(&dst, 0, sizeof(rga_info_t));
|
||||||
|
dst.fd = -1;
|
||||||
|
dst.mmuFlag = 0;
|
||||||
|
|
||||||
|
#if defined(__arm__)
|
||||||
|
dst.phyAddr = (void *)((uint32_t)dst_phys);
|
||||||
|
#else
|
||||||
|
dst.phyAddr = (void *)dst_phys;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dst.nn.nn_flag = 0;
|
||||||
|
|
||||||
|
rga_set_rect(&src.rect, 0, 0, src_w, src_h, src_w, src_h, RK_FORMAT_RGB_888);
|
||||||
|
rga_set_rect(&dst.rect, 0, 0, dst_w, dst_h, dst_w, dst_h, RK_FORMAT_RGB_888);
|
||||||
|
|
||||||
|
ret = rga_ctx->blit_func(&src, &dst, NULL);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
printf("c_RkRgaBlit error : %s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void img_resize_slow(rga_context *rga_ctx, void *src_virt, int src_w, int src_h, void *dst_virt, int dst_w, int dst_h,
|
||||||
|
int w_offset, int h_offset, RgaSURF_FORMAT color, bool add_extra_sz_w, bool add_extra_sz_h)
|
||||||
|
{
|
||||||
|
// printf("rga use virtual, src(%dx%d) -> dst(%dx%d)\n", src_w, src_h, dst_w, dst_h);
|
||||||
|
if (rga_ctx->rga_handle)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
rga_info_t src, dst;
|
||||||
|
|
||||||
|
memset(&src, 0, sizeof(rga_info_t));
|
||||||
|
src.fd = -1;
|
||||||
|
src.mmuFlag = 1;
|
||||||
|
src.virAddr = (void *)src_virt;
|
||||||
|
|
||||||
|
memset(&dst, 0, sizeof(rga_info_t));
|
||||||
|
dst.fd = -1;
|
||||||
|
dst.mmuFlag = 1;
|
||||||
|
dst.virAddr = dst_virt;
|
||||||
|
|
||||||
|
dst.nn.nn_flag = 0;
|
||||||
|
// printf("input to rga para, w_offset: %d, h_offset: %d, dst_w: %d, dst_h: %d\n",
|
||||||
|
// w_offset, h_offset, dst_w, dst_h);
|
||||||
|
|
||||||
|
rga_set_rect(&src.rect, 0, 0, src_w, src_h, src_w, src_h, RK_FORMAT_RGB_888);
|
||||||
|
int src_w = dst_w + 2*w_offset;
|
||||||
|
int src_h = dst_h + 2*h_offset;
|
||||||
|
if (add_extra_sz_w){
|
||||||
|
src_w += 1;
|
||||||
|
// printf("Adding extra sz w: %d\n", src_w);
|
||||||
|
}
|
||||||
|
else if (add_extra_sz_h){
|
||||||
|
src_h += 1;
|
||||||
|
// printf("Adding extra sz h: %d\n", src_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
//rga_set_rect(&dst.rect, w_offset, h_offset, dst_w, dst_h, src_w, dst_h + 2*h_offset, color);
|
||||||
|
rga_set_rect(&dst.rect, w_offset, h_offset, dst_w, dst_h, src_w, src_h, color);
|
||||||
|
|
||||||
|
ret = rga_ctx->blit_func(&src, &dst, NULL);
|
||||||
|
if (ret){
|
||||||
|
printf("c_RkRgaBlit error : %s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int RGA_deinit(rga_context *rga_ctx)
|
||||||
|
{
|
||||||
|
if(rga_ctx->rga_handle)
|
||||||
|
{
|
||||||
|
dlclose(rga_ctx->rga_handle);
|
||||||
|
rga_ctx->rga_handle = NULL;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,374 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <opencv2/opencv.hpp>
|
||||||
|
#include "yolov5_detect.h"
|
||||||
|
#include "rknn_api.h"
|
||||||
|
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace cv;
|
||||||
|
|
||||||
|
|
||||||
|
//unsigned char *model;
|
||||||
|
//detection* dets;
|
||||||
|
|
||||||
|
static void printRKNNTensor(rknn_tensor_attr *attr)
|
||||||
|
{
|
||||||
|
printf("index=%d name=%s n_dims=%d dims=[%d %d %d %d] n_elems=%d size=%d "
|
||||||
|
"fmt=%d type=%d qnt_type=%d fl=%d zp=%d scale=%f\n",
|
||||||
|
attr->index, attr->name, attr->n_dims, attr->dims[3], attr->dims[2],
|
||||||
|
attr->dims[1], attr->dims[0], attr->n_elems, attr->size, 0, attr->type,
|
||||||
|
attr->qnt_type, attr->fl, attr->zp, attr->scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int letter_box(cv::Mat input_image, cv::Mat *output_image, int model_input_size)
|
||||||
|
{
|
||||||
|
int input_width, input_height;
|
||||||
|
|
||||||
|
input_width = input_image.cols;
|
||||||
|
input_height = input_image.rows;
|
||||||
|
float ratio;
|
||||||
|
ratio = min((float)model_input_size / input_width, (float)model_input_size / input_height);
|
||||||
|
|
||||||
|
int new_width, new_height;
|
||||||
|
new_width = round(ratio * input_width );
|
||||||
|
new_height = round(ratio * input_height);
|
||||||
|
|
||||||
|
|
||||||
|
int height_padding = 0;
|
||||||
|
int width_padding = 0;
|
||||||
|
int top = 0;
|
||||||
|
int bottom = 0;
|
||||||
|
int left = 0;
|
||||||
|
int right = 0;
|
||||||
|
if( new_width >= new_height)
|
||||||
|
{
|
||||||
|
height_padding = new_width - new_height;
|
||||||
|
if( (height_padding % 2) == 0 )
|
||||||
|
{
|
||||||
|
top = (int)((float)(height_padding/2));
|
||||||
|
bottom = (int)((float)(height_padding/2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
top = (int)((float)(height_padding/2));
|
||||||
|
bottom = (int)((float)(height_padding/2))+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
width_padding = new_height - new_width;
|
||||||
|
if( (width_padding % 2) == 0 )
|
||||||
|
{
|
||||||
|
left = (int)((float)(width_padding/2));
|
||||||
|
right = (int)((float)(width_padding/2));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
left = (int)((float)(width_padding/2));
|
||||||
|
right = (int)((float)(width_padding/2))+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Mat resize_img;
|
||||||
|
|
||||||
|
cv::resize(input_image, resize_img, cv::Size(new_width, new_height));
|
||||||
|
cv::copyMakeBorder(resize_img, *output_image, top, bottom, left, right, cv::BORDER_CONSTANT, cv::Scalar(0, 0, 0));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int yolov5_detect_init(rknn_context *ctx, const char * path)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
// Load model
|
||||||
|
FILE *fp = fopen(path, "rb");
|
||||||
|
if(fp == NULL)
|
||||||
|
{
|
||||||
|
printf("fopen %s fail!\n", path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fseek(fp, 0, SEEK_END); //fp指向end,fseek(FILE *stream, long offset, int fromwhere);
|
||||||
|
int model_len = ftell(fp); //相对文件首偏移
|
||||||
|
unsigned char *model_data = (unsigned char*)malloc(model_len);
|
||||||
|
|
||||||
|
fseek(fp, 0, SEEK_SET); //SEEK_SET为文件头
|
||||||
|
if(model_len != fread(model_data, 1, model_len, fp))
|
||||||
|
{
|
||||||
|
printf("fread %s fail!\n", path);
|
||||||
|
free(model_data);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
//init
|
||||||
|
ret = rknn_init(ctx, model_data, model_len, RKNN_FLAG_PRIOR_MEDIUM);
|
||||||
|
if(ret < 0)
|
||||||
|
{
|
||||||
|
printf("rknn_init fail! ret=%d\n", ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(model_data);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int scale_coords(yolov5_detect_result_group_t *detect_result_group, int img_width, int img_height, int model_size)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < detect_result_group->count; i++)
|
||||||
|
{
|
||||||
|
yolov5_detect_result_t *det_result = &(detect_result_group->results[i]);
|
||||||
|
|
||||||
|
|
||||||
|
int x1 = det_result->box.left;
|
||||||
|
int y1 = det_result->box.top;
|
||||||
|
int x2 = det_result->box.right;
|
||||||
|
int y2 = det_result->box.bottom;
|
||||||
|
|
||||||
|
|
||||||
|
if( img_width >= img_height )
|
||||||
|
{
|
||||||
|
int image_max_len = img_width;
|
||||||
|
float gain;
|
||||||
|
gain = (float)model_size / image_max_len;
|
||||||
|
int resized_height = img_height * gain;
|
||||||
|
int height_pading = (model_size - resized_height)/2;
|
||||||
|
y1 = (y1 - height_pading);
|
||||||
|
y2 = (y2 - height_pading);
|
||||||
|
x1 = int(x1 / gain);
|
||||||
|
y1 = int(y1 / gain);
|
||||||
|
x2 = int(x2 / gain);
|
||||||
|
y2 = int(y2 / gain);
|
||||||
|
|
||||||
|
det_result->box.left = x1;
|
||||||
|
det_result->box.top = y1;
|
||||||
|
det_result->box.right = x2;
|
||||||
|
det_result->box.bottom = y2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int image_max_len = img_height;
|
||||||
|
float gain;
|
||||||
|
gain = (float)model_size / image_max_len;
|
||||||
|
int resized_width = img_width * gain;
|
||||||
|
int width_pading = (model_size - resized_width)/2;
|
||||||
|
x1 = (x1 - width_pading);
|
||||||
|
x2 = (x2 - width_pading);
|
||||||
|
x1 = int(x1 / gain);
|
||||||
|
y1 = int(y1 / gain);
|
||||||
|
x2 = int(x2 / gain);
|
||||||
|
y2 = int(y2 / gain);
|
||||||
|
|
||||||
|
det_result->box.left = x1;
|
||||||
|
det_result->box.top = y1;
|
||||||
|
det_result->box.right = x2;
|
||||||
|
det_result->box.bottom = y2;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int yolov5_detect_run(rknn_context ctx, cv::Mat input_image, yolov5_detect_result_group_t *detect_result_group)
|
||||||
|
{
|
||||||
|
int img_width = 0;
|
||||||
|
int img_height = 0;
|
||||||
|
int img_channel = 0;
|
||||||
|
|
||||||
|
size_t actual_size = 0;
|
||||||
|
const float vis_threshold = 0.1;
|
||||||
|
const float nms_threshold = 0.5;
|
||||||
|
const float conf_threshold = 0.2;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
img_width = input_image.cols;
|
||||||
|
img_height = input_image.rows;
|
||||||
|
|
||||||
|
rknn_sdk_version version;
|
||||||
|
ret = rknn_query(ctx, RKNN_QUERY_SDK_VERSION, &version,
|
||||||
|
sizeof(rknn_sdk_version));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
printf("rknn_init error ret=%d\n", ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
printf("sdk version: %s driver version: %s\n", version.api_version,
|
||||||
|
version.drv_version);
|
||||||
|
*/
|
||||||
|
|
||||||
|
rknn_input_output_num io_num;
|
||||||
|
ret = rknn_query(ctx, RKNN_QUERY_IN_OUT_NUM, &io_num, sizeof(io_num));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
printf("rknn_init error ret=%d\n", ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
printf("model input num: %d, output num: %d\n", io_num.n_input,
|
||||||
|
io_num.n_output);
|
||||||
|
*/
|
||||||
|
|
||||||
|
rknn_tensor_attr input_attrs[io_num.n_input];
|
||||||
|
memset(input_attrs, 0, sizeof(input_attrs));
|
||||||
|
for (int i = 0; i < io_num.n_input; i++)
|
||||||
|
{
|
||||||
|
input_attrs[i].index = i;
|
||||||
|
ret = rknn_query(ctx, RKNN_QUERY_INPUT_ATTR, &(input_attrs[i]),
|
||||||
|
sizeof(rknn_tensor_attr));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
printf("rknn_init error ret=%d\n", ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//printRKNNTensor(&(input_attrs[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
rknn_tensor_attr output_attrs[io_num.n_output];
|
||||||
|
memset(output_attrs, 0, sizeof(output_attrs));
|
||||||
|
for (int i = 0; i < io_num.n_output; i++)
|
||||||
|
{
|
||||||
|
output_attrs[i].index = i;
|
||||||
|
ret = rknn_query(ctx, RKNN_QUERY_OUTPUT_ATTR, &(output_attrs[i]),
|
||||||
|
sizeof(rknn_tensor_attr));
|
||||||
|
//printRKNNTensor(&(output_attrs[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
int input_channel = 3;
|
||||||
|
int input_width = 0;
|
||||||
|
int input_height = 0;
|
||||||
|
if (input_attrs[0].fmt == RKNN_TENSOR_NCHW)
|
||||||
|
{
|
||||||
|
//printf("model is NCHW input fmt\n");
|
||||||
|
input_width = input_attrs[0].dims[0];
|
||||||
|
input_height = input_attrs[0].dims[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//printf("model is NHWC input fmt\n");
|
||||||
|
input_width = input_attrs[0].dims[1];
|
||||||
|
input_height = input_attrs[0].dims[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
printf("model input height=%d, width=%d, channel=%d\n", height, width,
|
||||||
|
channel);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Init input tensor */
|
||||||
|
rknn_input inputs[1];
|
||||||
|
memset(inputs, 0, sizeof(inputs));
|
||||||
|
inputs[0].index = 0;
|
||||||
|
inputs[0].type = RKNN_TENSOR_UINT8;
|
||||||
|
inputs[0].size = input_width * input_height * input_channel;
|
||||||
|
inputs[0].fmt = RKNN_TENSOR_NHWC;
|
||||||
|
inputs[0].pass_through = 0;
|
||||||
|
|
||||||
|
/* Init output tensor */
|
||||||
|
rknn_output outputs[io_num.n_output];
|
||||||
|
memset(outputs, 0, sizeof(outputs));
|
||||||
|
|
||||||
|
for (int i = 0; i < io_num.n_output; i++)
|
||||||
|
{
|
||||||
|
outputs[i].want_float = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Mat letter_image;
|
||||||
|
letter_box(input_image, &letter_image, input_width);
|
||||||
|
inputs[0].buf = letter_image.data;
|
||||||
|
|
||||||
|
rknn_inputs_set(ctx, io_num.n_input, inputs);
|
||||||
|
ret = rknn_run(ctx, NULL);
|
||||||
|
ret = rknn_outputs_get(ctx, io_num.n_output, outputs, NULL);
|
||||||
|
|
||||||
|
// Post process
|
||||||
|
std::vector<float> out_scales;
|
||||||
|
std::vector<uint8_t> out_zps;
|
||||||
|
for (int i = 0; i < io_num.n_output; ++i)
|
||||||
|
{
|
||||||
|
out_scales.push_back(output_attrs[i].scale);
|
||||||
|
out_zps.push_back(output_attrs[i].zp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
yolov5_post_process_u8((uint8_t *)outputs[0].buf, (uint8_t *)outputs[1].buf, (uint8_t *)outputs[2].buf, input_height, input_width,
|
||||||
|
conf_threshold, nms_threshold, out_zps, out_scales, detect_result_group);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
yolov5_post_process_fp((float *)outputs[0].buf, (float *)outputs[1].buf, (float *)outputs[2].buf, input_height, input_width,
|
||||||
|
conf_threshold, nms_threshold, &detect_result_group);
|
||||||
|
*/
|
||||||
|
|
||||||
|
rknn_outputs_release(ctx, io_num.n_output, outputs);
|
||||||
|
|
||||||
|
scale_coords(detect_result_group, img_width, img_height, input_width);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int yolov5_detect_release(rknn_context ctx)
|
||||||
|
{
|
||||||
|
rknn_destroy(ctx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
|
||||||
|
std::string ret;
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
unsigned char char_array_3[3];
|
||||||
|
unsigned char char_array_4[4];
|
||||||
|
|
||||||
|
while (in_len--) {
|
||||||
|
char_array_3[i++] = *(bytes_to_encode++);
|
||||||
|
if (i == 3) {
|
||||||
|
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||||
|
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||||
|
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||||
|
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||||
|
|
||||||
|
for(i = 0; (i <4) ; i++)
|
||||||
|
ret += base64_chars[char_array_4[i]];
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i) {
|
||||||
|
for(j = i; j < 3; j++)
|
||||||
|
char_array_3[j] = '\0';
|
||||||
|
|
||||||
|
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||||
|
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||||
|
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||||
|
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||||
|
|
||||||
|
for (j = 0; (j < i + 1); j++)
|
||||||
|
ret += base64_chars[char_array_4[j]];
|
||||||
|
|
||||||
|
while((i++ < 3))
|
||||||
|
ret += '=';
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool is_base64(unsigned char c) {
|
||||||
|
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||||
|
}
|
Loading…
Reference in New Issue