DeepStream--保存NvBufSurface图片

        NvBufSurface保存了图像信息,是硬件内存,怎么将硬件内存保存到本地文件?NvBufSurface的memorytype有很多种,类型不一样,获取的方式也不一样,今天主要说的是DGPU上的NVBUF_MEM_CUDA_DEVICE类型。如下是nvidia支持的内存类型。

typedef enum

{

  /** Specifies the default memory type, i.e. \ref NVBUF_MEM_CUDA_DEVICE

   for dGPU, \ref NVBUF_MEM_SURFACE_ARRAY for Jetson. Use \ref NVBUF_MEM_DEFAULT

   to allocate whichever type of memory is appropriate for the platform. */

  NVBUF_MEM_DEFAULT,

  /** Specifies CUDA Host memory type. */

  NVBUF_MEM_CUDA_PINNED,

  /** Specifies CUDA Device memory type. */

  NVBUF_MEM_CUDA_DEVICE,

  /** Specifies CUDA Unified memory type. */

  NVBUF_MEM_CUDA_UNIFIED,

  /** Specifies NVRM Surface Array type. Valid only for Jetson. */

  NVBUF_MEM_SURFACE_ARRAY,

  /** Specifies NVRM Handle type. Valid only for Jetson. */

  NVBUF_MEM_HANDLE,

  /** Specifies memory allocated by malloc(). */

  NVBUF_MEM_SYSTEM,

} NvBufSurfaceMemType;

        保存图片的流程主要是用cudaMemcpy将Device内存拷贝到CPU内存,再根据颜色格式,保存到本地文件。代码如下,支持nv12/rgba/rgb格式的保存。

void
save_nv12(char* src, int width, int height, int pitch, FILE* fp)
{
    for (int i = 0;i < height;i++)
    {
        fwrite(src, 1, width, fp);
        src += pitch;
    }
    for (int i = 0;i < height / 2;i++)
    {
        fwrite(src, 1, width, fp);
        src += pitch;
    }
}

void
save_rgba(char* src, int width, int height, int pitch, FILE* fp)
{
    int datalen = width * 4;
    for (int i = 0;i < height;i++) {
        fwrite(src, 1, datalen, fp);
        src += pitch;
    }
}

void
save_rgb(char* src, int width, int height, int pitch, FILE* fp)
{
    int datalen = width * 3;
    for (int i = 0;i < height;i++) {
        fwrite(src, 1, datalen, fp);
        src += pitch;
    }
}

int
save_NvBufSurface(NvBufSurface * surface, char* filename)
{
    int nRst = 0;
    char* src_data = NULL;
    NvBufSurfaceColorFormat colorFormat;
    int width, height, dataSize, pitch;
    char full_filename[256] = {0};
    for (uint32_t i = 0; i < surface->batchSize; i++) {
      colorFormat = surface->surfaceList[i].colorFormat;
      width = surface->surfaceList[i].width;
      height = surface->surfaceList[i].height;
      dataSize = surface->surfaceList[i].dataSize;
      pitch = surface->surfaceList[i].pitch;
      //printf("colorFormat:%d, w:%d,h:%d,size:%d, pitch:%d\n", colorFormat, width, height, dataSize, pitch);
      if(colorFormat == NVBUF_COLOR_FORMAT_NV12){
        sprintf(full_filename,"%s_%d.yuv", filename, i);
      } else if (colorFormat == NVBUF_COLOR_FORMAT_RGBA){
        sprintf(full_filename,"%s_%d.rgb", filename, i);
      } else if (colorFormat == NVBUF_COLOR_FORMAT_RGB){
        sprintf(full_filename,"%s_%d.rgb", filename, i);
      }
      //save data to file.
      FILE* fp = fopen(full_filename, "wb");
      if(!fp) {
        printf("fopen %s failed\n", full_filename);
        return -1;
      }
      src_data = (char*) malloc(dataSize);
      if(!src_data){ 
        fclose(fp); 
        fp = NULL;
        printf("mallloc failed\n");
        return -1;
      }
      cudaMemcpy((void*)src_data, (void*)surface->surfaceList[i].dataPtr, dataSize, cudaMemcpyDeviceToHost);

      if(colorFormat == NVBUF_COLOR_FORMAT_NV12){
        save_nv12(src_data, width, height, pitch, fp);
      } else if (colorFormat == NVBUF_COLOR_FORMAT_RGBA){
        save_rgba(src_data, width, height, pitch, fp);
      } else if (colorFormat == NVBUF_COLOR_FORMAT_RGB){
        save_rgb(src_data, width, height, pitch, fp);
      }

      fclose(fp);
      fp =  NULL;
      free(src_data); 
      src_data = NULL;
    }
    return nRst;
}

