> ## Documentation Index
> Fetch the complete documentation index at: https://dragonwingdocs.qualcomm.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 评估 FastCV 加速

## **如何衡量 FastCV HAL 与 OpenCV 的性能对比**

使用以下任一选项编译构建

* 要启用 FastCV 加速，使用 `-DWITH_FASTCV=ON` 选项
* 要在 CPU 上使用默认 OpenCV，使用 `-DWITH_FASTCV=OFF` 选项

<Note>
  **注意**

  默认情况下已启用基于 FastCV 的 OpenCV 加速。
</Note>

编译完成后，烧录构建并启动设备。所有库都位于 `/usr/lib/` 目录中。

1. 将测试二进制文件复制到 `/usr/bin` 以运行测试。
   ```bash theme={null}
   scp -r opencv_perf_core root@[IP-address]:/usr/bin/
   ```
2. 如果之前未复制过测试数据，请将其复制到设备上。

   要获取测试数据，请克隆 [https://github.com/opencv/opencv\_extra/tree/4.13.0](https://github.com/opencv/opencv_extra/tree/4.13.0) 上的项目。

   使用 `scp` 命令将测试数据推送到主机上的目标位置。例如：

   ```bash theme={null}
   scp -r [file] root@[IP-ADDR]:/tmp
   ```
3. 要在目标设备上开始测试，请运行以下命令。
   ```bash theme={null}
   cd /usr/bin/
   chmod 777 opencv_perf*
   export OPENCV_OPENCL_RUNTIME=disabled && export OPENCV_TEST_DATA_PATH=/tmp && /usr/bin/opencv_perf_core --gtest_filter=ArithmMixedTest.subtract/2 --perf_min_samples=100 --perf_force_samples=100 >> results_Arithm.txt
   ```

上述命令针对 subtract API 运行不同的测试用例，每个测试用例循环执行 100 次。

结果收集在 `results_Arithm.txt` 文本文件中。

`results_Arithm.txt` 包含各测试用例的详细信息，包括测试名称、样本数、分辨率、平均时间、通过/失败状态。对于以下启用了 FastCV 加速的测试用例，总耗时为 **16 毫秒**。

<img src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-prod/zh/Technologies/Vision/images/testing-fastcv-results.png" alt="FastCV 性能结果" />

使用默认 OpenCV 时，同一测试用例的总耗时为 23 毫秒。

<img src="https://mintlify.s3.us-west-1.amazonaws.com/qualcomm-prod/zh/Technologies/Vision/images/testing-opencv-results.png" alt="OpenCV 性能结果" />

运行其他测试用例，并比较默认 OpenCV 与 FastCV 加速的 OpenCV 之间的延迟数据。

## **支持的 OpenCV API 及对应的 FastCV API**

<Card>
  <b style={{fontSize: "1.1rem", display: "block", textAlign: "center"}}>支持的 OpenCV API</b>

  <table>
    <thead>
      <tr>
        <th style={{color: "white", fontWeight: "bold"}}>OpenCV 模块</th>
        <th style={{color: "white", fontWeight: "bold"}}>OpenCV API</th>
        <th style={{color: "white", fontWeight: "bold"}}>用于 OpenCV 加速的底层 FastCV API</th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <td rowspan="19">IMGPROC</td>
        <td>medianBlur</td>
        <td>fcvFilterMedian3x3u8\_v3</td>
      </tr>

      <tr><td>sobel</td><td>fcvFilterSobel3x3u8s16</td></tr>
      <tr><td>sobel</td><td>fcvFilterSobel5x5u8s16</td></tr>
      <tr><td>sobel</td><td>fcvFilterSobel7x7u8s16</td></tr>
      <tr><td>boxFilter</td><td>fcvBoxFilter3x3u8\_v3</td></tr>
      <tr><td>boxFilter</td><td>fcvBoxFilter5x5u8\_v2</td></tr>
      <tr><td>adaptiveThreshold</td><td>fcvAdaptiveThresholdGaussian3x3u8\_v2</td></tr>
      <tr><td>adaptiveThreshold</td><td>fcvAdaptiveThresholdGaussian5x5u8\_v2</td></tr>
      <tr><td>adaptiveThreshold</td><td>fcvAdaptiveThresholdMean3x3u8\_v2</td></tr>
      <tr><td>adaptiveThreshold</td><td>fcvAdaptiveThresholdMean5x5u8\_v2</td></tr>
      <tr><td>subtract</td><td>fcvImageDiffu8f32\_v2</td></tr>
      <tr><td>pyrDown</td><td>fcvPyramidCreateu8\_v4</td></tr>
      <tr><td>cvtColor</td><td>fcvColorRGB888toYCrCbu8\_v3</td></tr>
      <tr><td>cvtColor</td><td>fcvColorRGB888ToHSV888u8</td></tr>
      <tr><td>GaussianBlur</td><td>fcvFilterGaussian5x5u8\_v3</td></tr>
      <tr><td>GaussianBlur</td><td>fcvFilterGaussian3x3u8\_v4</td></tr>
      <tr><td>cvWarpPerspective</td><td>fcvWarpPerspectiveu8\_v5</td></tr>
      <tr><td>Canny</td><td>fcvFilterCannyu8</td></tr>
      <tr><td>boxFilter</td><td>fcvBoxFilterNxNf32</td></tr>

      <tr>
        <td rowspan="20">CORE</td>
        <td>lut</td>
        <td>fcvTableLookupu8</td>
      </tr>

      <tr><td>norm</td><td>fcvHammingDistanceu8</td></tr>
      <tr><td>multiply</td><td>fcvElementMultiplyu8u16\_v2</td></tr>
      <tr><td>multiply</td><td>fcvElementMultiplyu8</td></tr>
      <tr><td>multiply</td><td>fcvElementMultiplys16</td></tr>
      <tr><td>multiply</td><td>fcvElementMultiplyf32</td></tr>
      <tr><td>transpose</td><td>fcvTransposeu8\_v2</td></tr>
      <tr><td>transpose</td><td>fcvTransposeu16\_v2</td></tr>
      <tr><td>transpose</td><td>fcvTransposef32\_v2</td></tr>
      <tr><td>meanStdDev</td><td>fcvImageIntensityStats\_v2</td></tr>
      <tr><td>flip</td><td>fcvFlipu8</td></tr>
      <tr><td>flip</td><td>fcvFlipu16</td></tr>
      <tr><td>flip</td><td>fcvFlipRGB888u8</td></tr>
      <tr><td>rotate</td><td>fcvRotateImageu8</td></tr>
      <tr><td>rotate</td><td>fcvRotateImageInterleavedu8</td></tr>
      <tr><td>addWeighted</td><td>fcvAddWeightedu8\_v2</td></tr>
      <tr><td>SVD</td><td>fcvSVDf32\_v2</td></tr>
      <tr><td>Gemm</td><td>fcvMatrixMultiplyf32\_v2</td></tr>
      <tr><td>Gemm</td><td>fcvMultiplyScalarf32</td></tr>
      <tr><td>Gemm</td><td>fcvAddf32\_v2</td></tr>
    </tbody>
  </table>
</Card>

<Card>
  <b style={{fontSize: "1.1rem", display: "block", textAlign: "center"}}>FastCV CPU 扩展</b>

  <table>
    <thead>
      <tr>
        <th style={{color: "white", fontWeight: "bold"}}>OpenCV 扩展 API</th>
        <th style={{color: "white", fontWeight: "bold"}}>使用的 FastCV API</th>
        <th style={{color: "white", fontWeight: "bold"}}>描述</th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <td rowspan="5">arithmetic\_op</td>
        <td>fcvAddu8</td>
        <td>将两个 uint8\_t 类型矩阵相加得到一个 uint8\_t 矩阵</td>
      </tr>

      <tr><td>fcvAddf32\_v2</td><td>两个 float32\_t 类型矩阵的矩阵加法。</td></tr>
      <tr><td>fcvAdds16\_v2</td><td>两个 int16\_t 类型矩阵的矩阵加法，支持原地操作</td></tr>
      <tr><td>fcvSubtracts16</td><td>两个 uint16\_t 类型矩阵的矩阵减法</td></tr>
      <tr><td>fcvSubtractu8</td><td>两个 uint8\_t 类型矩阵的矩阵减法</td></tr>

      <tr>
        <td rowspan="3">bilateralFilter</td>
        <td>fcvBilateralFilter5x5u8\_v3</td>
        <td>使用 5x5 双边核进行双边平滑</td>
      </tr>

      <tr><td>fcvBilateralFilter7x7u8\_v3</td><td>使用 7x7 双边核进行双边平滑</td></tr>
      <tr><td>fcvBilateralFilter9x9u8\_v3</td><td>使用 9x9 双边核进行双边平滑</td></tr>
      <tr><td>bilateralRecursive</td><td>fcvBilateralFilterRecursiveu8</td><td>此处的平滑实际是在梯度域中执行的。</td></tr>

      <tr>
        <td rowspan="3">buildPyramid</td>
        <td>fcvPyramidAllocate\_v3</td>
        <td>为图像金字塔分配内存。此 API 可能在不另行通知的情况下被移除，仅应用于测试。</td>
      </tr>

      <tr><td>fcvPyramidCreateu8\_v4</td><td>从 8 位无符号（灰度）源图像创建图像金字塔。</td></tr>
      <tr><td>fcvPyramidDelete\_v2</td><td>释放 fcvPyramidLevel 数组。可用于任何类型（f32/s8/u8）。</td></tr>
      <tr><td>calcHist</td><td>fcvImageIntensityHistogram</td><td>为灰度图像的矩形区域创建强度直方图。</td></tr>
      <tr><td>clusterEuclidean</td><td>fcvClusterEuclideanu8</td><td>用于计算聚类中心和聚类绑定的通用函数</td></tr>

      <tr>
        <td rowspan="18">cvtColor</td>
        <td>fcvColorYCbCr420PseudoPlanarToYCbCr444PseudoPlanaru8</td>
        <td>从伪平面 YCbCr420 到伪平面 YCbCr444 的颜色转换。</td>
      </tr>

      <tr><td>fcvColorYCbCr420PseudoPlanarToYCbCr422PseudoPlanaru8</td><td>从伪平面 YCbCr420 到伪平面 YCbCr422 的颜色转换。</td></tr>
      <tr><td>fcvColorYCbCr422PseudoPlanarToYCbCr444PseudoPlanaru8</td><td>从伪平面 YCbCr422 到伪平面 YCbCr444 的颜色转换。</td></tr>
      <tr><td>fcvColorYCbCr422PseudoPlanarToYCbCr420PseudoPlanaru8</td><td>从伪平面 YCbCr422 到伪平面 YCbCr420 的颜色转换。</td></tr>
      <tr><td>fcvColorYCbCr444PseudoPlanarToYCbCr422PseudoPlanaru8</td><td>从伪平面 YCbCr444 到伪平面 YCbCr422 的颜色转换。</td></tr>
      <tr><td>fcvColorYCbCr444PseudoPlanarToYCbCr420PseudoPlanaru8</td><td>从伪平面 YCbCr444 到伪平面 YCbCr420 的颜色转换。</td></tr>
      <tr><td>fcvColorRGB565ToYCbCr444PseudoPlanaru8</td><td>从 RGB565 到伪平面 YCbCr444 的颜色转换。</td></tr>
      <tr><td>fcvColorRGB565ToYCbCr422PseudoPlanaru8</td><td>从 RGB565 到伪平面 YCbCr422 的颜色转换。</td></tr>
      <tr><td>fcvColorRGB565ToYCbCr420PseudoPlanaru8</td><td>从 RGB565 到伪平面 YCbCr420 的颜色转换。</td></tr>
      <tr><td>fcvColorRGB888ToYCbCr444PseudoPlanaru8</td><td>从 RGB888 到伪平面 YCbCr444 的颜色转换。</td></tr>
      <tr><td>fcvColorRGB888ToYCbCr422PseudoPlanaru8</td><td>从 RGB888 到伪平面 YCbCr422 的颜色转换。</td></tr>
      <tr><td>fcvColorRGB888ToYCbCr420PseudoPlanaru8</td><td>从 RGB888 到伪平面 YCbCr420 的颜色转换。</td></tr>
      <tr><td>fcvColorYCbCr420PseudoPlanarToRGB565u8</td><td>从伪平面 YCbCr420 到 RGB565 的颜色转换。</td></tr>
      <tr><td>fcvColorYCbCr422PseudoPlanarToRGB565u8</td><td>从伪平面 YCbCr422 到 RGB565 的颜色转换。</td></tr>
      <tr><td>fcvColorYCbCr422PseudoPlanarToRGB888u8</td><td>从伪平面 YCbCr422 到 RGB888 的颜色转换。</td></tr>
      <tr><td>fcvColorYCbCr422PseudoPlanarToRGBA8888u8</td><td>从伪平面 YCbCr422 到 RGBA8888 的颜色转换。</td></tr>
      <tr><td>fcvColorYCbCr444PseudoPlanarToRGB565u8</td><td>从伪平面 YCbCr444 到 RGB565 的颜色转换。</td></tr>
      <tr><td>fcvColorYCbCr444PseudoPlanarToRGB888u8</td><td>从伪平面 YCbCr444 到 RGB888 的颜色转换。</td></tr>
      <tr><td>DCT</td><td>fcvDCTu8</td><td>对 uint8\_t 像素执行正向离散余弦变换</td></tr>

      <tr>
        <td rowspan="4">FAST10</td>
        <td>fcvCornerFast10InMaskScoreu8</td>
        <td>基于掩码从图像中提取 FAST 角点和评分。</td>
      </tr>

      <tr><td>fcvCornerFast10InMasku8</td><td>从图像中提取 FAST 角点。</td></tr>
      <tr><td>fcvCornerFast10Scoreu8</td><td>从图像中提取 FAST 角点和评分</td></tr>
      <tr><td>fcvCornerFast10u8</td><td>从图像中提取 FAST 角点。</td></tr>
      <tr><td>FFT</td><td>fcvFFTu8</td><td>计算实值矩阵的一维或二维快速傅里叶变换。</td></tr>
      <tr><td>fillConvexPoly</td><td>fcvFillConvexPolyu8</td><td>此函数使用指定的颜色填充凸多边形的内部。</td></tr>

      <tr>
        <td rowspan="3">filter2D</td>
        <td>fcvFilterCorrNxNu8</td>
        <td>使用不可分离核的 NxN 相关运算。此函数忽略边界值。</td>
      </tr>

      <tr><td>fcvFilterCorrNxNu8s16</td><td>使用不可分离核的 NxN 相关运算。此函数忽略边界值。</td></tr>
      <tr><td>fcvFilterCorrNxNu8f32</td><td>使用不可分离核的 NxN 相关运算。此函数忽略边界值。</td></tr>

      <tr>
        <td rowspan="5">gaussianBlur</td>
        <td>fcvFilterGaussian3x3u8\_v4</td>
        <td>使用 3x3 高斯滤波器对图像进行模糊，边界处理方式由用户指定</td>
      </tr>

      <tr><td>fcvFilterGaussian5x5u8\_v3</td><td>使用 5x5 高斯滤波器对图像进行模糊</td></tr>
      <tr><td>fcvFilterGaussian5x5s16\_v3</td><td>使用 5x5 高斯滤波器对图像进行模糊</td></tr>
      <tr><td>fcvFilterGaussian5x5s32\_v3</td><td>使用 5x5 高斯滤波器对图像进行模糊</td></tr>
      <tr><td>fcvFilterGaussian11x11u8\_v2</td><td>使用 11x11 高斯滤波器对图像进行模糊</td></tr>
      <tr><td>houghLines</td><td>fcvHoughLineu8</td><td>执行霍夫直线检测</td></tr>
      <tr><td>iDCT</td><td>fcvIDCTs16</td><td>对 int16\_t 系数执行逆离散余弦变换</td></tr>
      <tr><td>IFFT</td><td>fcvIFFTf32</td><td>计算复值矩阵的一维或二维快速傅里叶逆变换。</td></tr>
      <tr><td>integrateImageYUV</td><td>fcvIntegrateImageYCbCr420PseudoPlanaru8</td><td>此函数计算 YCbCr420 图像的积分图，其中输入 YCbCr420 的 UV 是交错排列的。</td></tr>
      <tr><td>matmuls8s32</td><td>fcvMatrixMultiplys8s32</td><td>两个 int8\_t 类型矩阵的矩阵乘法</td></tr>

      <tr>
        <td rowspan="3">meanShift</td>
        <td>fcvMeanShiftu8</td>
        <td>应用 meanshift 过程并获得最终收敛位置。源图像必须是 8 位灰度图像。</td>
      </tr>

      <tr><td>fcvMeanShifts32</td><td>应用 meanshift 过程并获得最终收敛位置。源图像必须是 32 位整型灰度图像。</td></tr>
      <tr><td>fcvMeanShiftf32</td><td>应用 meanshift 过程并获得最终收敛位置。源图像必须是 32 位浮点灰度图像。</td></tr>

      <tr>
        <td rowspan="3">Merge</td>
        <td>fcvChannelCombine2Planesu8</td>
        <td>以交错方式合并两个通道</td>
      </tr>

      <tr><td>fcvChannelCombine3Planesu8</td><td>以交错方式合并三个通道</td></tr>
      <tr><td>fcvChannelCombine4Planesu8</td><td>以交错方式合并四个通道</td></tr>

      <tr>
        <td rowspan="3">moments</td>
        <td>fcvImageMomentsu8</td>
        <td>计算图像像素强度的加权平均（矩）。输入必须为 8 位图像数据。</td>
      </tr>

      <tr><td>fcvImageMomentss32</td><td>计算图像像素强度的加权平均（矩）。输入必须为 int32\_t 数据类型。</td></tr>
      <tr><td>fcvImageMomentsf32</td><td>计算图像像素强度的加权平均（矩）。输入必须为 float32\_t 数据类型。</td></tr>

      <tr>
        <td rowspan="2">NormalizeLocalBox</td>
        <td>fcvNormalizeLocalBoxu8</td>
        <td>计算图像的局部减法和对比度归一化。</td>
      </tr>

      <tr><td>fcvNormalizeLocalBoxf32</td><td>计算图像的局部减法和对比度归一化。</td></tr>
      <tr><td>remap</td><td>fcvRemapu8\_v2</td><td>对灰度 CV\_8UC1 图像应用通用几何变换。</td></tr>

      <tr>
        <td rowspan="2">remapRGBA</td>
        <td>fcvRemapRGBA8888BLu8</td>
        <td>使用双线性插值对 4 通道 CV\_8UC4 图像应用通用几何变换</td>
      </tr>

      <tr><td>fcvRemapRGBA8888NNu8</td><td>使用最近邻插值对 4 通道 CV\_8UC4 图像应用通用几何变换</td></tr>
      <tr><td>resizeDownBy2</td><td>fcvScaleDownBy2u8\_v2</td><td>通过对每个 2x2 像素块求平均对图像进行降采样</td></tr>
      <tr><td>resizeDownBy4</td><td>fcvScaleDownBy4u8\_v2</td><td>通过对每个 4x4 像素块求平均对图像进行降采样</td></tr>

      <tr>
        <td rowspan="2">ResizeDown</td>
        <td>FcvScaleDownMNu8</td>
        <td>使用 MN 方法进行图像降采样</td>
      </tr>

      <tr><td>fcvScaleDownMNInterleaveu8</td><td>使用 MN 方法对交错图像进行降采样</td></tr>

      <tr>
        <td rowspan="6">runMSER</td>
        <td>fcvMserInit</td>
        <td>初始化 MSER 的函数。</td>
      </tr>

      <tr><td>fcvMserNN8Init</td><td>初始化 8 邻域 MSER 的函数</td></tr>
      <tr><td>fcvMserExtu8\_v3</td><td>以更小内存占用调用 MSER 的函数，可（可选地）输出轮廓边界框及附加信息。</td></tr>
      <tr><td>fcvMserExtNN8u8</td><td>调用 8 邻域 MSER 的函数，并为每个轮廓提供附加输出。</td></tr>
      <tr><td>fcvMserNN8u8</td><td>调用 8 邻域 MSER 的函数。</td></tr>
      <tr><td>fcvMserRelease</td><td>释放 MSER 资源的函数。</td></tr>

      <tr>
        <td rowspan="7">sepFilter2D</td>
        <td>fcvFilterCorrSepMxNu8</td>
        <td>使用可分离核的 MxN 相关运算。</td>
      </tr>

      <tr><td>fcvFilterCorrSep9x9s16\_v2</td><td>使用可分离核的 9x9 FIR 滤波器（卷积）。</td></tr>
      <tr><td>fcvFilterCorrSep11x11s16\_v2</td><td>使用可分离核的 11x11 FIR 滤波器（卷积）。</td></tr>
      <tr><td>fcvFilterCorrSep13x13s16\_v2</td><td>使用可分离核的 13x13 相关运算。</td></tr>
      <tr><td>fcvFilterCorrSep15x15s16\_v2</td><td>使用可分离核的 15x15 相关运算。</td></tr>
      <tr><td>fcvFilterCorrSep17x17s16\_v2</td><td>使用可分离核的 17x17 相关运算。</td></tr>
      <tr><td>fcvFilterCorrSepNxNs16</td><td>使用可分离核的 NxN 相关运算。</td></tr>

      <tr>
        <td rowspan="4">sobel</td>
        <td>fcvFilterSobel3x3u8\_v2</td>
        <td>3x3 Sobel 边缘滤波器</td>
      </tr>

      <tr><td>fcvFilterSobel3x3u8s16</td><td>从源亮度数据创建未归一化的 2D 梯度图像。使用 3x3 Sobel 核进行卷积。</td></tr>
      <tr><td>fcvFilterSobel5x5u8s16</td><td>从源亮度数据创建未归一化的 2D 梯度图像。使用 5x5 Sobel 核进行卷积。</td></tr>
      <tr><td>fcvFilterSobel7x7u8s16</td><td>从源亮度数据创建未归一化的 2D 梯度图像。使用 7x7 Sobel 核进行卷积。</td></tr>

      <tr>
        <td rowspan="10">sobelPyramid</td>
        <td>fcvPyramidAllocate</td>
        <td>为金字塔分配内存</td>
      </tr>

      <tr><td>fcvPyramidAllocate\_v2</td><td>为金字塔分配内存</td></tr>
      <tr><td>fcvPyramidAllocate\_v3</td><td>为金字塔分配内存</td></tr>
      <tr><td>fcvPyramidSobelGradientCreatei8</td><td>从 uint8\_t 图像金字塔创建 integer8 梯度金字塔</td></tr>
      <tr><td>fcvPyramidSobelGradientCreatei16</td><td>从 uint8\_t 图像金字塔创建 int16\_t 梯度金字塔</td></tr>
      <tr><td>fcvPyramidSobelGradientCreatef32</td><td>从 uint8\_t 图像金字塔创建 float32 梯度金字塔</td></tr>
      <tr><td>fcvPyramidDelete</td><td>释放 fcvPyramidLevel 数组。可用于任何类型（f32/s8/u8）。</td></tr>
      <tr><td>fcvPyramidDelete\_v2</td><td>释放 fcvPyramidLevel 数组。可用于任何类型（f32/s8/u8）。</td></tr>
      <tr><td>fcvPyramidCreatef32\_v2</td><td>构建图像金字塔（带步幅）。内存应使用 fcvPyramidDelete\_v2 释放</td></tr>
      <tr><td>fcvPyramidCreateu8\_v4</td><td>构建高斯图像金字塔。</td></tr>
      <tr><td>sobel3x3u8</td><td>fcvImageGradientSobelPlanars8\_v2</td><td>使用 3x3 邻域和 Sobel 核从源亮度数据创建 2D 梯度图像</td></tr>
      <tr><td>sobel3x3u9</td><td>fcvImageGradientSobelPlanars16\_v2</td><td>使用 3x3 邻域和 Sobel 核从源亮度数据创建 2D 梯度图像</td></tr>
      <tr><td>sobel3x3u10</td><td>fcvImageGradientSobelPlanars16\_v3</td><td>使用 3x3 邻域和 Sobel 核从源亮度数据创建 2D 梯度图像</td></tr>
      <tr><td>sobel3x3u11</td><td>fcvImageGradientSobelPlanarf32\_v2</td><td>使用 3x3 邻域和 Sobel 核从源亮度数据创建 2D 梯度图像</td></tr>
      <tr><td>sobel3x3u12</td><td>fcvImageGradientSobelPlanarf32\_v3</td><td>使用 3x3 邻域和 Sobel 核从源亮度数据创建 2D 梯度图像</td></tr>

      <tr>
        <td rowspan="2">split</td>
        <td>fcvDeinterleaveu8</td>
        <td>对无符号字节数据执行图像去交错。</td>
      </tr>

      <tr><td>fcvChannelExtractu8</td><td>从交错或多平面图像格式中将通道提取为单个 uint8\_t 类型平面</td></tr>
      <tr><td>thresholdRange</td><td>fcvFilterThresholdRangeu8\_v2</td><td>基于一对阈值对灰度图像进行二值化。</td></tr>

      <tr>
        <td rowspan="2">trackOpticalFlowLK</td>
        <td>fcvTrackLKOpticalFlowu8\_v3</td>
        <td>光流（带步幅，因此可支持 ROI）</td>
      </tr>

      <tr><td>fcvTrackLKOpticalFlowu8</td><td>光流。位宽优化实现</td></tr>
      <tr><td>warpAffine</td><td>fcvTransformAffineClippedu8\_v3</td><td>使用 2x3 矩阵对灰度图像应用仿射变换。</td></tr>
      <tr><td>warpAffine3Plane</td><td>fcv3ChannelTransformAffineClippedBCu8</td><td>使用 2x3 矩阵和双三次插值对 3 色通道图像应用仿射变换。</td></tr>
      <tr><td>warpPatchAffine</td><td>fcvTransformAffineu8\_v2</td><td>使用 nAffine 中的仿射变换对输入图像中以 nPos 为中心的图像块进行变形</td></tr>
      <tr><td>warpPerspective</td><td>fcvWarpPerspectiveu8\_v5</td><td>使用透视投影变换矩阵（也称为单应矩阵）对灰度图像进行变形。</td></tr>
      <tr><td>warpPerspective2Plane</td><td>fcv2PlaneWarpPerspectiveu8</td><td>使用同一变换对两幅图像进行透视变形。</td></tr>
    </tbody>
  </table>
</Card>

<Card>
  <b style={{fontSize: "1.1rem", display: "block", textAlign: "center"}}>FastCV QDSP 扩展</b>

  <table>
    <thead>
      <tr>
        <th style={{color: "white", fontWeight: "bold"}}>OpenCV 扩展 API</th>
        <th style={{color: "white", fontWeight: "bold"}}>使用的 FastCV API</th>
        <th style={{color: "white", fontWeight: "bold"}}>描述</th>
      </tr>
    </thead>

    <tbody>
      <tr>
        <td>Canny</td>
        <td>fcvFilterCannyu8Q</td>
        <td>提供更多算法配置控制的 Canny 边缘检测。</td>
      </tr>

      <tr>
        <td>fcvdspinit</td>
        <td>fcvQ6Init</td>
        <td>初始化 FastCV DSP 环境。</td>
      </tr>

      <tr>
        <td>fcvdspdeinit</td>
        <td>fcvQ6DeInit</td>
        <td>反初始化 FastCV DSP 环境。</td>
      </tr>

      <tr>
        <td>FFT</td>
        <td>fcvFFTu8Q</td>
        <td>计算实值矩阵的一维或二维快速傅里叶变换。</td>
      </tr>

      <tr>
        <td rowspan="4">filter2D</td>
        <td>fcvFilterCorr3x3s8\_v2Q</td>
        <td>使用不可分离核的 3x3 相关运算。</td>
      </tr>

      <tr>
        <td>fcvFilterCorrNxNu8Q</td>
        <td>使用不可分离核的 NxN 相关运算。此函数忽略边界值。</td>
      </tr>

      <tr>
        <td>fcvFilterCorrNxNu8s16Q</td>
        <td>使用不可分离核的 NxN 相关运算。此函数忽略边界值。</td>
      </tr>

      <tr>
        <td>fcvFilterCorrNxNu8f32Q</td>
        <td>使用不可分离核的 NxN 相关运算。此函数忽略边界值。</td>
      </tr>

      <tr>
        <td>IFFT</td>
        <td>fcvIFFTf32Q</td>
        <td>计算复值矩阵的一维或二维快速傅里叶逆变换。</td>
      </tr>

      <tr>
        <td>sumOfAbsoluteDiffs</td>
        <td>fcvSumOfAbsoluteDiffs8x8u8\_v2Q</td>
        <td>图像相对于 8x8 模板的绝对差之和。</td>
      </tr>

      <tr>
        <td>thresholdOtsu</td>
        <td>fcvFilterThresholdOtsuu8Q</td>
        <td>使用 Otsu 方法对灰度图像进行二值化。</td>
      </tr>
    </tbody>
  </table>
</Card>

有关 FastCV 扩展的详细信息，请参阅[该扩展的文档](https://docs.opencv.org/4.x/dc/db8/group__fastcv.html)

## **启用或禁用 FastCV 加速**

**启用**

如下所示，在 OpenCV BitBake 文件的 **EXTRA\_OECMAKE** 选项中包含 **-DWITH\_FASTCV=ON** 来启用 FastCV HAL 加速。

该标志允许使用 FastCV HAL 编译 OpenCV API。

```bash theme={null}
DEPENDS:qcom-custom-bsp += "qcom-fastcv-binaries"

EXTRA_OECMAKE += "-DOPENCV_ALLOW_DOWNLOADS=ON"
EXTRA_OECMAKE:append:qcom-custom-bsp = " -DWITH_FASTCV=ON "
#python () {
```

**禁用**

如下所示，在 OpenCV BitBake 文件的 `EXTRA_OECMAKE` 选项中包含 **-DWITH\_FASTCV=OFF** 来禁用 FastCV HAL 加速，然后使用 devtool 方法重新编译 OpenCV 配方。

```bash theme={null}
DEPENDS:qcom-custom-bsp += "qcom-fastcv-binaries"

EXTRA_OECMAKE:append:qcom-custom-bsp = " -DWITH_FASTCV=OFF "
#python () {
#    bsp_type = d.getVar('BSP_TYPE')
```

以下展示了该标志如何包含在 CMakeLists 文件中（`opencv/3rdparty/fastcv/CMakeLists.txt`）：

```cmake theme={null}
if(NOT WITH_FASTCV OR NOT FASTCV_DIR)
   message(STATUS "FastCV is not available, disabling related HAL and stuff")
   return()
endif()

if(NOT ANDROID AND NOT UNIX)
   message(FATAL_ERROR "FastCV HAL supports Android and UNIX only!")
endif()

set(OPENCV_3P_FASTCV_DIR ${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(hal)
```

以下示例是使用 FastCV API 实现的 FastCV HAL API 之一。

`opencv/3rdparty/fastcv/src/fastcv_hal_core.cpp`

```cpp theme={null}
int fastcv_hal_sub8u32f(
    const uchar*    src1_data,
    size_t          src1_step,
    const uchar*    src2_data,
    size_t          src2_step,
    float*          dst_data,
    size_t          dst_step,
    int             width,
    int             height)
{
    INITIALIZATION_CHECK;

    fcvStatus status = FASTCV_SUCCESS;

    if (src1_step < width && src2_step < width)
    {
       src1_step = width*sizeof(uchar);
       src2_step = width*sizeof(uchar);
       dst_step  = width*sizeof(float);
    }

    status = fcvImageDiffu8f32_v2(src1_data, src2_data, width, height, src1_step,
                                  src2_step, dst_data, dst_step);

    CV_HAL_RETURN(status,hal_subtract);
}
```
