第二章 开发环境搭建:交叉编译工具链安装、OpenCV与TensorFlow Lite在ARM平台上的编译与部署
好,咱们正式开始动手了。这一章,说白了就是给你的开发板“配齐家伙”。没有趁手的工具,再牛的算法也跑不起来。我见过不少新手,算法在PC上跑得飞起,一放到ARM板上就各种报错,最后发现是环境没搭对。所以,这一章咱们稳扎稳打,把交叉编译环境、OpenCV和TensorFlow Lite(TFLite)在ARM平台上的部署,一步不落地搞定。
2.1 交叉编译工具链:为什么需要它?
你想想看,你的PC是x86架构,ARM开发板是ARM架构。在x86上编译出来的程序,ARM板能直接运行吗?不能。所以我们需要交叉编译——在PC上编译出能在ARM上运行的程序。
我个人习惯用Linaro提供的工具链,稳定且社区支持好。以ARM Cortex-A72为例(比如树莓派4B),我们选择gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu。为什么选这个版本?因为我在项目中踩过坑,太老的版本对C++17支持不好,太新的又可能跟某些库不兼容。
核心要点:交叉编译工具链 = 编译器 + 链接器 + 库文件。它告诉编译器:“嘿,目标CPU是ARM,别按x86的规矩来。”
安装步骤
- 下载工具链:
wget https://developer.arm.com/-/media/Files/downloads/gnu-a/10.2-2020.11/binrel/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu.tar.xz - 解压到指定目录:
tar -xf gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt/ - 添加环境变量:
export PATH=$PATH:/opt/gcc-arm-10.2-2020.11-x86_64-aarch64-none-linux-gnu/bin - 验证安装:
aarch64-none-linux-gnu-gcc --version
我的小技巧:把环境变量写到~/.bashrc里,省得每次开终端都要export一遍。我曾经因为忘了这步,浪费了半小时排查“为什么找不到编译器”。
2.2 OpenCV在ARM上的编译:一场耐心的修行
OpenCV的编译,说难不难,说简单也不简单。尤其是第一次编译,各种依赖缺失会让你抓狂。我建议你直接编译OpenCV 4.5.5版本,这个版本对ARM的NEON指令集优化做得不错。
2.2.1 准备工作
先安装依赖。在ARM板上(或者通过chroot环境)执行:
sudo apt-get update
sudo apt-get install build-essential cmake git pkg-config
sudo apt-get install libjpeg-dev libpng-dev libtiff-dev
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install libgtk2.0-dev libcanberra-gtk-module
sudo apt-get install python3-dev python3-numpy python3-pip
嗯,这里要注意。如果你是在PC上交叉编译OpenCV给ARM用,那这些依赖需要在你的sysroot里准备好。我个人更推荐直接在ARM板上原生编译,虽然慢一点,但省去了很多路径配置的麻烦。
2.2.2 编译OpenCV
下载源码并创建构建目录:
git clone https://github.com/opencv/opencv.git -b 4.5.5
cd opencv
mkdir build && cd build
然后配置CMake。这里有几个关键选项:
cmake -DCMAKE_BUILD_TYPE=RELEASE \
-DCMAKE_INSTALL_PREFIX=/usr/local \
-DENABLE_NEON=ON \
-DENABLE_VFPV3=ON \
-DWITH_TBB=ON \
-DWITH_OPENMP=ON \
-DWITH_GTK=ON \
-DWITH_JPEG=ON \
-DWITH_PNG=ON \
-DWITH_TIFF=ON \
-DBUILD_opencv_python3=ON \
-DBUILD_TESTS=OFF \
-DBUILD_PERF_TESTS=OFF ..
关键参数解释:
ENABLE_NEON=ON:启用ARM的NEON SIMD指令集,人脸检测的卷积运算能快3-5倍。ENABLE_VFPV3=ON:启用浮点运算加速。WITH_TBB=ON:启用Intel TBB并行库,多核CPU上效果明显。
配置完成后,开始编译。ARM板子性能有限,建议用make -j4(4核并行)。如果是树莓派4B,大概需要1-2小时。这时候你可以去喝杯咖啡,或者看看下一节的内容。
我曾经踩过的坑:编译到一半报错“内存不足”。原因是树莓派只有1GB内存,而OpenCV编译时某些文件需要大量内存。解决方案:增加swap空间,或者用make -j2降低并行度。
2.3 TensorFlow Lite:轻量级推理引擎的部署
TFLite是Google为移动和嵌入式设备量身定做的。它比完整的TensorFlow小得多,但推理速度却很快。说白了,它就是为ARM这类资源受限的平台设计的。
2.3.1 下载TFLite C++库
有两种方式:一是直接下载预编译的静态库,二是从源码编译。我建议你从源码编译,因为可以针对你的ARM CPU做优化。
git clone https://github.com/tensorflow/tensorflow.git
cd tensorflow
./tensorflow/lite/tools/make/download_dependencies.sh
./tensorflow/lite/tools/make/build_aarch64_lib.sh
这个脚本会自动下载依赖并编译。编译完成后,你会在tensorflow/lite/tools/make/gen/aarch64_armv8-a/lib/目录下找到libtensorflow-lite.a。
2.3.2 交叉编译TFLite(进阶)
如果你需要在PC上交叉编译TFLite给ARM用,可以这样做:
cd tensorflow
mkdir build && cd build
cmake ../tensorflow/lite \
-DCMAKE_TOOLCHAIN_FILE=../tensorflow/lite/tools/cmake/toolchains/aarch64_linux.toolchain.cmake \
-DCMAKE_BUILD_TYPE=Release
make -j4
我的经验:交叉编译TFLite时,记得检查你的工具链路径是否正确。我曾经因为工具链路径写错,编译出来的库在ARM板上运行直接段错误。排查了整整一天才发现是编译器版本不匹配。
2.4 验证环境:跑一个简单的测试
环境搭好了,怎么知道对不对?写个简单的测试程序吧。
// test_opencv.cpp
#include <opencv2/opencv.hpp>
#include <iostream>
int main() {
cv::Mat img = cv::Mat::zeros(100, 100, CV_8UC3);
std::cout << "OpenCV version: " << CV_VERSION << std::endl;
std::cout << "Image size: " << img.size() << std::endl;
return 0;
}
编译命令:
aarch64-none-linux-gnu-g++ test_opencv.cpp -o test_opencv \
-I/usr/local/include/opencv4 \
-L/usr/local/lib \
-lopencv_core -lopencv_imgproc -lopencv_highgui
把编译好的test_opencv传到ARM板上,运行。如果输出OpenCV版本号和图像尺寸,恭喜你,环境搭建成功了!
小总结:
| 组件 | 版本建议 | 编译时间(树莓派4B) | 关键优化选项 |
|---|---|---|---|
| 交叉编译工具链 | gcc-arm-10.2 | 5分钟(下载+解压) | 选择aarch64版本 |
| OpenCV | 4.5.5 | 1-2小时 | ENABLE_NEON, WITH_TBB |
| TensorFlow Lite | 2.9.0 | 30分钟 | 使用build_aarch64_lib.sh |
环境搭建是嵌入式开发中最枯燥但最重要的一步。别嫌麻烦,也别跳过。我见过太多人因为环境没搭好,后面调试时浪费了更多时间。记住:磨刀不误砍柴工。下一章,我们就要开始真正的“人脸检测”实战了,到时候你会发现,今天花的时间,值!
最后一个小建议:把编译好的库文件备份一份。下次换SD卡或者重装系统时,直接拷贝过去,能省下好几个小时。我自己的服务器上就存了各种ARM平台的预编译库,随用随取。
好了,环境搭完了,咱们下章见!