sample:
    static int n = 0;
    char sbuf[32] = {0};
    sprintf(sbuf, "%d", n);
    if(n++ % 300 == 0)
    save_NvBufSurface(surface, sbuf);



保存的数据是原始数据,可以用ffplay进行预览。命令如下:

ffplay -pixel_format nv12 -s 1920x1080 1.yuv

ffplay -pixel_format rgba -s 1920x1080 1.rgb

存成一个文件

int
save_NvBufSurface(NvBufSurface * surface, char* filename)
{
    int nRst = 0;
    char* src_data = NULL;
    NvBufSurfaceColorFormat colorFormat;
    int width, height, dataSize, pitch;
    char full_filename[256] = {0};
    for (uint32_t i = 0; i < surface->batchSize; i++) {
      colorFormat = surface->surfaceList[i].colorFormat;
      width = surface->surfaceList[i].width;
      height = surface->surfaceList[i].height;
      dataSize = surface->surfaceList[i].dataSize;
      pitch = surface->surfaceList[i].pitch;
      //printf("colorFormat:%d, w:%d,h:%d,size:%d, pitch:%d\n", colorFormat, width, height, dataSize, pitch);
      if(colorFormat == NVBUF_COLOR_FORMAT_NV12){
        sprintf(full_filename,"%s.yuv", filename);
      } else if (colorFormat == NVBUF_COLOR_FORMAT_RGBA){
        sprintf(full_filename,"%s.rgb", filename);
      } else if (colorFormat == NVBUF_COLOR_FORMAT_RGB){
        sprintf(full_filename,"%s.rgb", filename);
      }
      //save data to file.
      FILE* fp = fopen(full_filename, "ab+");
      if(!fp) {
        printf("fopen %s failed\n", full_filename);
        return -1;
      }
      src_data = (char*) malloc(dataSize);
      if(!src_data){ 
        fclose(fp); 
        fp = NULL;
        printf("mallloc failed\n");
        return -1;
      }
      cudaMemcpy((void*)src_data, (void*)surface->surfaceList[i].dataPtr, dataSize, cudaMemcpyDeviceToHost);
 
      if(colorFormat == NVBUF_COLOR_FORMAT_NV12){
        save_nv12(src_data, width, height, pitch, fp);
      } else if (colorFormat == NVBUF_COLOR_FORMAT_RGBA){
        save_rgba(src_data, width, height, pitch, fp);
      } else if (colorFormat == NVBUF_COLOR_FORMAT_RGB){
        save_rgb(src_data, width, height, pitch, fp);
      }
 
      fclose(fp);
      fp =  NULL;
      free(src_data); 
      src_data = NULL;
    }
    return nRst;
}

用法:

static int n = 0;
char sbuf[32] = {0};
sprintf(sbuf, "%d", n);

save_NvBufSurface(&nvdspreprocess->batch_outsurf, sbuf);

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
Deepstream-App是一个在安装Deepstream时就已经编译好并安装在系统中的程序,可以在任意位置的命令终端进行调用。它有两种版本,分别是deepstream-app和deepstream-test5-app。这两个版本的功能基本相同,唯一的区别是deepstream-test5-app支持类型设置为6的sink,也就是可以向kafka服务器收发数据的组件。英伟达还提供了这两个app的源代码,源代码的位置在/opt/nvidia/deepstream/deepstream-5.1/sources/apps/sample_apps/deepstream-app和/opt/nvidia/deepstream/deepstream-5.1/sources/apps/sample_apps/deepstream-test5。你可以在这里找到它们并进行学习和参考。\[1\] 如果你想使用deepstream-app,你可以通过在命令终端中输入以下命令来调用它: ``` $ deepstream-app -c ./configs/deepstream-app/source12_1080p_dec_infer-resnet_tracker_tiled_display_fp16_tx2.txt ``` 这个命令会使用指定的配置文件来运行deepstream-app。\[2\] 如果你想查看deepstream-app的用法,你可以在命令终端中输入以下命令: ``` $ deepstream-app --help ``` 这个命令会显示deepstream-app的用法信息。此外,你还可以在/opt/nvidia/deepstream/deepstream-5.1/samples文件夹中找到一些配置文件的示例,可以作为参考。例如,/opt/nvidia/deepstream/deepstream-5.1/samples/configs/deepstream-app/config_infer_primary.txt是一个配置文件的示例。\[3\] #### 引用[.reference_title] - *1* [带你玩转Jetson之Deepstream简明教程(四)DeepstreamApp如何使用以及用于工程验证。](https://blog.csdn.net/u013963960/article/details/129032242)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [运行 deepstream-app](https://blog.csdn.net/quicmous/article/details/117817657)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山西茄子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值