NVIDIA Maxine

NvCVImage API 指南

NvCVImage API 指南

本指南提供有关 AR 和视频特效 SDK 中的 NvCVImage API 的信息。

NvCVImage 为各种图像提供丰富的描述符和优化的功能。

  • 所有函数均可用于 C 和 C++。
  • CPU 或 GPU 上的缓冲区。
  • 多种像素格式,例如,RGB、BGRA、灰度、YUV420 等。
  • 多种组件类型,例如,u8、f32、f16 等。
  • Chunky(交错)、planar(平面)和 semi-planar(半平面)排列。
  • 缓冲区分配、重新分配和释放。
  • 图像传输。
  • 不同图像格式、类型和排列之间的转换。
  • 由遮罩控制的一个图像与另一个图像的合成。
  • 对图像子矩形的操作。
  • NvCVImage 和其他图像表示之间进行零拷贝转换的图像包装器。

本节提供有关如何使用图像的信息。

2.1. 在 GPU 或 CPU 缓冲区上使用图像帧

NVIDIA® AR 和视频特效 SDK 中的 AI 过滤器接受图像缓冲区作为 NvCVImage 对象。图像缓冲区可以是 CPU 或 GPU 缓冲区,但出于性能原因,AI 过滤器需要 GPU 缓冲区。

SDK 提供将图像表示形式转换为 NvCVImage 以及在 CPU 和 GPU 缓冲区之间传输图像的函数。

2.2. 将图像表示形式转换为 NvCVImage 对象

AR 和视频特效 SDK 提供将 OpenCV 图像和其他图像表示形式转换为 NvCVImage 对象的函数。

每个函数都在现有缓冲区周围放置一个包装器。当调用包装器的析构函数时,包装器可防止缓冲区被释放。

2.2.1. 将 OpenCV 图像转换为 NvCVImage 对象

您可以使用 SDK 专门为 RGB OpenCV 图像提供的包装函数。

注意

AR 和视频特效 SDK 仅为 RGB 图像提供包装函数。不为 YUV 图像提供包装函数。


  • 要为 OpenCV 图像创建 NvCVImage 对象包装器,请使用 NVWrapperForCVMat() 函数。
    复制
    已复制!
                

    //Allocate source and destination OpenCV images cv::Mat srcCVImg( ); cv::Mat dstCVImg(...); // Declare source and destination NvCVImage objects NvCVImage srcCPUImg; NvCVImage dstCPUImg; NVWrapperForCVMat(&srcCVImg, &srcCPUImg); NVWrapperForCVMat(&dstCVImg, &dstCPUImg);


  • 要为 NvCVImage 对象创建 OpenCV 图像包装器,请使用 CVWrapperForNvCVImage() 函数。
    复制
    已复制!
                

    // Allocate source and destination NvCVImage objects NvCVImage srcCPUImg(...); NvCVImage dstCPUImg(...); //Declare source and destination OpenCV images cv::Mat srcCVImg; cv::Mat dstCVImg; CVWrapperForNvCVImage (&srcCPUImg, &srcCVImg); CVWrapperForNvCVImage (&dstCPUImg, &dstCVImg);


2.2.2. 将 GPU 或 CPU 缓冲区上的图像帧转换为 NvCVImage 对象

调用 NvCVImage_Init() 函数以在现有缓冲区 (srcPixelBuffer) 周围放置一个包装器。

复制
已复制!
            

NvCVImage src_gpu; vfxErr = NvCVImage_Init(&src_gpu, 640, 480, 1920, srcPixelBuffer, NVCV_BGR, NVCV_U8, NVCV_INTERLEAVED, NVCV_GPU); NvCVImage src_cpu; vfxErr = NvCVImage_Init(&src_cpu, 640, 480, 1920, srcPixelBuffer, NVCV_BGR, NVCV_U8, NVCV_INTERLEAVED, NVCV_CPU);

2.2.3. 将 NvCVImage 对象转换为可由 NvEncoder 编码的缓冲区

要将 NvCVImage 转换为通过 NvEncoder 编码期间使用的像素格式,您可以调用 NvCVImage_Transfer() 函数。以下示例显示了以 BGRA 像素格式编码的帧。

复制
已复制!
            

//BGRA frame is 4-channel, u8 buffer residing on the GPU NvCVImage BGRA_frame; NvCVImage_Alloc(&BGRA_frame, dec.GetWidth(), dec.GetHeight(), NVCV_BGRA, NVCV_U8, NVCV_CHUNKY, NVCV_GPU, 1); //Initialize encoder with a BGRA output pixel format using NvEncCudaPtr = std::unique_ptr<NvEncoderCuda, std::function<void(NvEncoderCuda*)>>; NvEncCudaPtr pEnc(new NvEncoderCuda(cuContext, dec.GetWidth(), dec.GetHeight(), NV_ENC_BUFFER_FORMAT_ARGB)); pEnc->CreateEncoder(&initializeParams); //... std::vector<std::vector<uint8_t>> vPacket; //Get the address of the next input frame from the encoder const NvEncInputFrame* encoderInputFrame = pEnc->GetNextInputFrame(); //Copy the pixel data from BGRA_frame into the input frame address obtained above NvEncoderCuda::CopyToDeviceFrame(cuContext, BGRA_frame.pixels, BGRA_frame.pitch, (CUdeviceptr)encoderInputFrame->inputPtr, encoderInputFrame->pitch, pEnc->GetEncodeWidth(), pEnc->GetEncodeHeight(), CU_MEMORYTYPE_DEVICE, encoderInputFrame->bufferFormat, encoderInputFrame->chromaOffsets, encoderInputFrame->numChromaPlanes); pEnc->EncodeFrame(vPacket);

2.2.4.  将来自 NvDecoder 的解码帧转换为 NvCVImage 对象

调用 NvCVImage_Transfer() 函数以转换 NvDecoder 提供的解码帧,从解码的像素格式转换为 SDK 的某项功能所需的格式。

以下示例显示了一个解码帧,该帧已从 NV12 转换为 BGRA 像素格式。

复制
已复制!
            

NvCVImage decoded_frame, BGRA_frame, stagingBuffer; NvDecoder dec; //Initialize decoder... //Assuming dec.GetOutputFormat() == cudaVideoSurfaceFormat_NV12 //Initialize memory for decoded frame NvCVImage_Init(&decoded_frame, dec.GetWidth(), dec.GetHeight(), dec.GetDeviceFramePitch(), NULL, NVCV_YUV420, NVCV_U8, NVCV_NV12, NVCV_GPU, 1); decoded_frame.colorSpace = NVCV_709 | NVCV_VIDEO_RANGE | NVCV_CHROMA_ COSITED; //Allocate memory for BGRA frame NvCVImage_Alloc(&BGRA_frame, dec.GetWidth(), dec.GetHeight(), NVCV_BGRA, NVCV_U8, NVCV_CHUNKY, NVCV_GPU, 1); decoded_frame.pixels = (void*)dec.GetFrame(); //Convert from decoded frame format(NV12) to desired format(BGRA) NvCVImage_Transfer(&decoded_frame, &BGRA_frame, 1.f, stream, & stagingBuffer);


注意

以上示例假定高清内容的典型色彩空间规范。SD 通常使用 NVCV_601。共有 8 种可能的组合,您应该使用与视频标头中描述的视频匹配的组合,或者通过试错法进行。

以下是一些其他信息:

  • 如果颜色不正确,请交换 709<->601。
  • 如果颜色发灰或过曝,请交换 VIDEO<->FULL。
  • 如果颜色水平偏移,请交换 INTSTITIAL<->COSITED。

2.3. 分配 NvCVImage 对象缓冲区

您可以使用 NvCVImage 分配构造函数或图像函数来分配 NvCVImage 对象的缓冲区。在这两种选项中,当图像超出作用域时,缓冲区都会被析构函数自动释放。

2.3.1. 使用 NvCVImage 分配构造函数来分配缓冲区

NvCVImage 分配构造函数创建一个对象,该对象已分配内存并已初始化。有关更多信息,请参阅分配构造函数
分配构造函数的最后三个可选参数确定生成的 NvCVImage 对象的属性:

  • 像素组织确定蓝色、绿色和红色是在单独的平面中还是交错排列。
  • 内存类型确定缓冲区驻留在 GPU 还是 CPU 上。
  • 字节对齐确定连续扫描线之间的间隙。

以下示例说明了如何使用分配构造函数的最后三个可选参数来确定 NvCVImage 对象的属性。

  • 此示例创建一个对象,而无需设置分配构造函数的最后三个可选参数。在此对象中,蓝色、绿色和红色分量在每个像素中交错排列,缓冲区驻留在 CPU 上,字节对齐是默认对齐。
    复制
    已复制!
                

    NvCVImage cpuSrc( srcWidth, srcHeight, NVCV_BGR, NVCV_U8 );


  • 此示例通过显式设置最后三个可选参数来创建一个对象,该对象具有与前一个示例相同的像素组织、内存类型和字节对齐。与上一个示例一样,蓝色、绿色和红色分量在每个像素中交错排列,缓冲区驻留在 CPU 上,字节对齐是默认对齐,即针对最大性能进行了优化。
    复制
    已复制!
                

    NvCVImage src( srcWidth, srcHeight, NVCV_BGR, NVCV_U8, NVCV_INTERLEAVED, NVCV_CPU, 0 );


  • 此示例创建一个对象,其中蓝色、绿色和红色分量位于单独的平面中,缓冲区驻留在 GPU 上,并且字节对齐确保一个扫描线和下一个扫描线之间不存在间隙。
    复制
    已复制!
                

    NvCVImage gpuSrc( srcWidth, srcHeight, NVCV_BGR, NVCV_U8, NVCV_PLANAR, NVCV_GPU, 1 );


