DeepStream结合OpenCV4实现视频的分析和截图(二)

12 篇文章 22 订阅
5 篇文章 0 订阅

0. 前言

上一篇写的是基于test4的更改,后来应用到app的demo里发现颜色转换存在问题。
首先要确定自己的探针添加位置,以及该位置获取的图像颜色空间是什么。在deepstream-app里我查看的是NV12,CV里没有NV12转BGR(或许有,我没找到),所以需要利用NvBufSurfTransformNvBufSurfTransformParams进行转换。

1. 分源截图

  如果演示的视频一共有4路,如何将这4路分别截图呢?方法是利用source_id和batch_id
  其中source_id代表不同的源,这些信息进入队列后,不是按照顺序排列的,有可能第二个先进入,然后第四个又进入了,后面才是1、3。batch_id对应的就是队列里的位置。NvBufSurface的surfacelist对应的是batch_id。
  如何获取source_id和batch_id呢?这些都存在NvDsFrameMeta的结构里。
可令:

    NvBufSurface *surface = NULL;
    NvBufSurface surface_idx;
    
	surface_idx.surfaceList = &(surface->surfaceList[batch_id]);

2. 参数转换

 先转成RGBA,再用opencv转BGR

/** save pictures */
	// GstBuffer *buf;
    NvBufSurfTransformRect src_rect, dst_rect;
    NvBufSurfTransformParams nvbufsurface_params;
    NvBufSurface *dst_surface = NULL;
    NvBufSurfaceCreateParams nvbufsurface_create_params;
    cudaError_t cuda_err;
    cudaStream_t cuda_stream;
    gint create_result;
    NvBufSurfTransformConfigParams transform_config_params;
    NvBufSurfTransform_Error err;
    cv::Mat bgr_frame, in_mat;
	
	batch_size = surface_idx.batchSize;
	src_rect.top   = 0;
	src_rect.left  = 0;
	src_rect.width = (guint) surface->surfaceList[batch_id].width;
	src_rect.height = (guint) surface->surfaceList[batch_id].height;
	
	dst_rect.top   = 0;
	dst_rect.left  = 0;
	dst_rect.width = (guint) surface->surfaceList[batch_id].width;
	dst_rect.height = (guint) surface->surfaceList[batch_id].height;
	
	nvbufsurface_params.src_rect = &src_rect;
	nvbufsurface_params.dst_rect = &dst_rect;
	nvbufsurface_params.transform_flag =  NVBUFSURF_TRANSFORM_CROP_SRC | NVBUFSURF_TRANSFORM_CROP_DST;
	nvbufsurface_params.transform_filter = NvBufSurfTransformInter_Default;
	
	nvbufsurface_create_params.gpuId  = surface->gpuId;
	nvbufsurface_create_params.width  = (guint) surface->surfaceList[batch_id].width;
	nvbufsurface_create_params.height = (guint) surface->surfaceList[batch_id].height;
	nvbufsurface_create_params.size = 0;
	nvbufsurface_create_params.isContiguous = true;
	nvbufsurface_create_params.colorFormat = NVBUF_COLOR_FORMAT_RGBA;
	nvbufsurface_create_params.layout = NVBUF_LAYOUT_PITCH;
	
	// THE memType PARAM IS SET TO CUDA UNIFIED IN dGPU DEVICES COMMENT IT out
	// AND USE THE IMMEDIATE NEXT LINE TO SET THE memType PARAM FOR JETSON DEVICES

#ifdef PLATFORM_TEGRA
    nvbufsurface_create_params.memType = NVBUF_MEM_DEFAULT;
#else
    nvbufsurface_create_params.memType = NVBUF_MEM_CUDA_UNIFIED;
#endif
 	cuda_err = cudaSetDevice (surface->gpuId);
	cuda_err = cudaStreamCreate(&cuda_stream);
	create_result = NvBufSurfaceCreate(&dst_surface, batch_size, &nvbufsurface_create_params);
	
	transform_config_params.compute_mode = NvBufSurfTransformCompute_Default;
	transform_config_params.gpu_id = surface->gpuId;
	transform_config_params.cuda_stream = cuda_stream;
	err = NvBufSurfTransformSetSessionParams (&transform_config_params);
	
	NvBufSurfaceMemSet (dst_surface, 0, 0, 0);
	err = NvBufSurfTransform (&surface_idx, dst_surface, &nvbufsurface_params);
	
	if (err != NvBufSurfTransformError_Success) {
	   g_print ("NvBufSurfTransform failed with error %d while converting buffer\n", err);
	}
	
	NvBufSurfaceMap (dst_surface, 0, 0, NVBUF_MAP_READ);
	NvBufSurfaceSyncForCpu (dst_surface, 0, 0);

 用完不要忘记释放空间

  NvBufSurfaceUnMap(dst_surface, 0, 0);
  NvBufSurfaceUnMap(&surface_idx, 0, 0);
  NvBufSurfaceDestroy(dst_surface);
  cudaStreamDestroy (cuda_stream);
  gst_buffer_unmap (buf, &in_map_info);	

3. 其他问题

(1)目前我调试还会遇到以下错误:

CUDA error at nvbufsurftransform.cpp:1793 code=-57(NPP_RECTANGLE_ERROR) “nppiResizeSqrPixel_8u_C4R ( src_ptr + src_offset, jnppSrcSize, jsrc_pitch, jnppSrcROI, intermediate_buffer + dst_offset, jdst_pitch, jnppDstROI, scale_x, scale_y, jdx, jdy, nppInterFlag)”

NvBufSurfTransfrom failed with error -3 while converting buffer

 目前无解,但不影响截图~~有哪位大佬找到问题所在后可以私戳我。
(2)纠错
 上篇文章里写到,对于非jetson,用不到下面两个函数:

NvBufSurfaceMap (dst_surface, 0, 0, NVBUF_MAP_READ);
NvBufSurfaceSyncForCpu (dst_surface, 0, 0);

 这里辟谣一下。这种说法是不对的,能不能在GPU上跑,和这俩函数无关。一定要有buffer的拷贝就对了。

4. makefile

 补充一下,有人问makefile是否需要修改。
 需要的。
 需要添加opencv的头文件,库,以及-lnvbufsurface -lnvbufsurftransform 两个库。如果用到了cuda,也需要添加cuda的相关内容。

5. 结果

存的图片分路保存了,加了个时间戳
在这里插入图片描述
截图效果如下:
在这里插入图片描述

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值