# OpenCV 测试应用程序

本节介绍了如何启用 OpenCV 库并运行 OpenCV 测试应用程序

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Generated by Microsoft Visio, SVG Export getting-started-workflow.svg getting-started-workflow -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="9.38542in" height="2.16667in" viewbox="0 0 675.75 156" xml:space="preserve" color-interpolation-filters="sRGB" class="st11" aria-label="../_images/getting-started-workflow.svg" svgdefaultwidth="75%"><v:documentproperties v:langid="1033" v:viewmarkup="false">	<v:userdefs>		<v:ud v:nameu="msvNoAutoConnect" v:val="VT0(1):26"></v:ud>	</v:userdefs></v:documentproperties>
<style>.svg-1 .st1 { fill: #fafafa; stroke: #d2d7e1; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1 }
.svg-1 .st2 { fill: #6280cc; stroke: #6280cc; stroke-linecap: round; stroke-linejoin: round; stroke-width: 0.75 }
.svg-1 .st3 { fill: #ffffff; font-family: SimHei; font-size: 1.16666em }
.svg-1 .st4 { fill: #ffffff; stroke: #ffffff; stroke-linecap: round; stroke-linejoin: round; stroke-width: 0.75 }
.svg-1 .st5 { fill: #000000; font-family: Symbol; font-size: 1.00001em }
.svg-1 .st6 { font-size: 1em }
.svg-1 .st7 { font-family: SimHei; font-size: 1em }
.svg-1 .st8 { font-family: Arial; font-size: 1em }
.svg-1 .st9 { marker-end: url("#mrkr13-27"); stroke: #000000; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1.5 }
.svg-1 .st10 { fill: #000000; fill-opacity: 1; stroke: #000000; stroke-opacity: 1; stroke-width: 0.37313432835821 }
.svg-1 .st11 { fill: none; fill-rule: evenodd; font-size: 12px; overflow: visible; stroke-linecap: square; stroke-miterlimit: 3 }</style>
<defs id="Markers">	<g id="lend13">		<path d="M 3 1 L 0 0 L 3 -1 L 3 1 " style="stroke:none"></path>	</g>	<marker id="mrkr13-27" class="st10" v:arrowtype="13" v:arrowsize="2" v:setback="8.04" refx="-8.04" orient="auto" markerunits="strokeWidth" overflow="visible">		<use xlink:href="#lend13" transform="scale(-2.68,-2.68) "></use>	</marker></defs><g v:mid="7" v:index="3" v:groupcontext="foregroundPage">	<title>getting-started-workflow</title>	<v:pageproperties v:drawingscale="1" v:pagescale="1" v:drawingunits="19" v:shadowoffsetx="9" v:shadowoffsety="-9"></v:pageproperties>	<g id="shape16-1" v:mid="16" v:groupcontext="shape" transform="translate(18,-18)">		<title>Rectangle.8</title>		<v:userdefs>			<v:ud v:nameu="visVersion" v:val="VT0(15):26"></v:ud>		</v:userdefs>		<rect x="0" y="36" width="639.938" height="120" rx="3.6" ry="3.6" class="st1"></rect>	</g>	<g id="shape2-3" v:mid="2" v:groupcontext="shape" transform="translate(31.875,-88.125)">		<title>Sheet.2</title>		<desc>前提条件</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="49.5" cy="138" width="99.01" height="36"></v:textrect>		<rect x="0" y="120" width="99" height="36" rx="4.5" ry="4.5" class="st2"></rect>		<text x="21.5" y="142.26" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>前提条件</text>		</g>	<g id="shape3-6" v:mid="3" v:groupcontext="shape" transform="translate(45,-25.875)">		<title>Sheet.3</title>		<desc>构建程序 启用 OpenCV 库和测试包</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="71.8125" cy="123.375" width="143.63" height="65.25"></v:textrect>		<rect x="0" y="90.7501" width="143.625" height="65.25" rx="4.5" ry="4.5" class="st4"></rect>		<text x="4" y="112.43" class="st5" v:langid="1033"><v:paragraph v:indentfirst="-18" v:indentleft="18" v:bullet="1"></v:paragraph><v:tablist></v:tablist><tspan class="st6" v:isbullet="true">·</tspan> <tspan class="st7">构建程序<v:newlinechar></v:newlinechar></tspan><tspan x="4" dy="1.216em" class="st6" v:isbullet="true">·</tspan> <tspan class="st7">启用</tspan><tspan class="st8"> </tspan><tspan class="st8">OpenCV </tspan><tspan x="22" dy="1.216em" class="st7">库和测试包</tspan></text>		</g>	<g id="shape4-16" v:mid="4" v:groupcontext="shape" transform="translate(256.875,-88.125)">		<title>Sheet.4</title>		<desc>实现</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="49.5" cy="138" width="99.01" height="36"></v:textrect>		<rect x="0" y="120" width="99" height="36" rx="4.5" ry="4.5" class="st2"></rect>		<text x="35.5" y="142.26" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>实现</text>		</g>	<g id="shape6-19" v:mid="6" v:groupcontext="shape" transform="translate(484.125,-88.125)">		<title>Sheet.6</title>		<desc>测试</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="49.5" cy="138" width="99.01" height="36"></v:textrect>		<rect x="0" y="120" width="99" height="36" rx="4.5" ry="4.5" class="st2"></rect>		<text x="35.5" y="142.26" class="st3" v:langid="1033"><v:paragraph v:horizalign="1"></v:paragraph><v:tablist></v:tablist>测试</text>		</g>	<g id="shape11-22" v:mid="11" v:groupcontext="shape" transform="translate(130.875,-108)">		<title>Sheet.11</title>		<path d="M0 156 L113.94 156" class="st9"></path>	</g>	<g id="shape13-28" v:mid="13" v:groupcontext="shape" transform="translate(355.875,-108)">		<title>Sheet.13</title>		<path d="M0 156 L116.19 156" class="st9"></path>	</g>	<g id="shape14-33" v:mid="14" v:groupcontext="shape" transform="translate(270.375,-25.875)">		<title>Sheet.14</title>		<desc>编译版本 在设备上刷写镜像</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="71.8125" cy="123.375" width="143.63" height="65.25"></v:textrect>		<rect x="0" y="90.7501" width="143.625" height="65.25" rx="4.5" ry="4.5" class="st4"></rect>		<text x="4" y="119.73" class="st5" v:langid="1033"><v:paragraph v:indentfirst="-18" v:indentleft="18" v:bullet="1"></v:paragraph><v:tablist></v:tablist><tspan class="st6" v:isbullet="true">·</tspan> <tspan class="st7">编译版本<v:newlinechar></v:newlinechar></tspan><tspan x="4" dy="1.216em" class="st6" v:isbullet="true">·</tspan> <tspan class="st7">在设备上刷写镜像</tspan></text>		</g>	<g id="shape15-40" v:mid="15" v:groupcontext="shape" transform="translate(495.75,-25.875)">		<title>Sheet.15</title>		<desc>运行测试应用程序</desc>		<v:textblock v:margins="rect(4,4,4,4)"></v:textblock>		<v:textrect cx="71.8125" cy="123.375" width="143.63" height="65.25"></v:textrect>		<rect x="0" y="90.7501" width="143.625" height="65.25" rx="4.5" ry="4.5" class="st4"></rect>		<text x="4" y="127.02" class="st5" v:langid="1033"><v:paragraph v:indentfirst="-18" v:indentleft="18" v:bullet="1"></v:paragraph><v:tablist></v:tablist><tspan class="st6" v:isbullet="true">·</tspan> <tspan class="st7">运行测试应用程序</tspan></text>		</g></g>
</svg>

## 前提条件

- 按照 [Qualcomm Linux 编译指南](https://docs.qualcomm.com/bundle/publicresource/topics/80-70020-254/introduction.html)中所述搭建基础架构。
- 刷写最新的软件版本，将其写入至开发板中。
- 设置 SSH 连接：按照[使用 SSH](https://docs.qualcomm.com/bundle/publicresource/topics/80-70020-254/how_to.html#use-ssh) 中提到的步骤在 Permissive 模式下启用 SSH
- 确认目标设备上 `/usr/lib` 存在 `libopencv_fastcv` 库。

    偶尔会出现 `fastcv_linux_aarch64_2025_02_12.tgz` 下载失败的情况，导致无法生成 `libopencv_fastcv` 库。

    如果缺少该库，请按以下启用 fastCV HAL 的补丁所示修改 `opencv_4.11.0.qcom.bb` 文件并重新编译版本：

    **启用 fastCV HAL 的补丁**

diff --git a/recipes-support/opencv/opencv_4.11.0.qcom.bb b/recipes-support/opencv/opencv_4.11.0.qcom.bb
        index 4ce2023..69c678d 100644
        --- a/recipes-support/opencv/opencv_4.11.0.qcom.bb
        +++ b/recipes-support/opencv/opencv_4.11.0.qcom.bb
        
        @@ -22,6 +22,7 @@ SRCREV_boostdesc = "34e4206aef44d50e6bbcd0ab06354b52e7466d26"
        SRCREV_vgg = "fccf7cd6a4b12079f73bbfb21745f9babcd4eb1d"
        SRCREV_face = "8afa57abc8229d611c4937165d20e2a2d9fc5a12"
        SRCREV_wechat-qrcode = "a8b69ccc738421293254aec5ddb38bd523503252"
        +SRCREV_fastcv = "f4413cc2ab7233fdfc383a4cded402c072677fb0"
        SRCREV_FORMAT = "opencv_contrib_ipp_boostdesc_vgg"
        
        @@ -31,6 +32,7 @@ SRC_URI = "git://github.com/opencv/opencv.git;name=opencv;branch=4.x;protocol=ht
                    git://github.com/opencv/opencv_3rdparty.git;branch=contrib_xfeatures2d_vgg_20160317;destsuffix=git/vgg;name=vgg;protocol=https \
                    git://github.com/opencv/opencv_3rdparty.git;branch=contrib_face_alignment_20170818;destsuffix=git/face;name=face;protocol=https \
                    git://github.com/WeChatCV/opencv_3rdparty.git;branch=wechat_qrcode;destsuffix=git/wechat_qrcode;name=wechat-qrcode;protocol=https \
        +           git://github.com/opencv/opencv_3rdparty.git;branch=fastcv/4.x_20250212;destsuffix=git/fastcv;name=fastcv;protocol=https \
                    file://0003-To-fix-errors-as-following.patch \
                    file://0001-Temporarliy-work-around-deprecated-ffmpeg-RAW-functi.patch \
                    file://0001-Dont-use-isystem.patch \
        @@ -66,6 +68,7 @@ do_unpack_extra() {
           cache data ${S}/face/*.dat
           cache wechat_qrcode ${S}/wechat_qrcode/*.caffemodel
           cache wechat_qrcode ${S}/wechat_qrcode/*.prototxt
        +    cache fastcv ${S}/fastcv/fastcv/*.tgz
        }
        addtask unpack_extra after do_unpack before do_patch
        
        @@ -91,7 +94,7 @@ EXTRA_OECMAKE:append:x86 = " -DX86=ON"
        # https://github.com/opencv/opencv/issues/21597
        EXTRA_OECMAKE:remove:x86 = " -DENABLE_SSE41=1 -DENABLE_SSE42=1"
        -PACKAGECONFIG ??= "gapi python3 eigen jpeg png tiff v4l libv4l gstreamer samples tbb gphoto2 \
        +PACKAGECONFIG ??= "gapi python3 eigen jpeg png tiff v4l libv4l gstreamer samples tbb gphoto2 fastcv \
           ${@bb.utils.contains_any('DISTRO_FEATURES', '${GTK3DISTROFEATURES}', 'gtk', '', d)} \
           ${@bb.utils.contains_any("LICENSE_FLAGS_ACCEPTED", "commercial_ffmpeg commercial", "libav", "", d)}"
        
        @@ -126,6 +129,7 @@ PACKAGECONFIG[tests] = "-DBUILD_TESTS=ON,-DBUILD_TESTS=OFF,,"
        PACKAGECONFIG[text] = "-DBUILD_opencv_text=ON,-DBUILD_opencv_text=OFF,tesseract,"
        PACKAGECONFIG[tiff] = "-DWITH_TIFF=ON,-DWITH_TIFF=OFF,tiff,"
        PACKAGECONFIG[v4l] = "-DWITH_V4L=ON,-DWITH_V4L=OFF,v4l-utils,"
        +PACKAGECONFIG[fastcv] = "-DWITH_FASTCV=ON ,-DWITH_FASTCV=OFF,,"
        inherit pkgconfig cmake setuptools3-base python3native
        
        @@ -224,9 +228,6 @@ SUMMARY = "Opencv : The Open Computer Vision Library, Qualcomm Fork"
        SRC_URI += "file://0001-PENDING-Removed-cluster-euclidean-in-fastcv-ext.patch;patchdir=${S}/contrib/ \
                    file://0001-FROMLIST-Using-fastcv-static-lib-for-compilation.patch"
        -EXTRA_OECMAKE += "-DOPENCV_ALLOW_DOWNLOADS=ON "
        -EXTRA_OECMAKE += " -DWITH_FASTCV=ON "
        -
        do_install:append() {
           rm -f ${D}/usr/lib/libfastcv.a
        }
        Copy to clipboard

    刷写编译版本后，确认 `libopencv_fastcv` 库存在于 `/usr/lib` 中。

## 启用 OpenCV 库和测试包

1. 要启用 **tests** 包，请将 `tests` 包括在 `<workspace>/layers/meta-qcom-hwe/recipes-support/opencv/opencv_4.11.0.qcom.bb` 配方文件的 `PACKAGECONFIG` 中，如下所示。

PACKAGECONFIG ??= "gapi python3 eigen jpeg png tiff v4l libv4l samples tbb gphoto2 tests \
        ${@bb.utils.contains("DISTRO_FEATURES", "x11", "gtk", "", d)} \
        Copy to clipboard

    默认情况下，只有编译版本中显示为测试 bin 的库会被清理。
2. 要保留测试 bin，请在 `<workspace>/layers/meta-qcom-hwe/recipes-support/opencv/opencv_4.11.0.qcom.bb` 配方文件中包括以下代码：

RM_WORK_EXCLUDE += "opencv"
        Copy to clipboard
3. 当版本已经被编译过了，必须在重新编译之前清理 OpenCV。要清理 OpenCV，运行以下命令：

bitbake -fc cleanall opencv
        Copy to clipboard

    编译期间不会修改代码，因此直接编译不会生成相应的二进制文件。
4. 要编译 OpenCV，运行以下命令：

bitbake opencv
        Copy to clipboard

库的路径为 `tmp-glibc\sysroots-components\armv8-2a\opencv\usr\lib`。

Bin 的路径为 `tmp-glibc\work\armv8-2a-qcom-linux\opencv\4.11.0.qcom\build\bin`。

## 运行现有测试应用程序

要调用 OpenCV API，原生 OpenCV 测试示例可以参考示例程序。使用以下步骤调用 Snapdragon 设备上的应用程序。完整地编译镜像以确保所有库都是应用程序镜像的一部分。

1. 按照 [Qualcomm Linux 编译指南](https://docs.qualcomm.com/bundle/publicresource/topics/80-70020-254/)的描述在设备上刷写镜像。

    OpenCV 库位于设备上的 `/usr/lib`。
2. 关于测试数据，`git clone` 在 [https://github.com/opencv/opencv_extra/tree/4.11.0](https://github.com/opencv/opencv_extra/tree/4.11.0) 的项目。
3. 为了避免在尝试将测试数据和 bin 推送到设备时出现只读错误，使用设备的 IP 地址登录 SSH 终端，并运行以下命令重新挂载设备。

mount -o remount,rw /usr
        Copy to clipboard
4. 使用 `scp` 命令将测试数据推送到首选主机。

    例如：`scp -r [file] root@[IP-ADDR]:/tmp`
5. 使用 `scp` 命令将所需的测试 bin 推送到 `/usr/bin`。

    例如：`scp -r [test] root@[IP-ADDR]:/usr/bin/`
6. 登录 SSH 终端并运行以下命令。

chmod 777 /usr/bin/<opencv_test_bin>
        cd /usr/bin
        export OPENCV_LOG_LEVEL=DEBUG
        export OPENCV_VIDEOIO_DEBUG=1
        export OPENCV_TEST_DATA_PATH=/tmp
        ./<opencv_test_bin> --gtest_output=json:/tmp/results.json --gtest_also_run_disabled_tests
        exit
        Copy to clipboard

    结果存储在 `/tmp/results.json`。要更改结果文件名，请修改 `--gtest_output=json:/tmp/{results.json}` 参数。

Last Published: Aug 12, 2025

[Previous Topic
概述](https://docs.qualcomm.com/bundle/publicresource/80-70020-21SC/topics/overview.md) [Next Topic
实现新示例应用](https://docs.qualcomm.com/bundle/publicresource/80-70020-21SC/topics/sample-applications.md)