2.3.2. 使用图像函数来分配缓冲区

通过声明一个空图像,您可以延迟缓冲区分配。

  1. 声明一个空的 NvCVImage 对象。
    复制
    已复制!
                

    NvCVImage xfr;

  2. 为图像分配或重新分配缓冲区。
    • 要分配缓冲区,请调用 NvCVImage_Alloc() 函数。

      当图像是状态结构的一部分时,以这种方式分配缓冲区,在这种情况下,您在稍后才会知道图像的大小。

    • 要重新分配缓冲区,请调用 NvCVImage_Realloc()

      此函数检查是否已分配缓冲区,如果缓冲区足够大,则会重塑缓冲区,然后再释放缓冲区并调用 NvCVImage_Alloc()

2.4. 在 CPU 和 GPU 缓冲区之间传输图像

如果输入和输出图像缓冲区的内存类型不同,则应用程序可以在 CPU 和 GPU 缓冲区之间传输图像。

2.4.1. 将输入图像从 CPU 缓冲区传输到 GPU 缓冲区

以下是有关如何传输输入图像的一些信息。

  1. 要使用转换将图像从 CPU 传输到 GPU 缓冲区,给定以下代码
    复制
    已复制!
                

    NvCVImage srcCpuImg(width, height, NVCV_RGB, NVCV_U8, NVCV_INTERLEAVED, NVCV_CPU, 1); NvCVImage dstGpuImg(width, height, NVCV_BGR, NVCV_F32, NVCV_PLANAR, NVCV_GPU, 1);

  2. 创建 NvCVImage 对象以用作以下方式之一的暂存 GPU 缓冲区:
    • 为避免在视频管线中分配内存,请在初始化阶段创建 GPU 缓冲区,其尺寸和格式与 CPU 图像相同。
      复制
      已复制!
                  

      NvCVImage stageImg(srcCpuImg.width, srcCpuImg.height, srcCpuImg.pixelFormat, srcCpuImg.componentType, srcCpuImg.planar, NVCV_GPU);

    • 为了简化您的应用程序程序代码,您可以在初始化阶段声明一个空的暂存缓冲区。
      复制
      已复制!
                  

      NvCVImage stageImg;

      如果需要,将根据需要分配或重新分配适当大小的缓冲区。

  3. 调用 NvCVImage_Transfer() 函数以通过暂存 GPU 缓冲区将源 CPU 缓冲区内容复制到最终 GPU 缓冲区。
    复制
    已复制!
                

    // Transfer the image from the CPU to the GPU, perhaps with conversion. NvCVImage_Transfer(&srcCpuImg, &dstGpuImg, 1.0f, stream, &stageImg);

2.4.2. 将输出图像从 GPU 缓冲区传输到 CPU 缓冲区

以下是将输出图像从 GPU 传输到 CPU 缓冲区的步骤。

  1. 要使用转换将图像从 GPU 传输到 CPU 缓冲区,给定以下代码
    复制
    已复制!
                

    NvCVImage srcGpuImg(width, height, NVCV_BGR, NVCV_F32, NVCV_PLANAR, NVCV_GPU, 1); NvCVImage dstCpuImg(width, height, NVCV_BGR, NVCV_U8, NVCV_INTERLEAVED, NVCV_CPU, 1);

  2. 创建 NvCVImage 对象以用作以下方式之一的暂存 GPU 缓冲区:
    • 为避免在视频管线中分配内存,请在初始化阶段创建 GPU 缓冲区,其尺寸和格式与 CPU 图像相同。
      复制
      已复制!
                  

      NvCVImage stageImg(dstCpuImg.width, dstCpuImg.height, dstCPUImg.pixelFormat, dstCPUImg.componentType, dstCPUImg.planar, NVCV_GPU);


    • 为了简化您的应用程序程序代码,您可以在初始化阶段声明一个空的暂存缓冲区。
      复制
      已复制!
                  

      NvCVImage stageImg;


      如果需要,将根据需要分配或重新分配适当大小的缓冲区。

  3. 调用 NvCVImage_Transfer() 函数以通过暂存 GPU 缓冲区将 GPU 缓冲区内容复制到目标 CPU 缓冲区。
    复制
    已复制!
                

    // Retrieve the image from the GPU to CPU, perhaps with conversion. NvCVImage_Transfer(&srcGpuImg, &dstCpuImg, 1.0f, stream, &stageImg);


    如果暂存缓冲区是持久性的,则可以重复使用相同的暂存缓冲区,而无需在 NvCVImage_Transfer 中重新分配。

本节提供有关 NvCVImage API 中枚举的信息。

3.1. NvCVImage_ComponentType

以下是有关 NvCVImage_ComponentType 的详细信息。

此枚举定义用于表示像素的一个组件的数据类型。

NVCV_TYPE_UNKNOWN = 0
未知的组件数据类型。
NVCV_U8 = 1
无符号 8 位整数。
NVCV_U16 = 2
无符号 16 位整数。
NVCV_S16 = 3
有符号 16 位整数。
NVCV_F16 = 4
16 位浮点数。
NVCV_U32
无符号 32 位整数。
NVCV_S32 = 6
有符号 32 位整数。
NVCV_F32 = 7
32 位浮点数 (float)。
NVCV_U64 =8
无符号 64 位整数。
NVCV_S64 = 9
有符号 64 位整数。
NVCV_F64 = 10
64 位浮点数 (double)。

3.2. NvCVImage_PixelFormat

此枚举定义像素中组件的顺序。

NVCV_FORMAT_UNKNOWN
未知的像素格式。
NVCV_Y
亮度(灰度)。
NVCV_A
Alpha(不透明)。
NVCV_YA
亮度、Alpha。
NVCV_RGB
红色、绿色、蓝色。
NVCV_BGR
蓝色、绿色、红色。
NVCV_RGBA
红色、绿色、蓝色、Alpha。
NVCV_BGRA
蓝色、绿色、红色、Alpha。
NVCV_YUV420
亮度和子采样色度 (Y, Cb, Cr)。
NVCV_YUV444
亮度和全带宽色度 { Y, Cb, Cr }
NVCV_YUV422
亮度和子采样色度 (Y, Cb, Cr)。

3.2.1. 像素组织

以下是有关像素如何组织的信息。

图像中像素的组件可以通过以下方式组织:

  • 交错像素(也称为 chunky 像素)很紧凑,并且排列方式使得图像中每个像素的组件都是连续的。
  • 平面像素的排列方式使得图像中所有像素的各个组件(例如,红色组件)都组合在一起。
  • 半平面像素是交错和平面组件的混合。
  • 这些类型的像素在视频领域中很常见,其中 [Y] 组件位于一个平面中,而 [UV] 组件交错排列在另一个平面中。

通常,像素是交错的。但是,许多神经网络在使用平面像素时性能更好。在像素组织的描述中,方括号 ([]) 用于指示像素组件组的排列方式。例如:

  • [VYUY] 表示 V、Y、U 和 Y 组件组是交错的。
  • [Y][U][V] 表示所有像素的 Y、U 和 V 组件都组合在一起。
  • [Y][UV] 表示 Y 组件组以及 U 和 V 组件组是交错的。
有关 YUV 像素格式的更多信息,请参阅YUV 像素格式
AR 和视频特效 API 定义了以下类型来指定像素组织

表 1. 像素组织类型
类型 描述
NVCV_INTERLEAVED 0  
NVCV_CHUNKY 0

这些类型中的每一种都指定了交错或 chunky 像素,其中图像中每个像素的组件都是相邻的。

NVCV_PLANAR 1

此类型指定了平面像素,其中图像中所有像素的各个组件都组合在一起。

NVCV_UYVY 2

此类型指定 UYVY 像素,这些像素采用交错 YUV 4:2:2 格式(4:2:2 的默认格式和非 YUV 的默认格式)。

像素排列在 [UYVY] 组中。

NVCV_VYUY 4

此类型指定 VYUY 像素,这些像素采用交错 YUV 4:2:2 格式。

像素排列在 [VYUY] 组中。

NVCV_YUYV

NVCV_YUY2

6

这些类型中的每一种都指定 YUYV 像素,这些像素采用交错 YUV 4:2:2 格式。

像素排列在 [YUYV] 组中。

NVCV_YVYU 8

此类型指定 YVYU 像素,这些像素采用交错 YUV 4:2:2 格式。

像素排列在 [YVYU] 组中。

NVCV_CYUV 10

此类型指定交错(chunky)YUV 4:4:4 像素。

像素排列在 [YUV] 组中。

NVCV_CYVU 12

此类型指定交错(chunky)YVU 4:4:4 像素。

像素排列在 [YVU] 组中。

NVCV_YUV

NVCV_I420(与 NVCV_YUV420 一起使用)

NVCV_IYUV(与 NVCV_YUV420 一起使用)

NVCV_I444(与 NVCV_YUV444 一起使用)

NVCV_YM24(与 NVCV_YUV444 一起使用)

