K230 OpenCV开发指南#

1.OpenCV简介#

OpenCV的全称是Open Source Computer Vision Library,是一个跨平台的计算机视觉库。OpenCV是由英特尔公司发起并参与开发,以BSD许可证授权发行,可以在商业和研究领域中免费使用。OpenCV可用于开发实时的图像处理、计算机视觉以及模式识别程序。 嘉楠科技提供了针对K230优化的升级版OpenCV加速库,相比于原始版本OpenCV,可大幅减少OpenCV算子的推理时间。对比示例如下:

算子名称

K230+原始版OpenCV

K230+升级版OpenCV

计算积分图(inter)

34.5ms

7.7ms

仿射变换 (warpaffine)

391.1ms

34.7ms

注意:

上述算子推理时间均在K230大核+1.6GHZ的条件下测试。 计算积分图(inter)算子:输入图像为1280x1080灰度图;积分图类型为32位浮点数。 仿射变换 (warpaffine)算子:输入图像为1280x1080灰度图;顺时针旋转15度,缩放0.6倍;目标图像为1280x1080灰度图;

此外,SDK中已包含预先交叉编译好的升级版OpenCV加速库(位于k230_sdk/src/big/utils/lib/opencv/路径下),用户直接使用该静态库编译自己的可执行程序即可。

2.测试用例编译示例#

本节讲解如何通过SDK中预设的OpenCV静态库,来进行可执行程序的编译。SDK的已包含多个基于OpenCV实现的可执行程序编译示例(位于k230_sdk/src/big/utils/examples/opencv/路径下),本节基于这些示例来进行讲解。该路径下的目录结构说明如下:

|-- 1_opencv_calcHist              # OpenCV示例1
|   |-- CMakeLists.txt             # OpenCV示例1的CMake配置文件
|   `-- opencv_calcHist.cpp        # OpenCV示例1的源码
|-- 2_opencv_threshold             # OpenCV示例2
|   |-- CMakeLists.txt             # OpenCV示例2的CMake配置文件
|   `-- opencv_threshold.cpp       # OpenCV示例2的源码
|-- 3_opencv_findContours
|   |-- CMakeLists.txt
|   `-- opencv_findContours.cpp
|-- 4_opencv_features2d
|   |-- CMakeLists.txt
|   `-- opencv_features2d.cpp
|-- 5_opencv_objdetect
|   |-- CMakeLists.txt
|   `-- opencv_objdetect.cpp
|-- CMakeLists.txt               # 总体CMake配置文件
|-- build_app.sh                 # 总体编译脚本
|-- cmake                        # 默认CMaek配置
|   |-- Riscv64.cmake
|   `-- link.lds
`-- resources                    # OpenCV示例所需的所有输入图片及数据
    |-- 1.bmp
    ...
    |-- a.jpg

首先,运行build_app.sh文件:

./build_app.sh

在终端中出现如下提示,说明可执行程序编译成功:

Install the project...
-- Install configuration: "Release"
-- Installing: /data/zhanglimin/code_kmodel_export_build_inference_k230/k230_sdk/src/big/utils/examples/opencv/out/bin/1_opencv_calcHist.elf
-- Installing: /data/zhanglimin/code_kmodel_export_build_inference_k230/k230_sdk/src/big/utils/examples/opencv/out/bin/2_opencv_threshold.elf
-- Installing: /data/zhanglimin/code_kmodel_export_build_inference_k230/k230_sdk/src/big/utils/examples/opencv/out/bin/3_opencv_findContours.elf
-- Installing: /data/zhanglimin/code_kmodel_export_build_inference_k230/k230_sdk/src/big/utils/examples/opencv/out/bin/4_opencv_features2d.elf
-- Installing: /data/zhanglimin/code_kmodel_export_build_inference_k230/k230_sdk/src/big/utils/examples/opencv/out/bin/5_opencv_objdetect.elf

最后,在k230_sdk/src/big/utils/examples/opencv/out/bin文件夹中即包含了编译好的所有elf文件:

  • 1_opencv_calcHist.elf

  • 2_opencv_threshold.elf

  • 3_opencv_findContours.elf

  • 4_opencv_features2d.elf

  • 5_opencv_objdetect.elf

3.测试用例运行示例#

注意:

所有测试用例运行所需的输入图像数据,均位于SDK的k230_sdk/src/big/utils/examples/opencv/resources路径下。

3.1 opencv_calcHist#

1_opencv_calcHist测试用例的运行方式如下:

msh /sharefs/bin_opencv>./1_opencv_calcHist.elf

1_opencv_calcHist测试用例的运行结果示例如下:

test_opencv_calcHist

其中,左侧为原图像,右侧为3个channel的像素直方图信息。

3.2 opencv_threshold#

2_opencv_threshold测试用例的运行方式如下:

msh /sharefs/bin_opencv>./2_opencv_threshold.elf

2_opencv_threshold测试用例的运行结果示例如下: test_opencv_threshold

其中,左侧为原图像,右侧为阈值化后的图像。

3.3 opencv_findContours#

3_opencv_findContours测试用例的运行方式如下:

msh /sharefs/bin_opencv>./3_opencv_findContours.elf

3_opencv_findContours测试用例的运行结果示例如下: test_opencv_findContours

其中,左侧为原图像,右侧为处理后的轮廓信息图。

3.4 opencv_features2d#

4_opencv_features2d测试用例的运行方式如下:

msh /sharefs/bin_opencv>./4_opencv_features2d.elf

4_opencv_features2d测试用例的运行结果示例如下: test_opencv_features2d 其中,左侧为原图像,右侧为处理后的特征提取结果图。

3.5 opencv_objdetect#

5_opencv_objdetect测试用例的运行方式如下:

msh /sharefs/bin_opencv>./5_opencv_objdetect.elf

5_opencv_objdetect测试用例的运行结果示例如下: test_opencv_objdetect

其中,左侧为原图像,右侧为眼睛和人脸的目标检测结果图。

4.原始版本OpenCV库的交叉编译及使用#

注意:

在第1~3章节中,均基于嘉楠科技提供的K230 加速版OpenCV库进行讲解。若用户希望使用原生的OpenCV库进行应用程序的开发,那可以参考本节内容:首先,通过交叉编译得到原始版本OpenCV的静态库;然后,基于原始版本OpenCV的静态库,进行可执行程序的编译。

4.1 下载OpenCV源码#

首先,使用Github获取OpenCV仓库,由于OpenCV来自于Github,因此克隆速度慢为正常现象,请耐心等待:

git clone https://github.com/opencv/opencv.git

OpenCV中存在着很多版本,这里我们选用最新的版本4.6.0:

# 切换为v4.6.0分支
git checkout tags/4.6.0 -b v4.6.0-branch

4.2 应用patch补丁包#

patch补丁包在SDK中的路径为:k230_sdk/src/big/rt-smart/userapps/opencv/v4.6.0

首先,在OpenCV根目录下新建patch文件夹,并将补丁包放入patch文件夹中。放置好的目录结构示例如下:

|-- 3rdparty
|-- patch # opencv 的 补 丁 包
| |-- 0001-****.patch
| |-- 0002-****.patch
| |-- 0003-****.patch
...
| |-- 0011-****.patch
| |-- 0017-****.patch
| |-- 0018-****.patch
|-- CMakeLists.txt
...
|-- include
|-- modules
|-- platforms
|-- samples

然后,在OpenCV根目录下执行以下命令应用补丁:

git am ./patch/*.patch

此时,打完补丁的OpenCV目录结构示例如下:

|-- 3rdparty
|-- patch
|-- CMakeLists.txt
...
|-- apps
|-- build.sh
|-- cmake
|-- data
|-- doc
|-- include
|-- modules
|-- platforms
| |-- android
...
| |-- rt_smart
| | `-- riscv64-gcc.toolchain.cmake # rt_smart平台的编译配置文件
| |-- scripts
| |-- semihosting
| |-- wince
| |-- winpack_dldt
| `-- winrt
|-- samples
`-- version

