# 图形运算加速模块

BMCV提供了一套基于算丰AI芯片优化的机器视觉库，目前可以完成色彩空间变换，尺度变换，仿射变换，线性变换等操作。关于bmcv模块详细内容请阅读[**BMCV\_User\_Guide.pdf**](https://sophon-edge.gitbook.io/bmcv-1684/)。

​ python接口的实现请参考[**Sophon\_Inference\_zh.pdf**](https://sophon-edge.gitbook.io/sophon-inference/)

​ bmcv api均是围绕bm\_image来进行的。一个bm\_image结构对应于一张图片。用户通过一系列bm\_image\_create的API来构建bm\_image结构体，然后供各个bmcv的功能函数使用。

## 1. C语言编程接口

### **bm\_image结构体：**

```
struct bm_image {
    int width;
    int height;
    bm_image_format_ext image_format;
    bm_data_format_ext data_type;
    bm_image_private* image_private;
};
```

bm\_image 结构成员包括图片的宽高，，图片格式，图片数据格式，以及该结构的私有数据。

关于bm\_image初始化，我们不建议用户直接填充bm\_image结构使用，而是通过以下API来创建/销毁一个bm\_image结构

### **图片格式 image\_format枚举类型**

```
typedef enum bm_image_format_ext_{
    FORMAT_YUV420P,
    FORMAT_NV12,
    FORMAT_NV21,
    FORMAT_NV16,
    FORMAT_NV61,
    FORMAT_RGB_PLANAR,
    FORMAT_BGR_PLANAR,
    FORMAT_RGB_PACKED,
    FORMAT_BGR_PACKED,
    FORMAT_GRAY,
    FORMAT_COMPRESSED
}bm_image_format_ext;
```

| 格式                  | 说明                               |
| ------------------- | -------------------------------- |
| FORMAT\_YUV420P     | 表示预创建一个YUV420格式的图片，有三个plane      |
| FORMAT\_NV12        | 表示预创建一个NV12格式的图片，有两个plane        |
| FORMAT\_NV21        | 表示预创建一个NV21格式的图片，有两个plane        |
| FORMAT\_RGB\_PLANAR | 表示预创建一个RGB格式的图片，RGB分开排列，有一个plane |
| FORMAT\_BGR\_PLANAR | 表示预创建一个BGR格式的图片，BGR分开排列，有一个plane |
| FORMAT\_RGB\_PACKED | 表示预创建一个RGB格式的图片，RGB交错排列，有一个plane |
| FORMAT\_BGR\_PACKED | 表示预创建一个BGR格式的图片，BGR交错排列，有一个plane |
| FORMAT\_GRAY        | 表示预创建一个灰度图格式的图片，有一个plane         |
| FORMAT\_COMPRESSED  | 表示预创建一个VPU内部压缩格式的图片，有四个plane     |

### **数据存储格式枚举**

```
typedef enum bm_image_data_format_ext_{
    DATA_TYPE_EXT_FLOAT32,
    DATA_TYPE_EXT_1N_BYTE,
    DATA_TYPE_EXT_4N_BYTE,
    DATA_TYPE_EXT_1N_BYTE_SIGNED,
    DATA_TYPE_EXT_4N_BYTE_SIGNED,
}bm_image_data_format_ext;
```

| 数据格式                              | 说明                                      |
| --------------------------------- | --------------------------------------- |
| DATA\_TYPE\_EXT\_FLOAT32          | 表示所创建的图片数据格式为单精度浮点数                     |
| DATA\_TYPE\_EXT\_1N\_BYTE         | 表示所创建图片数据格式为普通带符号1N INT8                |
| DATA\_TYPE\_EXT\_4N\_BYTE         | 表示所创建图片数据格式为4N INT8，即四张带符号INT8图片数据交错排列  |
| DATA\_TYPE\_EXT\_1N\_BYTE\_SIGNED | 表示所创建图片数据格式为普通无符号1N UINT8               |
| DATA\_TYPE\_EXT\_4N\_BYTE         | 表示所创建图片数据格式为4N UINT8，即四张无符号INT8图片数据交错排列 |

​ 关于bm\_image初始化，我们不建议用户直接填充bm\_image结构使用，而是通过以下API来创建/销毁一个bm\_image结构

* **bm\_image\_create\_batch**

  创建物理内存连续的多个bm image。

  ```
   /*
   * @param [in]     handle       handle of low level device             
   * @param [in]     img_h        image height                 
   * @param [in]     img_w        image width
   * @param [in]     img_format   format of image: BGR or YUV
   * @param [in]     data_type    data type of image: INT8 or FP32 
   * @param [out]    image        pointer of bm image object
   * @param [in]     batch_num    batch size
   */
   static inline bool bm_image_create_batch (bm_handle_t              handle,  
                                            int                      img_h,  
                                          int                      img_w,    
                                            bm_image_format_ext      img_format,
                                          bm_image_data_format_ext data_type,  
                                            bm_image                 *image, 
                                            int                      batch_num)
  ```
* **bm\_image\_destroy\_batch**

  释放物理内存连续的多个bm image。要和bm\_image\_create\_batch接口成对使用。

  ```
  /*
  * @param [in]     image        pointer of bm image object
  * @param [in]     batch_num    batch size
  */
  static inline bool bm_image_destroy_batch (bm_image *image, int batch_num)
  ```
* **bm\_image\_alloc\_contiguous\_mem**

  为多个 image 分配连续的内存

  ```
  bm_status_t bm_image_alloc_contiguous_mem(
                  int image_num,
                  bm_image *images,
                  int bmcv_image_usage
  );
  ```

  | 参数                     | 说明                                          |
  | ---------------------- | ------------------------------------------- |
  | int image\_num         | 待分配内存的 image 个数                             |
  | bm\_image \*images     | 待分配内存的 image 的指针                            |
  | int bmcv\_image\_usage | 已经为客户默认设置了参数，（如果客户对于所分配内存位置有要求，可以通过该参数进行制定） |
* **bm\_image\_free\_contiguous\_mem**

  释放通过bm\_image\_alloc\_contiguous\_mem申请的内存

  ```
  bm_status_t bm_image_free_contiguous_mem(
                  int image_num,
                  bm_image *images
          );
  ```

  | 参数                 | 说明               |
  | ------------------ | ---------------- |
  | int image\_num     | 待分配内存的 image 个数  |
  | bm\_image \*images | 待分配内存的 image 的指针 |
* **bmcv\_image\_vpp\_convert**

  bm1684上有专门的视频后处理硬件，满足一定条件下可以一次实现**csc + crop + resize**功能，速度比TPU更快。

  ```
  bmcv_image_vpp_convert(
  bm_handle_t           handle,
        int                   output_num,
        bm_image              input,
        bm_image *            output,
        bmcv_rect_t *         crop_rect,
        bmcv_resize_algorithm algorithm = BMCV_INTER_LINEAR);
  ```

  该API将输入图像格式转化为输出图像格式，并支持crop + resize功能， 支持从1张输入中crop多张输出并resize到输出图片大小。

  | 参数                                                       | 说明                               |
  | -------------------------------------------------------- | -------------------------------- |
  | bm\_handle\_t handle                                     | 设备环境句柄，通过调用bm\_dev\_request获取    |
  | int image\_num                                           | 输bm\_image数量                     |
  | bm\_image input                                          | 输入bm\_image对象                    |
  | bm\_image\* output                                       | 输出bm\_image对象指针                  |
  | bmcv\_rect\_t \*  crop\_rect                             | 每个输出bm\_image对象所对应的在输入图像上crop的参数 |
  | bmcv\_resize\_algorithm algorithm = BMCV\_INTER\_LINEAR) | resize算法选择，默认情况下是双线性差值           |
* **bmcv\_convert\_to**

  实现图像像素线性变化，具体数据关系可用公式表示

  $$
  y= α\*x+ β
  $$

  ```
  bm_status_t bmcv_convert_to (bm_handle_t handle,int input_num,
                          bmcv_convert_to_attr convert_to_attr, 
                          bm_image* input, bm_image* output)
  ```

  | 参数                                        | 说明                                                                                                                                                                    |
  | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
  | bm\_handle\_thandle                       | 输入的bm\_handle句柄                                                                                                                                                       |
  | int    input\_num                         | 输入图片数。最多支持4                                                                                                                                                           |
  | bmcv\_convert\_to\_attr convert\_to\_attr | 每张图片对应的配置参数                                                                                                                                                           |
  | bm\_image\* input                         | 输入bm\_image。每个bm\_image外部需要调用bmcv\_image\_create创建。image内存可以使用bmcv\_image\_dev\_mem\_alloc或者bmcv\_image\_copy\_to\_device来开辟新的内存，或者使用bmcv\_image\_attach来attach已有的内存。 |
  | bm\_image\*output                         | 输出bm\_image。每个bm\_image外部需要调用bmcv\_image\_create创建。image内存可以通过bmcv\_image\_dev\_mem\_alloc来开辟新的内存，或者使用bmcv\_image\_attach来attach已有的内存。如果不主动分配将在api内部进行自行分配            |

  结构体**bmcv\_convert\_to\_attr\_s**

  ```
  typedef struct bmcv_convert_to_attr_s {
      float alpha_0;                 
      float beta_0;  
      float alpha_1;
      float beta_1;
      float alpha_2;
      float beta_2;
  } bmcv_convert_to_attr;
  ```

  | 参数       | 说明                     |
  | -------- | ---------------------- |
  | alpha\_0 | 描述了第0个channel进行线性变换的系数 |
  | beta\_0  | 描述了第0个channel进行线性变换的偏移 |
  | alpha\_1 | 描述了第1个channel进行线性变换的系数 |
  | beta\_1  | 描述了第1个channel进行线性变换的偏移 |
  | alpha\_2 | 描述了第2个channel进行线性变换的系数 |
  | beta\_2  | 描述了第2个channel进行线性变换的偏移 |

  结构体描述了三通道中的alpha和beta。实际要根据推理的输入数据是几通道来进行参数配置。

## 2. python语言编程接口

本章节只介绍了用例py\_ffmpeg\_bmcv\_sail中用的的接口函数

更多接口定义请查阅[**Sophon\_Inference\_zh.pdf**](https://sophon-edge.gitbook.io/sophon-inference/)

* **init**

  ```
  def __init__(handle): 
  """ Constructor.
  Parameters 
  ---------
  handle : sail.Handle Handle instance 
  """
  ```
* **tensor\_to\_bm\_image**

  ```
  def tensor_to_bm_image(tensor): 
  """ Convert tensor to image.
  Parameters 
  ---------
  tensor : sail.Tensor Tensor instance
  Returns 
  ------
  image : sail.BMImage BMImage instance 
  """
  ```
* **convert\_to**

  ```
  def convert_to(input, alpha_beta): 
  """ Applies a linear transformation to an image.
  Parameters
  ---------
  input : sail.BMImage Input image 
  alpha_beta: tuple (a0, b0), (a1, b1), (a2, b2) factors
  Returns 
  ---------
  output : sail.BMImage Output image 
  """
  ```
* **vpp\_resize**

  ```
  def vpp_resize(input, resize_w, resize_h): 
  """ Resize an image with interpolation of INTER_NEAREST using vpp.
  Parameters 
  ---------
  input : sail.BMImage Input image 
  resize_w : int Target width 
  resize_h : int Target height
  Returns 
  ---------
  output : sail.BMImage Output image 
  """
  ```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://1684.gitbook.io/bmnnsdk2-1684-2-0-1/tu-xing-yun-suan-jia-su-mo-kuai.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