3

这些类型中的每一种都指定了平面 YUV 像素,具有 4:2:0、4:2:2 或 4:4:4 采样。

像素排列在 [Y]、[U] 和 [V] 组中。

NVCV_YVU

NVCV_YV12(与 NVCV_YUV420 一起使用)

NVCV_YM42(与 NVCV_YUV444 一起使用)

5

这些类型中的每一种都指定了 YV12 像素,这些像素采用平面 YUV 4:2:0、YUV 4:2:2 或 YUV 4:4:4 格式。

像素排列在 [Y]、[V] 和 [U] 组中。

NVCV_YCUV

NVCV_NV12(与 NVCV_YUV420 一起使用)

NVCV_NV24(与 NVCV_YUV444 一起使用)

7

这些类型中的每一种都指定了半平面 YUV 像素,具有 4:2:0、4:2:2 或 4:4:4 采样。

像素排列在 [Y] 和 [UV] 组中,例如,Y 在第一个平面中,U 和 V 交错排列在第二个平面中。NV12 用于指代具有 4:2:0 采样的半平面像素,是 GPU 上最流行的 YUV 格式。

NVCV_YCVU

NVCV_NV21(与 NVCV_YUV420 一起使用)

NVCV_NV42(与 NVCV_YUV444 一起使用)

9

这些类型中的每一种都指定了半平面 YVU 像素,具有 4:2:0、4:2:2 或 4:4:4 采样。

像素排列在 [Y] 和 [VU] 组中,例如,Y 在第一个平面中,V 和 U 交错排列在第二个平面中。这与之前的布局类似,只是 U 和 V 交换了位置。


注意

FlipY 仅在平面 4:2:2 格式(UYVY、VYUY、YUYV 和 YVYU)中受支持,在其他平面或半平面格式中不受支持。

3.2.2. YUV 色彩空间

以下是有关 YUV 色彩空间的信息。

AR 和视频特效 API 定义了以下类型来指定 YUV 色彩空间

表 2. 指定 YUV 色彩空间的类型
类型 描述
NVCV_601 0

此类型指定 Rec.601 YUV 色彩空间,该色彩空间通常用于标准清晰度 (SD) 视频。

NVCV_709 1

此类型指定 Rec.709 YUV 色彩空间,该色彩空间通常用于高清晰度 (HD) 视频。

NVCV_VIDEO_RANGE 0

此类型指定视频范围 [16, 235]。

NVCV_FULL_RANGE 4

此类型指定视频范围 [0, 255]。

NVCV_CHROMA_COSITED

NVCV_CHROMA_MPEG2

0

这些类型中的每一种都指定了一种色彩空间,其中色度在水平方向上与亮度样本在同一位置进行采样。大多数视频格式都使用此采样方案。

NVCV_CHROMA_INTSTITIAL

NVCV_CHROMA_MPEG1

8

这些类型中的每一种都指定了一种色彩空间,其中色度在水平方向上在亮度样本之间的中间位置进行采样。JPEG 使用此采样方案。


示例:创建高清 NV12 CUDA 缓冲区

复制
已复制!
            

NvCVImage *imp = new NvCVImage(1920, 1080, NVCV_YUV420, NVCV_U8, NVCV_NV12, NVCV_CUDA, 0); imp->colorSpace = NVCV_709 | NVCV_VIDEO_RANGE | NVCV_CHROMA_COSITED;


示例:围绕现有高清 NV12 CUDA 缓冲区包装 NvCVImage 描述符

复制
已复制!
            

NvCVImage img; NvCVImage_Init(&img, 1920, 1080, 1920, existingBuffer, NVCV_YUV420, NVCV_U8, NVCV_NV12, NVCV_CUDA); img.colorSpace = NVCV_709 | NVCV_VIDEO_RANGE | NVCV_CHROMA_COSITED; These are particularly useful and performant for interfacing to the NVDEC video decoder.

3.2.3. 内存类型

以下是有关 AR 和视频特效 SDK 中可用的内存类型的信息。

图像数据缓冲区可以存储在不同类型的内存中,这些内存具有不同的地址空间。

表 3. 存储图像数据缓冲区的内存类型
类型 描述
NVCV_CPU

缓冲区存储在普通 CPU 内存中。

NVCV_CPU_PINNED

缓冲区存储在锁页 CPU 内存中;这可以提高 CPU 和 GPU 之间的传输速率(115%-200%),但应谨慎使用。

NVCV GPU

NVCV CUDA

缓冲区存储在 CUDA 内存中。

本节提供有关 AR 和视频特效 SDK 中 NvCVImage API 的详细信息。

4.1. NvCVImage_Alloc

以下是有关 NcCVImage_Alloc 的详细信息。

复制
已复制!
            

NvCV_Status NvCVImage_Alloc( NvCVImage *im unsigned width, unsigned height, NvCVImage_PixelFormat format, NvCVImage_ComponentType type, unsigned layout, unsigned memSpace, unsigned alignment );

参数

im [in,out]

类型:NvCVImage *

要初始化的图像。

width [in]

类型:unsigned

图像的宽度(以像素为单位)。

height [in]

类型:unsigned

图像的高度(以像素为单位)。

format [in]

类型:NvCVImage_PixelFormat

像素的格式。

type [in]

类型:NvCVImage_ComponentType

像素组件的类型。

layout [in]

类型:unsigned

图像中像素组件的组织。有关更多信息,请参阅像素组织

memSpace [in]

类型:unsigned

要存储图像数据缓冲区的内存类型。有关更多信息,请参阅内存类型

alignment [in]

类型:unsigned

行字节对齐,用于指定每条扫描线中第一个像素的对齐方式。将此参数设置为 0 或 2 的幂。

  • 1:指定扫描线之间没有间隙。

    许多视频特效过滤器使用的所有 GPU 缓冲区都需要字节对齐为 1。

  • 0:指定默认对齐,该对齐取决于存储图像数据缓冲区的内存类型:
    • CPU 内存:指定 4 字节对齐。
    • GPU 内存:指定 cudaMallocPitch 设置的对齐。
  • 2 或更大:指定任何其他对齐,例如 16 或 32 字节的缓存行大小。

    例如,Upscale 特效需要 32 的对齐。

注意

如果 widthNvCVImagepixelBytes 成员的乘积是 alignment 的整数倍,则扫描线之间的间隙为 0 字节,而与 alignment 的值无关。

返回值

  • NVCV_SUCCESS 表示成功。
  • NVCV_ERR_PIXELFORMAT 表示不支持像素格式。
  • NVCV_ERR_MEMORY 表示缓冲区需要的内存超出可用内存。

备注

此函数为图像分配内存并初始化图像。此函数假定图像数据结构中没有任何有意义的内容。此函数由 C++ NvCVImage 构造函数调用。您可以从 C 代码调用此函数,以为空图像分配内存并初始化图像。

4.2. NvCVImage_ComponentOffsets

以下是有关 NvCVImage_ComponentOffsets 的详细信息。

复制
已复制!
            

void NvCVImage_ComponentOffsets( NvCVImage_PixelFormat format, int *rOff, int *gOff, int *bOff, int *aOff, int *yOff );

参数

format [in]

类型:NvCVImage_PixelFormat

要检索其组件偏移的像素格式。

rOff [out]

类型:int *

存储红色通道偏移的位置(可以为 NULL)。

gOff [out]

类型:int *

存储绿色通道偏移的位置(可以为 NULL)。

bOff [out]

类型:int *

存储蓝色通道偏移的位置(可以为 NULL)。

aOff [out]

类型:int *

存储 Alpha 通道偏移的位置(可以为 NULL)。

yOff [out]

类型:int *

存储亮度通道偏移的位置(可以为 NULL)。

返回值

不返回值。

备注

此函数获取像素格式组件的偏移量。这些偏移量是组件偏移量,而不是字节偏移量。对于交错像素,组件偏移量必须乘以 NvCVImagecomponentBytes 成员才能获得字节偏移量。

4.3. NvCVImage_Composite

以下是有关 NvCVImage_Composite 的详细信息。

复制
已复制!
            

NvCV_Status NvCVImage_Composite( const NvCVImage *fg, const NvCVImage *bg, const NvCVImage *mat, NvCVImage *dst, CUstream stream );

参数

fg [in]

类型:const NvCVImage *

前景源,它是 RGB、BGR、RGBA 或 BGRA 图像,具有 u8 或 f32 组件。

bg [in]

类型:const NvCVImage *

背景源,它是 RGB、BGR、RGBA 或 BGRA 图像,具有 u8 或 f32 组件。

mat [in]

类型:const NvCVImage *

遮罩 Y 或 A 图像,具有 u8 或 f32 组件,指示源图像应从何处通过。

dst [out]

类型:NvCVImage *

目标图像,可以与 fg 前景图像或 bg 背景图像相同,也可以是完全无关的图像。

注意

如果目标图像格式包含 Alpha,则在此实现中不会更新 Alpha 通道。


stream [out]

类型:CUstream

要在其上传输图像的 CUDA 流。如果源图像和目标图像的内存类型均为 CPU,则忽略此参数。

返回值

  • NVCV_SUCCESS 表示成功
  • NVCV_ERR_PIXELFORMAT 表示像素格式不受支持。

备注

