目录
[笔者实现了Android rtsp yolov5实时检测 50帧](#笔者实现了Android rtsp yolov5实时检测 50帧)
[返回 opencv yuv](#返回 opencv yuv)
rknn3588官网
只有linux支持rtsp,代码:
if(ZLMEDIAKIT_LIBS)
add_definitions(-DBUILD_VIDEO_RTSP)
endif()
cpp
#if defined(BUILD_VIDEO_RTSP)
process_video_rtsp(&app_ctx, video_name);
#else
printf("rtsp no support\n");
#endif
Android支持h264裸流,不支持rtsp码流实时运算
笔者实现了Android rtsp yolov5实时检测 50帧
下载地址:
https://download.csdn.net/download/jacke121/89197233
更换yolov5模型
代码地址:
cpp/postprocess.cc
label地址 类别数 anchors
cpp
#define LABEL_NALE_TXT_PATH "/storage/emulated/0/Android/data/com.rockchip.gpadc.yolodemo/files/coco_2_labels.txt"
static char *labels[OBJ_CLASS_NUM];
int anchor0[6] = {25, 59, 18, 99, 57, 76};
int anchor1[6] = {32, 164, 62, 217, 147, 165};
int anchor2[6] = {85, 388, 179, 457, 421, 368};
用的模型是yolov5 relu版
ffmpegrtsp转264裸流
ffmpeg -i rtsp://admin:[email protected]:554/ch1/main/av_stream -vcodec copy -an -f h264 output.h264
ndk下载:
ffmpeg编译android平台-(ubuntu+ndkr16b+ffmpeg3.4.12)_android-ndk-r16b-CSDN博客
格式RK_FORMAT_YCbCr_420_SP:
cpp
origin = wrapbuffer_fd(fd, width, height, RK_FORMAT_YCbCr_420_SP, width_stride, height_stride);
src = wrapbuffer_fd(mpp_frame_fd, width, height, RK_FORMAT_YCbCr_420_SP, width_stride, height_stride);
android系统rtsp读流进行算法识别
设置权限
bash
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.package.name">
<!-- 网络通信权限 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- 检查网络状态权限 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- 外部存储读写权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
</manifest>
依赖项:
ffmpeg
mpp
返回 opencv yuv
FFmpegMPPDecoder/src/H264MPPDecoder.cpp at main · Done4/FFmpegMPPDecoder · GitHub
cpp
RK_U32 h_stride = mpp_frame_get_hor_stride(frame);
RK_U32 v_stride = mpp_frame_get_ver_stride(frame);
MppBuffer buffer = mpp_frame_get_buffer(frame);
cv::Mat yuvImg(height * 3/2, width, CV_8UC1);
RK_U8 *base = (RK_U8 *)mpp_buffer_get_ptr(buffer);
RK_U8 *base_c = base + h_stride * v_stride;
int idx = 0;
for (int i = 0; i < height; i++, base += h_stride, idx += width)
{
memcpy(yuvImg.data + idx, base, width);
}
for (int i = 0; i < height / 2; i++, base_c += h_stride, idx += width)
{
memcpy(yuvImg.data + idx, base_c, width);
}
rknn输入数据转换
cpp
g_rga_src = wrapbuffer_virtualaddr((void *)inDataRaw, img_width, img_height,
RK_FORMAT_RGBA_8888);
// convert color format and resize. RGA8888 -> RGB888
ret = imresize(g_rga_src, g_rga_dst);
输入数据:
cpp
#if ZERO_COPY
#else
rknn_input inputs[1];
inputs[0].index = 0;
inputs[0].type = RKNN_TENSOR_UINT8;
inputs[0].size = m_in_width * m_in_height * m_in_channel;
inputs[0].fmt = RKNN_TENSOR_NHWC;
inputs[0].pass_through = 0;
inputs[0].buf = g_rga_dst.vir_addr;
#ifdef EVAL_TIME
gettimeofday(&start_time, NULL);
#endif
rknn_inputs_set(ctx, 1, inputs);