4.3 交叉编译OpenCV静态库#

首先,检查build.sh文件中的工具链路径是否正确:

# 注意:`toolchain_path` 会随开发者具体环境不同,路径前缀会有所不同,仅供参考。
toolchain_path=~/.tools/gnu_gcc/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin
c_compiler=${toolchain_path}/riscv64-unknown-linux-musl-gcc
cxx_compiler=${toolchain_path}/riscv64-unknown-linux-musl-g++

cmake .. -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE="../platforms/rt_smart/riscv64-rvv-gcc.toolchain.cmake" \
-DCMAKE_C_COMPILER=$c_compiler \
-DCMAKE_CXX_COMPILER=$cxx_compiler

然后,创建文件夹build,在build目录中执行以下命令即可:

source ../build.sh
make -j$(nproc)
make install

在编译过程中,若终端未出现告警信息,则说明编译成功,编译完成的产物在build/install中,其中包含了原始版本OpenCV的静态库文件。

4.4 编译可执行程序#

本小节通过对第2节中的测试用例进行修改,来说明如何基于原始版本OpenCV库来实现可执行程序的编译。 首先,把原始版本的OpenCV库拷贝到k230_sdk/src/big/utils/lib/下并将文件夹命名为opencv_rtt。 然后,删除加速版OpenCV库,并将原始版本OpenCV库进行软链接:

cd k230_sdk/src/big/utils/lib/opencv_rtt
rm opencv
ln -s opencv_rtt opencv

然后,修改各个示例文件夹内(例如1_opencv_calcHist文件夹)下CMakeLists.txt文件,对链接的静态库内容进行修改,删除对csi_cv库的链接:

# 加速版OpenCV库,采用如下链接设置
target_link_libraries(${bin} opencv_imgcodecs opencv_imgproc opencv_core libjpeg-turbo libopenjp2 libpng libtiff libwebp zlib csi_cv)
# 原始版OpenCV库,改为如下链接设置
target_link_libraries(${bin} opencv_imgcodecs opencv_imgproc opencv_core libjpeg-turbo libopenjp2 libpng libtiff libwebp zlib)

最后,其余步骤(如程序的编译及运行)均与加速版本OpenCV保持一致。