此函数使用指定的遮罩图像将前景图像合成到背景图像上。fg、bg、matdst 图像必须具有相同的组件类型,但图像不需要具有相同的像素格式。可以使用 RGBA 或 BGRA 图像,但不会更新目标的 A 通道。

此函数假定源未预乘 Alpha。如果值是预乘的,请改用模式 1 的 NvCVImage_CompositeRect()

4.4.  NvCVImage_CompositeRect

以下是有关 NvCVImage_CompositeRect 的详细信息。

复制
已复制!
            

NvCV_Status NvCVImage_CompositeRect( const NvCVImage *fg, const NvCVPoint2i *fgOrg, const NvCVImage *bg, const NvCVPoint2i *bgOrg, const NvCVImage *mat, unsigned int mode, NvCVImage *dst, const NvCVPoint2i *dstOrg, CUstream stream );

参数

fg [in]

类型:const NvCVImage *

前景源,它是 RGB、BGR、RGBA 或 BGRA 图像,具有 u8 或 f32 组件。

fgOrg [in]

类型:const NvCVPoint2i *

指向前景图像左上角原点的指针,图像将从该原点传输。

复制
已复制!
            

typedef struct NvCVPoint2i { int x, y; } NvCVPoint2i;


如果此参数为 NULL,则图像将从 (0,0) 传输。

bg [in]

类型:const NvCVImage *

背景源,它是 RGB、BGR、RGBA 或 BGRA 图像,具有 u8 或 f32 组件。

bgOrg [in]

类型:const NvCVPoint2i *

指向背景图像左上角原点的指针

复制
已复制!
            

typedef struct NvCVPoint2i { int x, y; } NvCVPoint2i;


图像将从该原点传输。如果此参数为 NULL,则图像将从 (0,0) 传输。

mat [in]

类型:const NvCVImage *

遮罩 Y 或 A 图像,具有 u8 或 f32 组件,指示源图像应从何处通过。遮罩的尺寸确定要合成的区域的大小。

如果此参数包含 Alpha 通道,则该参数可以与 fg 图像相同。

mode [in]

类型:unsigned int

以下是合成模式选择选项:

  • 0:正常、直通 Alpha 覆盖合成。

    “覆盖”是最常见的合成操作,它将前景应用到背景之上,并由遮罩引导。这是在其他未明确指定模式的函数中使用的合成模式。

  • 1:预乘 Alpha覆盖合成。

    预乘表示源 R、G 和 B 预乘了 Alpha,例如(αR, αG, αB, α),这在渲染场景中自然发生。

  • 其他值返回参数错误。
dst [out]

类型:NvCVImage *

目标图像,可以与 fg (前景) 或 bg (背景) 图像相同,也可以是完全无关的图像。

注意

如果目标图像格式包含 Alpha,则在此实现中不会更新 Alpha 通道。


dstOrg [输入]

类型:const NvCVPoint2i *

指向目标图像左上角原点的指针

复制
已复制!
            

typedef struct NvCVPoint2i { int x, y; } NvCVPoint2i;


图像将传输到该原点。如果此参数为 NULL,则图像将传输到 (0,0)。

stream [out]

类型:CUstream

要在其上传输图像的 CUDA 流。如果源图像和目标图像的内存类型均为 CPU,则忽略此参数。

返回值

  • NVCV_SUCCESS 表示成功
  • NVCV_ERR_PIXELFORMAT 表示像素格式不受支持。
  • 如果选择了 0 以外的模式,则返回 NVCV_ERR_PARAMETER

备注

此函数使用指定的蒙版图像将前景图像合成到背景图像之上。fgbgmatdst 图像必须具有相同的组件类型,但图像不需要具有相同的像素格式。也可以使用 RGBA 或 BGRA 图像,但不会更新目标的 A 通道。

复制
已复制!
            

NvCVImage_Composite(fg, bg, mat, dst, str);


等于

复制
已复制!
            

NvCVImage_CompositeRect(fg, 0, bg, 0, mat, 0, dst, 0, str);

4.5. NvCVImage_CompositeOverConstant

以下是有关 NvCVImage_Composite 的详细信息。

复制
已复制!
            

NvCV_Status NvCVImage_CompositeOverConstant( const NvCVImage *src, const NvCVImage *mat, const void *bgColor, NvCVImage *dst, CUstream stream );

参数

src [输入]

类型:const NvCVImage *

源 RGB、BGR、RGBA 或 BGRA 图像,具有 u8 或 f32 组件。像素颜色不应预乘 alpha。

mat [in]

类型:const NvCVImage *

如果此参数包含 alpha 通道,则此参数可以与 src 图像相同。

[输入] bgColor

类型:const void*

指向背景颜色的指针,源图像将合成在该背景颜色之上。此颜色必须具有与目标图像相同的类型 (u8, f32) 和格式 (RGB, BGR),并且必须在合成完成之前保持有效。

dst [out]

类型:NvCVImage *

目标 BGR 或 RGB u8 或 f32 图像。目标图像可能与源图像相同。

注意

如果目标图像格式包含 alpha,则在此实现中不会更新 alpha 通道。


stream [out]

类型:CUstream

要在其上传输图像的 CUDA 流。如果源图像和目标图像的内存类型均为 CPU,则忽略此参数。

返回值

  • NVCV_SUCCESS 表示成功。
  • NVCV_ERR_PIXELFORMAT 表示不支持像素格式。

备注

此函数使用指定的蒙版图像将 BGR 或 RGB 图像合成到恒定颜色场上。也可以使用 RGBA 和 BGRA 图像,但不会更新目标的 A 通道。

4.6. NvCVImage_Create

以下是关于 NvCVImage_Create 的详细信息。

复制
已复制!
            

NvCV_Status NvCVImage_Create( unsigned width, unsigned height, NvCVImage_PixelFormat format, NvCVImage_ComponentType type, unsigned layout, unsigned memSpace, unsigned alignment, NvCVImage **out );

参数

width [in]

类型:unsigned

图像的宽度(以像素为单位)。

height [in]

类型:unsigned

图像的高度(以像素为单位)。

format [in]

类型:NvCVImage_PixelFormat

像素的格式。

type [in]

类型:NvCVImage_ComponentType

像素组件的类型。

layout [in]

类型:unsigned

图像中像素组件的组织。有关更多信息,请参阅像素组织

memSpace [in]

类型:unsigned

图像数据缓冲区将存储在其中的内存类型。有关更多信息,请参阅 内存类型

alignment [in]

类型:unsigned

行字节对齐,它指定每条扫描线中第一个像素的对齐方式。将此参数设置为 0 或 2 的幂。

  • 1:指定扫描线之间没有间隙。
  • 视频特效滤波器使用的所有 GPU 缓冲区都需要 1 字节对齐。
  • 0:指定默认对齐方式,该对齐方式取决于存储图像数据缓冲区的内存类型:
    • CPU 内存:指定 4 字节对齐,
    • GPU 内存:指定 cudaMallocPitch 设置的对齐。
  • 2 或更大:指定任何其他对齐,例如 16 或 32 字节的缓存行大小。
注意

如果 widthNvCVImagepixelBytes 成员的乘积是 alignment 的整数倍,则扫描线之间的间隙为 0 字节,而与 alignment 的值无关。


out [输出]

类型:NvCVImage **

指向将存储新分配的图像的位置的指针。图像描述符和像素缓冲区被存储,以便在调用 NvCVImage_Destroy() 时将其释放。

返回值

  • NVCV_SUCCESS 表示成功。
  • NVCV_ERR_PIXELFORMAT 表示不支持像素格式。
  • NVCV_ERR_MEMORY 表示缓冲区需要的内存超出可用内存。

备注

此函数创建一个图像并分配一个图像缓冲区,该缓冲区将作为特效滤波器的输入提供,并为新图像分配存储空间。此函数是 NvCVImage 结构实例的 C 风格构造函数(等效于 C++ 中的 new NvCVImage)。

4.7. NvCVImage_Dealloc

以下是关于 NvCVImage_Dealloc 的详细信息。

复制
已复制!
            

void NvCVImage_Dealloc( NvCVImage *im );

参数

im [in,out]

类型:NvCVImage *

指向将释放其图像缓冲区的图像的指针。

返回值

不返回值。

备注

此函数从指定的 NvCVImage 结构中释放图像缓冲区,并将 NvCVImage 结构的内容设置为 0。

4.8. NvCVImage_DeallocAsync

以下是关于 NvCVImage_DeallocAsync 的详细信息。

复制
已复制!
            

void NvCVImage_DeallocAsync( NvCVImage *im, CUstream stream );

参数

im [in,out]

类型:NvCVImage *

指向将释放其图像缓冲区的图像的指针。

stream [out]

类型:CUstream

CUDA 流,图像将在该流上传输。如果源图像和目标图像的内存类型为 CPU,则忽略此参数。

返回值

不返回值。

备注

此函数在指定的 CUDA 流上异步释放图像缓冲区,并将 NvCVImage 结构的内容设置为 0。如果没有缓冲区,或者缓冲区位于 CPU 上,则立即释放。

4.9. NvCVImage_Destroy

以下是关于 NvCVImage_Destroy 的详细信息。

复制
已复制!
            

void NvCVImage_Destroy( NvCVImage *im );

参数

im

类型:NvCVImage *

指向将要销毁的图像的指针。

返回值

不返回值。

备注

此函数销毁使用 NvCVImage_Create() 函数创建的图像,并释放为此图像分配的资源和内存。此函数是 NvCVImage 结构实例的 C 风格析构函数(等效于 C++ 中的 delete im)。

4.10. NvCVImage_Init

以下是关于 NvCVImage_Init 的详细信息。

复制
已复制!
            

NvCV_Status NvCVImage_Init( NvCVImage *im, unsigned width, unsigned height, unsigned pitch, void *pixels, NvCVImage_PixelFormat format, NvCVImage_ComponentType type, unsigned layout, unsigned memSpace );

参数

im [in,out]

类型:NvCVImage *

指向将要初始化的图像的指针。

width [in]

类型:unsigned

图像的宽度(以像素为单位)。

height [in]

类型:unsigned

图像的高度(以像素为单位)。

pitch [输入]

类型:unsigned

像素之间的垂直字节步幅。

pixels [输入]

类型:void

指向将附加到 NvCVImage 对象的像素缓冲区的指针。

format

类型:NvCVImage_PixelFormat

图像中像素的格式。

type

类型:NvCVImage_ComponentType

用于表示图像每个组件的数据类型。

layout [in]

类型:unsigned

图像中像素组件的组织。有关更多信息,请参阅像素组织

memSpace [in]

类型:unsigned

要存储图像数据缓冲区的内存类型。有关更多信息,请参阅内存类型

返回值

  • NVCV_SUCCESS 表示成功。
  • NVCV_ERR_PIXELFORMAT 表示不支持像素格式。

备注

此函数从原始缓冲区指针初始化 NvCVImage 结构。当您将现有像素缓冲区包装在 NvCVImage 图像描述符中时,从原始缓冲区指针初始化 NvCVImage 对象非常有用。此函数由初始化 NvCVImage 对象数据结构的函数调用,例如:

  • C++ 构造函数
  • NvCVImage_Alloc()
  • NvCVImage_Realloc()
  • NvCVImage_InitView()

调用此函数以初始化 NvCVImage 对象,而不是直接设置字段。

4.11. NvCVImage_InitView

以下是关于 NvCVImage_InitView 的详细信息。

复制
已复制!
            

void NvCVImage_InitView( NvCVImage *subImg, NvCVImage *fullImg, int x, int y, unsigned width, unsigned height );

参数

subImg [输入]

类型:NvCVImage *

指向将使用视图初始化的现有图像的指针。

fullImg [输入]

类型:NvCVImage *

指向现有图像的指针,将从该图像中获取指定矩形区域的视图。

x [输入]

类型:int

要获取的视图的左边缘的 x 坐标。

y [输入]

类型:int

要获取的视图的顶边缘的 y 坐标。

width [in]

类型:unsigned

要获取的视图的宽度(以像素为单位)。

height [in]

类型:unsigned

要获取的视图的高度(以像素为单位)。

返回值

不返回值。

备注

此函数获取图像中指定矩形区域的视图,并使用该视图初始化另一个现有图像描述符。由于使用了使用视图初始化的图像(由参数 fullImg 指定)的缓冲区,因此不分配内存。

注意

这仅适用于 NVCV_CHUNKY (NVCV_INTERLEAVED) 图像,不适用于 NVCV_PLANAR 或任何 YUV 平面或半平面图像格式。但是,如果此视图旨在选择图像的一部分来调用 NvCVImage_Transfer()NvCVImage_Composite(),则可以使用矩形版本 NvCVImage_TransferRect()NvCVImage_CompositeRect() 代替。这些版本适用于所有格式,包括平面或 YUV 格式。

4.12. NvCVImage_Realloc

以下是关于 NvCVImage_Realloc 的详细信息。

复制
已复制!
            

NvCV_Status NvCVImage_Realloc( NvCVImage *im, unsigned width, unsigned height, NvCVImage_PixelFormat format, NvCVImage_ComponentType type, unsigned layout, unsigned memSpace, unsigned alignment );

参数

im [in,out]

类型:NvCVImage *

要初始化的图像。

width [in]

类型:unsigned

图像的宽度(以像素为单位)。

height [in]
图像的高度(以像素为单位)。
format [in]

类型:NvCVImage_PixelFormat

像素的格式。

type [in]

类型:NvCVImage_ComponentType

像素组件的类型。

layout [in]

类型:unsigned

图像中像素组件的组织。有关更多信息,请参阅像素组织

memSpace [in]

类型:unsigned

要存储图像数据缓冲区的内存类型。有关更多信息,请参阅内存类型

alignment [in]

类型:unsigned

行字节对齐,它指定每条扫描线中第一个像素的对齐方式。将此参数设置为 0 或 2 的幂。

  • 1:指定扫描线之间没有间隙。

    视频特效滤波器使用的所有 GPU 缓冲区都需要 1 字节对齐。

  • 0:指定默认对齐方式,该对齐方式取决于存储图像数据缓冲区的内存类型:
    • CPU 内存:指定 4 字节对齐。
    • GPU 内存:指定 cudaMallocPitch 设置的对齐。
  • 2 或更大:指定任何其他对齐,例如 16 或 32 字节的缓存行大小。


注意

如果 width 与 NvCVImage 的 pixelBytes 成员的乘积是 alignment 的整数倍,则扫描线之间的间隙为 0 字节,而与 alignment 的值无关。

返回值

  • NVCV_SUCCESS 表示成功。
  • NVCV_ERR_PIXELFORMAT 表示不支持像素格式。
  • NVCV_ERR_MEMORY 表示缓冲区需要的内存超出可用内存。

备注

此函数重新分配内存并初始化图像。

注意

此函数假定图像有效。


该函数检查 NvCVImage 的 bufferBytes 成员以确定是否有足够的内存可用:

  • 如果有足够的内存可用,则该函数会重塑内存,而不是重新分配内存。
  • 如果内存不足,则该函数将释放现有缓冲区的内存并为新缓冲区分配内存。

4.13. NvCVImage_Transfer

以下是关于 NvCVImage_Transfer 的详细信息。

复制
已复制!
            

NvCV_Status NvCVImage_Transfer( const NvCVImage *src, NvCVImage *dst, float scale, CUstream stream, NvCVImage *tmp );

参数

src [输入]

类型:const NvCVImage *

指向将要传输的源图像的指针。

dst [out]

类型:NvCVImage *

指向将要传输源图像的目标图像的指针。

scale [输入]

类型:float

比例因子,当源图像或目标图像的组件类型为浮点型时,可以应用该比例因子。比例因子缩放每个组件的值(而不是图像的大小),并且 当源图像或目标图像的组件类型为浮点型时才有效。

以下是典型值:

  • 1.0f
  • 255.0f
  • 1.0f/255.0f

如果两个图像都没有浮点组件类型,则忽略此参数。

stream [输入]

类型:CUstream

要在其上传输图像的 CUDA 流。如果源图像和目标图像的内存类型均为 CPU,则忽略此参数。

tmp [输入,输出]

类型:NvCVImage *

指向 GPU 内存中临时缓冲区的指针,仅当源图像正在转换且源图像和目标图像的内存类型不同时才需要该缓冲区。该缓冲区具有与 CPU 图像相同的特性,但驻留在 GPU 上。

如有必要,临时 GPU 缓冲区将被重塑以适应传输的需要,例如,匹配 CPU 图像的特性。因此,为了获得最佳性能,您可以提供一个空图像作为临时 GPU 缓冲区。如有必要,NvCVImage_Transfer() 会分配一个大小合适的缓冲区。相同的临时 GPU 缓冲区可以用于后续调用 NvCVImage_Transfer(),而与形状、格式或组件类型无关,因为缓冲区将根据需要增长以适应最大的内存需求。

如果不需要临时 GPU 缓冲区,则不分配缓冲区。如果不需要临时 GPU 缓冲区,则 tmp 可以为 NULL。但是,如果 tmpNULL,并且需要临时 GPU 缓冲区,则会分配一个临时缓冲区,从而导致图像序列的性能下降。

返回值

  • NVCV_SUCCESS 表示成功。
  • 当发生 CUDA 错误时,返回 NVCV_ERR_CUDA
  • 当源图像或目标图像的像素格式不受支持时,返回 NVCV_ERR_PIXELFORMAT
  • 当发生未指定的错误时,返回 NVCV_ERR_GENERAL

备注

此函数将一个图像传输到另一个图像,并且可以对图像执行一些转换。当图像驻留在 GPU 上时,该函数使用 GPU 执行转换。

表 4 提供了有关像素格式之间支持的转换的详细信息。

注意

在每种转换类型中,RGB 可以是任何顺序。


表 4. 像素转换
  U8 --> U8 U8 --> F32 F32 --> U8 F32 --> F32
Y--> Y X   X  
Y --> A X   X  
Y --> RGB X X X X
Y --> RGBA X X X X
A --> Y X   X  
A --> A X   X  
A --> RGB X X X X
A --> RGBA X      
RGB --> Y X X    
RGB --> A X      
RGB --> RGB X X X X
RGB --> RGBA X X X X
RGBA --> Y X X    
RGBA --> A X      
RGBA --> RGB X X X X
RGBA --> RGBA X   X  
YUV420 --> RGB X X    
YUV422 --> RGB X X    
YUV444 --> RGB X X    
RGB --> YUV420 X   X  
RGB --> YUV422 X   X  
RGB --> YUV444 X   X  


以下是关于这些转换的一些附加信息:

  • 分块和平面像素组织之间的转换可以在任一方向发生。
  • CPU 和 GPU 内存类型之间的转换可以在任一方向发生。
  • 组件的不同排序之间的转换可以在任一方向发生,例如,BGR --> RGB。
  • 从 RGB(或 BGR)到 RGBA(或 BGRA)的转换会将 alpha 通道设置为不透明(u8 为 255,f32 为 1.0)。
  • 对于 RGBA(或 BGRA)目标,大多数实现不会更改 alpha 通道。在初始化时,对于分块和平面 u8 图像,我们建议您使用以下方法之一设置它
    复制
    已复制!
                

    [cuda]memset(im.pixels, -1, im.pitch * im.height)


    复制
    已复制!
                

    [cuda]memset(im.pixels, -1, im.pitch * im.height* im.numComponents)


  • 除了 pitch 之外,如果没有必要的转换,则所有像素格式传输都使用 cudaMemcpy2DAsync() 实现。

    YUV --> YUV 传输的另一个限制是,src 和 dst 之间的格式、布局和色彩空间必须匹配。

  • YUV420 和 YUV422 和 YUV444 源有几种变体。

    必须在传输之前手动设置色彩空间。有关更多信息,请参阅 YUV 色彩空间

  • 还有 RGBf16 --> RGBf32 和 RGBf32 --> RGBf16 传输。
  • CPU --> CPU 传输是同步的。
    • 此外,当 srcdst 格式相同时,CPU 和 GPU 上都支持所有格式,并且这可以用作 cudaMemcpy2DAsync() 的替代品(它利用了 cudaMemcpy2DAsync())。
    • 如果 srcdst 具有不同的大小,则传输仍然会发生,但会裁剪为较小的大小。

如果两个图像都驻留在 CPU 上,则传输同步发生。但是,如果任一图像驻留在 GPU 上,则传输可能会异步发生。同一 CUDA 流上的一系列异步调用会自动按预期顺序执行,但要同步,可以调用 cudaStreamSynchronize() 函数。

4.14. NvCVImage_TransferRect

以下是关于 NvCVImage_TransferRect 的详细信息。

复制
已复制!
            

NvCV_Status NvCVImage_TransferRect( const NvCVImage *src, const NvCVRect2i *srcRect, NvCVImage *dst, const NvCVPoint2i *dstPt, float scale, CUstream stream, NvCVImage *tmp );

参数

src [输入]

类型:const NvCVImage *

指向将要传输的源图像的指针。

srcRect [输入]

类型:const NvCVRect2i *

指向将要传输的源图像矩形的指针。

复制
已复制!
            

typedef struct NvCVRect2i { int x, y, width, height; } NvCVRect2i;


如果此参数为 NULL,则使用整个 src 图像矩形。

dst [out]

类型:NvCVImage *

指向将要传输源图像的目标图像的指针。

dstPt [输入]

类型:const NvCVPoint2i *

指向图像将要传输到的目标图像位置的指针。

复制
已复制!
            

typedef struct NvCVPoint2i { int x, y; } NvCVPoint2i;


如果此参数为 NULL,则图像将传输到 (0,0)。

scale [输入]

类型:float

比例因子,当源图像或目标图像的组件类型为浮点型时,可以应用该比例因子。比例仅当源图像或目标图像的组件类型为浮点型时才有效。

以下是典型值:

  • 1.0f
  • 255.0f
  • 1.0f/255.0f

如果两个图像都没有浮点组件类型,则忽略此参数。

stream [输入]

类型:CUstream

要在其上传输图像的 CUDA 流。如果源图像和目标图像的内存类型均为 CPU,则忽略此参数。

tmp [输入,输出]

类型:NvCVImage *

指向 GPU 内存中临时缓冲区的指针,仅当源图像正在转换 并且 源图像和目标图像的内存类型不同时才需要该缓冲区。该缓冲区具有与 CPU 图像相同的特性,但驻留在 GPU 上。

如有必要,临时 GPU 缓冲区将被重塑以适应传输的需要,例如,匹配 CPU 图像的特性。因此,为了获得最佳性能,您可以提供一个空图像作为临时 GPU 缓冲区。如有必要,NvCVImage_Transfer() 会分配一个大小合适的缓冲区。相同的临时 GPU 缓冲区可以用于后续调用 NvCVImage_Transfer(),而与形状、格式或组件类型无关,因为缓冲区将根据需要增长以适应最大的内存需求。

如果不需要临时 GPU 缓冲区,则不分配缓冲区。如果不需要临时 GPU 缓冲区,则 tmp 可以为 NULL。但是,如果 tmp 为 NULL,并且需要临时 GPU 缓冲区,则会分配一个临时缓冲区,从而导致图像序列的性能下降。

返回值

  • NVCV_SUCCESS 表示成功。
  • 当发生 CUDA 错误时,返回 NVCV_ERR_CUDA
  • 当源图像或目标图像的像素格式不受支持时,返回 NVCV_ERR_PIXELFORMAT
  • 当发生未指定的错误时,返回 NVCV_ERR_GENERAL

备注

此函数类似于 NvCVImage_Transfer(),因为它们共享相同的代码。可以通过将 NvCVImage_InitView()NvCVImage_Transfer() 结合使用来复制矩形,但这仅适用于分块图像。

NvCVImage_TransferRect 适用于分块、平面和半平面图像布局,并且性能没有差异。

NvCVImage_Transfer(src, dst, scale, stream, tmp) 等效于 NvCVImage_TransferRect(src, 0, dst, 0, scale, stream, tmp)

如果您在复制 YUV 矩形时不小心,则会发生意外的裁剪:

  • YUV420 必须具有偶数的 x、y、宽度和高度。
  • YUV422 必须具有偶数的 x 和宽度。

4.15. NvCVImage_TransferFromYUV

以下是关于 NvCVImage_TransferFromYUV 的详细信息。

复制
已复制!
            

NvCV_Status NvCVImage_TransferFromYUV( const void *y, int yPixBytes, int yPitch, const void *u, const void *v, int uvPixBytes, int uvPitch, NvCVImage_PixelFormat yuvFormat, NvCVImage_ComponentType yuvType, unsigned yuvColorSpace, unsigned yuvMemSpace, NvCVImage *dst, const NvCVRect2i *dstRect, float scale, struct CUstream_st *stream, NvCVImage *tmp );

参数

y [输入]

类型:const void *

指向亮度通道的像素 (0,0) 的指针。

yPixBytes [输入]

类型:int

y 像素之间水平方向的字节步幅。

yPitch [输入]

类型:int

y 像素之间垂直方向的字节步幅。

u [输入]

类型:const void *

指向 u (Cb) 色度通道的像素 (0,0) 的指针。

v [输入]

类型:const void *

指向 v (Cr) 色度通道的像素 (0,0) 的指针。

uvPixBytes [输入]

类型:int

u 或 v 像素之间水平方向的字节步幅。

uvPitch [输入]

类型:int

u 或 v 像素之间垂直方向的字节步幅。

yuvColorSpace [输入]

类型:unsigned int

yuv 色彩空间,它指定范围、色度和色度相位。

yuvMemSpace [输入]

类型:unsigned int

YUV 缓冲区驻留的内存空间(例如,CPU、CUDA 等)。

dst [out]

类型:NvCVImage *

指向将要传输源图像的目标图像的指针。

dstRect [输入]

类型:const NvCVRect2i *

指向目标图像矩形的指针

复制
已复制!
            

typedef struct NvCVRect2i { int x, y, width, height; } NvCVRect2i;


图像将传输到该矩形。此参数可以为 NULL,在这种情况下,将传输整个 dst 图像。

scale [输入]

类型:float

比例因子,当源图像或目标图像的组件类型为浮点型时,可以应用该比例因子。比例仅当源图像或目标图像的组件类型为浮点型时才有效。

以下是典型值:

  • 1.0f
  • 255.0f
  • 1.0f/255.0f

如果两个图像都没有浮点组件类型,则忽略此参数。

stream [输入]

类型:CUstream

要在其上传输图像的 CUDA 流。如果源图像和目标图像的内存类型均为 CPU,则忽略此参数。

tmp [输入,输出]

类型:NvCVImage *

指向 GPU 内存中临时缓冲区的指针,仅当源图像正在转换且源图像和目标图像的内存类型不同时才需要该缓冲区。该缓冲区具有与 CPU 图像相同的特性,但驻留在 GPU 上。

如有必要,临时 GPU 缓冲区将被重塑以适应传输的需要,例如,匹配 CPU 图像的特性。因此,为了获得最佳性能,您可以提供一个空图像作为临时 GPU 缓冲区。如有必要,NvCVImage_Transfer() 会分配一个大小合适的缓冲区。相同的临时 GPU 缓冲区可以用于后续调用 NvCVImage_Transfer(),而与形状、格式或组件类型无关,因为缓冲区将根据需要增长以适应最大的内存需求。

如果不需要临时 GPU 缓冲区,则不分配缓冲区。如果不需要临时 GPU 缓冲区,则 tmp 可以为 NULL。但是,如果 tmp 为 NULL,并且需要临时 GPU 缓冲区,则会分配一个临时缓冲区,从而导致图像序列的性能下降。

返回值

  • NVCV_SUCCESS 表示成功。
  • 当发生 CUDA 错误时,返回 NVCV_ERR_CUDA
  • 当源图像或目标图像的像素格式不受支持时,返回 NVCV_ERR_PIXELFORMAT
  • 当发生未指定的错误时,返回 NVCV_ERR_GENERAL

备注

此函数类似于 NvCVImage_TransferRect(),它也可以从 YUV 图像复制。不同之处在于 TransferRect 适用于具有结构的图像,如布局(或平面)参数中所述,而 NvCVImage_TransferFromYUV 适用于在布局参数的分类中没有表示结构的图像。由于结构未知,因此当从 CPU --> GPU 传输时,TransferFromYUV 也比 TransferRect 慢。

4.16. NvCVImage_TransferToYUV

以下是关于 NvCVImage_TransferToYUV 的详细信息。

复制
已复制!
            

NvCV_Status NvCVImage_TransferToYUV( const NvCVImage *src, const NvCVRect2i *srcRect, const void *y, int yPixBytes, int yPitch, const void *u, const void *v, int uvPixBytes, int uvPitch, NvCVImage_PixelFormat yuvFormat, NvCVImage_ComponentType yuvType, unsigned yuvColorSpace, unsigned yuvMemSpace, float scale, CUstream stream, NvCVImage *tmp );

参数

src [输入]

类型:const NvCVImage *

指向将要传输的源图像的指针。

srcRect [输入]

类型:const NvCVRect2i *

指向将要传输的源图像矩形的指针。

typedef struct NvCVRect2i { int x, y, width, height; } NvCVRect2i;

如果此参数为 NULL,则使用整个 src 图像矩形。

y [输出]

类型:NvCVImage *

指向亮度通道的像素 (0,0) 的指针。

yPixBytes [输入]

类型:int

y 像素之间水平方向的字节步幅。

yPitch [输入]

类型:in

y 像素之间垂直方向的字节步幅。

u [输出]

类型:NvCVImage *

指向 u (Cb) 色度通道的像素 (0,0) 的指针。

v [输出]

类型:NvCVImage *

指向 v (Cr) 色度通道的像素 (0,0) 的指针。

uvPixBytes [输入]

类型:int

u 或 v 像素之间水平方向的字节步幅。

uvPitch [输入]

类型:int

u 或 v 像素之间垂直方向的字节步幅。

yuvColorSpace [输入]

类型:unsigned int

yuv 色彩空间,它指定范围、色度和色度相位。

yuvMemSpace [输入]

类型:unsigned int

像素缓冲区驻留的内存空间。

scale [输入]

类型:float

比例因子,当源图像或目标图像的组件类型为浮点型时,可以应用该比例因子。比例仅当源图像或目标图像的组件类型为浮点型时才有效。

以下是典型值:

  • 1.0f
  • 255.0f
  • 1.0f/255.0f

如果两个图像都没有浮点组件类型,则忽略此参数。

stream [输入]

类型:CUstream

要在其上传输图像的 CUDA 流。如果源图像和目标图像的内存类型均为 CPU,则忽略此参数。

tmp [输入,输出]

类型:NvCVImage *

指向 GPU 内存中临时缓冲区的指针,仅当源图像正在转换且源图像和目标图像的内存类型不同时才需要该缓冲区。该缓冲区具有与 CPU 图像相同的特性,但驻留在 GPU 上。

如有必要,临时 GPU 缓冲区将被重塑以适应传输的需要,例如,匹配 CPU 图像的特性。因此,为了获得最佳性能,您可以提供一个空图像作为临时 GPU 缓冲区。如有必要,NvCVImage_Transfer() 会分配一个大小合适的缓冲区。相同的临时 GPU 缓冲区可以用于后续调用 NvCVImage_Transfer(),而与形状、格式或组件类型无关,因为缓冲区将根据需要增长以适应最大的内存需求。

如果不需要临时 GPU 缓冲区,则不分配缓冲区。如果不需要临时 GPU 缓冲区,则 tmp 可以为 NULL。但是,如果 tmp 为 NULL,并且需要临时 GPU 缓冲区,则会分配一个临时缓冲区,从而导致图像序列的性能下降。

返回值

  • NVCV_SUCCESS 表示成功。
  • 当发生 CUDA 错误时,返回 NVCV_ERR_CUDA
  • 当源图像或目标图像的像素格式不受支持时,返回 NVCV_ERR_PIXELFORMAT
  • 当发生未指定的错误时,返回 NVCV_ERR_GENERAL

备注

此函数类似于 NvCVImage_TransferRect(),它也可以复制到 YUV 图像。不同之处在于 TransferRect 适用于具有结构的图像,如布局(或平面)参数中所述,而 NvCVImage_TransferToYUV 适用于在布局参数的分类中没有表示结构的图像。

4.17. NvCVImage_MapResource

以下是关于 NvCVImage_MapResource 的详细信息。

复制
已复制!
            

NvCV_Status NvCVImage_MapResource( NvCVImage *im, struct CUstream_st *stream );

参数

im [in,out]

类型:NvCVImage *

要映射的图像。

stream [out]

类型:struct CUStream_st *

要在其上执行映射的流。

返回值

NVCV_SUCCESS 表示成功。

备注

在图形系统渲染和 CUDA 传输之间,您还需要映射纹理资源。此过程涉及相当多的开销,因此应尽量减少其使用。每次调用 NvCVImage_MapResource() 都应与后续调用 NvCVImage_UnmapResource() 相匹配。

在 Windows 上创建图像包装资源的一种方法是调用 NvCVImage_InitFromD3DTexture()

4.18. NvCVImage_UnmapResource

以下是关于 NvCVImage_UnmapResource 的详细信息。

复制
已复制!
            

NvCV_Status NvCVImage_UnmapResource( NvCVImage *im, struct CUstream_st *stream );

参数

im [in,out]

类型:NvCVImage *

要映射的图像。

stream [out]

类型:struct CUStream_st *

要在其上执行映射的流。

返回值

NVCV_SUCCESS 表示成功

备注

在图形系统渲染和 CUDA 传输之间,您还需要映射纹理资源。此过程涉及相当多的开销,因此应尽量减少其使用。每次调用 NvCVImage_MapResource() 都应与后续调用 NvCVImage_UnmapResource() 相匹配。

在 Windows 上创建图像包装资源的一种方法是调用 NvCVImage_InitFromD3DTexture()

4.19. NvCVImage_InitFromD3DTexture

以下是关于 NvCVImage_InitFromD3DTexture 的详细信息。

复制
已复制!
            

NvCV_Status NvCVImage_InitFromD3DTexture( NvCVImage *im, struct ID3D11Texture2D *tx );

参数

im [in,out]

类型:NvCVImage *

要初始化的图像。

tx [输入]

类型:struct ID3D11Texture2D *

用于初始化的纹理。

返回值

NVCV_SUCCESS 表示成功。

备注

您可以从 D3D11 纹理初始化 NvCVImagepixelFormat 和组件类型将被传输,并且注册 cudaGraphicsResourceNvCVImage 析构函数将注销资源。

注意

这旨在与 NvCVImage_Transfer() 一起使用。


在允许 D3D 纹理渲染到 NvCVImage 之前,您需要先调用 NvCVImage_MapResource()NvCVImage_UnmapResource()

4.20. C++ 示例应用程序的辅助函数

本节中的辅助函数在 nvCVOpenCV.h 文件中提供,以帮助 NvCVImage 接口与 OpenCV 的图像表示进行交互,例如,cv::Mat

4.20.1. CVWrapperForNvCVImage

以下是关于 CVWrapperForNvCVImage 的详细信息。

复制
已复制!
            

void CVWrapperForNvCVImage( const NvCVImage *vfxIm, cv::Mat *cvIm );

参数

vfxIm [输入]

类型:const NvCVImage *

指向已分配的 NvCVImage 对象的指针。

cvIm [输出]

类型:cv::Mat *

指向空的 OpenCV 图像的指针,该图像已正确初始化以访问 NvCVImage 对象的缓冲区。空 OpenCV 图像由默认的 cv::Mat 构造函数创建。

返回值

不返回值。

备注

此函数为 NvCVImage 对象创建 OpenCV 图像包装器。

4.20.2. NVWrapperForCVMat

以下是关于 NVWrapperForCVMat 的详细信息。

复制
已复制!
            

void NVWrapperForCVMat( const cv::Mat *cvIm, NvCVImage *vIm );

参数

cvIm [输入]

类型:const cv::Mat *

指向已分配的 OpenCV 图像的指针。

vfxIm [输出]

类型:NvCVImage *

指向空的 NvCVImage 对象的指针,该对象由此函数正确初始化以访问 OpenCV 图像的缓冲区。空 NvCVImage 对象由默认的(无参数)NvCVImage() 构造函数创建。

返回值

不返回值。

备注

此函数为 OpenCV 图像创建 NvCVImage 对象包装器。

4.21. 仅限 C++ 的图像函数

图像 API 为 C++ 提供了构造函数、析构函数以及一些仅 C++ 可访问的附加函数。

4.21.1. NvCVImage 构造函数

本节提供了 AR 和视频特效 SDK 中 NvCVImage 构造函数的列表。

4.21.1.1. 默认构造函数

默认构造函数创建一个没有缓冲区的空图像。

复制
已复制!
            

NvCVImage();

4.21.1.2. 分配构造函数

分配构造函数创建一个已分配内存并已初始化的图像。

复制
已复制!
            

NvCVImage( unsigned width, unsigned height, NvCVImage_PixelFormat format, NvCVImage_ComponentType type, unsigned layout, unsigned memSpace, unsigned alignment );

以下是参数

format [in]

类型:NvCVImage_PixelFormat

像素的格式。

type [in]

类型:NvCVImage_ComponentType

像素组件的类型。

layout [in]

类型:unsigned

图像中像素组件的组织。有关更多信息,请参阅像素组织

memSpace [in]

类型:unsigned

要存储图像数据缓冲区的内存类型。有关更多信息,请参阅内存类型

alignment [in]

类型:unsigned

行字节对齐,它指定每条扫描线中第一个像素的对齐方式。将此参数设置为 0 或 2 的幂。

  • 1:指定扫描线之间没有间隙。

    视频特效滤波器使用的所有 GPU 缓冲区都需要 1 字节对齐。

  • 0:指定默认对齐方式,该对齐方式取决于存储图像数据缓冲区的内存类型:
    • CPU 内存:指定 4 字节对齐。
    • GPU 内存:指定由 cudaMallocPitch 设置的对齐方式。
  • 2 或更大:指定任何其他对齐,例如 16 或 32 字节的缓存行大小。
注意

如果 width 与 NvCVImage 的 pixelBytes 成员的乘积是 alignment 的整数倍,则扫描线之间的间隙为 0 字节,而与 alignment 的值无关。


4.21.1.3. 子图像构造函数

子图像构造函数创建一个图像,该图像使用另一个图像中指定矩形的视图进行初始化。不分配额外的内存。

复制
已复制!
            

NvCVImage( NvCVImage *fullImg, int x, int y, unsigned width, unsigned height );

以下是参数

fullImg [输入]

类型:NvCVImage *

指向现有图像的指针,将从该图像中获取指定矩形区域的视图。

x [输入]
要获取的视图的左边缘的 x 坐标。
y [输入]
要获取的视图的顶边缘的 y 坐标。
width [in]

类型:unsigned

要获取的视图的宽度(以像素为单位)。

height [in]

类型:unsigned

要获取的视图的高度(以像素为单位)。

4.21.2. NvCVImage 析构函数

以下是此析构函数的代码。

复制
已复制!
            

~NvCVImage();

4.21.3. copyFrom

以下是关于 copyFrom 函数的一些信息。

此版本将整个图像复制到另一个图像,并且在功能上与 NvCVImage_Transfer(src, this, 1.0f, 0, NULL); 相同。

复制
已复制!
            

NvCV_Status copyFrom( const NvCVImage *src );


此版本将源图像中指定的矩形复制到目标图像。

复制
已复制!
            

NvCV_Status copyFrom( const NvCVImage *src, int srcX, int srcY, int dstX, int dstY, unsigned width, unsigned height );

参数

src [输入]

类型:const NvCVImage *

指向现有源图像的指针,将从该图像中复制指定的矩形。

srcX [输入]

类型:int

源图像中将要复制的矩形的左边缘的 x 坐标。

srcY [输入]

类型:int

源图像中将要复制的矩形的顶边缘的 y 坐标。

dstX [输入]

类型:int

目标图像中复制的矩形的左边缘的 x 坐标。

srcY [输入]

类型:int

目标图像中复制的矩形的顶边缘的 y 坐标。

width [in]

类型:unsigned

要复制的矩形的宽度(以像素为单位)。

height [in]

类型:unsigned

要复制的矩形的高度(以像素为单位)。

返回值

  • NVCV_SUCCESS 表示成功。
  • NVCV_ERR_PIXELFORMAT 表示不支持像素格式。
  • 当源图像和目标图像的格式不同时,返回 NVCV_ERR_MISMATCH
  • 如果发生 CUDA 错误,则返回 NVCV_ERR_CUDA

备注

此重载函数将整个图像复制到另一个图像,或将图像中指定的矩形复制到另一个图像。此函数可以复制存储在不同内存类型中的图像数据缓冲区,如下所示:

  • 从 CPU 到 CPU
  • 从 CPU 到 GPU
  • 从 GPU 到 GPU
  • 从 GPU 到 CPU

注意

对于其他用例,请使用 NvCVImage_Transfer() 函数。

注意

本文档仅供参考,不得视为对产品的特定功能、状况或质量的保证。NVIDIA Corporation(“NVIDIA”)不对本文档中包含的信息的准确性或完整性作任何明示或暗示的陈述或保证,并且对本文档中包含的任何错误不承担任何责任。对于因使用此类信息或因使用此类信息而可能导致的侵犯第三方专利或其他权利的行为,NVIDIA 概不负责。本文档不构成对开发、发布或交付任何材料(如下定义)、代码或功能的承诺。

NVIDIA 保留随时修改、更正、增强、改进和对本文档进行任何其他更改的权利,恕不另行通知。

客户在下订单之前应获取最新的相关信息,并应验证此类信息是否为最新且完整。

NVIDIA 产品按照 NVIDIA 标准销售条款和条件进行销售,这些条款和条件在订单确认时提供,除非 NVIDIA 授权代表和客户签署的单独销售协议另有约定(“销售条款”)。对于本文件中提及的 NVIDIA 产品的购买,NVIDIA 特此明确反对适用任何客户通用条款和条件。本文档未直接或间接形成任何合同义务。

NVIDIA 产品并非设计、授权或保证适用于医疗、军事、航空、航天或生命维持设备,也不适用于 NVIDIA 产品的故障或失灵可能合理预期会导致人身伤害、死亡或财产或环境损害的应用。NVIDIA 对在上述设备或应用中包含和/或使用 NVIDIA 产品不承担任何责任,因此,此类包含和/或使用由客户自行承担风险。

NVIDIA 不保证或声明基于本文档的产品将适用于任何特定用途。NVIDIA 不一定会对每种产品的所有参数进行测试。客户全权负责评估和确定本文档中包含的任何信息的适用性,确保产品适合并满足客户计划的应用,并为该应用执行必要的测试,以避免应用或产品发生故障。客户产品设计中的缺陷可能会影响 NVIDIA 产品的质量和可靠性,并可能导致超出本文档所包含的附加或不同的条件和/或要求。NVIDIA 对任何可能基于或归因于以下原因的任何故障、损坏、成本或问题不承担任何责任:(i) 以违反本文档的方式使用 NVIDIA 产品或 (ii) 客户产品设计。

本文档未授予任何 NVIDIA 专利权、版权或其他 NVIDIA 知识产权的明示或暗示许可。NVIDIA 发布的有关第三方产品或服务的信息不构成 NVIDIA 授予的使用此类产品或服务的许可,也不构成对此类产品或服务的保证或认可。使用此类信息可能需要获得第三方在其专利或其他知识产权下的许可,或获得 NVIDIA 在其专利或其他知识产权下的许可。

只有在事先获得 NVIDIA 书面批准的情况下,才能复制本文档中的信息,复制时不得进行修改,并应完全遵守所有适用的出口法律和法规,并且应附带所有相关的条件、限制和声明。

本文档以及所有 NVIDIA 设计规范、参考板、文件、图纸、诊断程序、列表和其他文档(统称为“材料”,单独称为“材料”)均“按原样”提供。NVIDIA 对这些材料不作任何明示、暗示、法定或其他形式的保证,并且明确否认所有关于不侵权、适销性和特定用途适用性的暗示保证。在法律未禁止的范围内,在任何情况下,NVIDIA 均不对因使用本文档而引起的任何损害(包括但不限于任何直接、间接、特殊、附带、惩罚性或后果性损害,无论何种原因造成,也无论何种责任理论)承担责任,即使 NVIDIA 已被告知可能发生此类损害。尽管客户可能因任何原因遭受任何损害,NVIDIA 对本文所述产品的总累积责任应根据产品的销售条款中的规定进行限制。

VESA DisplayPort

DisplayPort 和 DisplayPort Compliance Logo、Dual-mode Sources 的 DisplayPort Compliance Logo 以及 Active Cables 的 DisplayPort Compliance Logo 是视频电子标准协会在美国和其他国家/地区的商标。

HDMI

HDMI、HDMI 标志和 High-Definition Multimedia Interface 是 HDMI Licensing LLC 的商标或注册商标。

OpenCL

OpenCL 是 Apple Inc. 的商标,已获得 Khronos Group Inc. 的许可使用。

商标

NVIDIA、NVIDIA 徽标以及 cuBLAS、CUDA、CUDA Toolkit、cuDNN、DALI、DIGITS、DGX、DGX-1、DGX-2、DGX Station、DLProf、GPU、JetPack、Jetson、Kepler、Maxwell、NCCL、Nsight Compute、Nsight Systems、NVCaffe、NVIDIA Ampere GPU architecture、NVIDIA Deep Learning SDK、NVIDIA Developer Program、NVIDIA GPU Cloud、NVLink、NVSHMEM、PerfWorks、Pascal、SDK Manager、T4、Tegra、TensorRT、TensorRT Inference Server、Tesla、TF-TRT、Triton Inference Server、Turing 和 Volta 是 NVIDIA Corporation 在美国和其他国家/地区的商标和/或注册商标。其他公司和产品名称可能是与其相关的各自公司的商标。

© 2021-2023 NVIDIA Corporation 及其附属公司。保留所有权利。 上次更新时间:2022 年 12 月 20 日。