基于龙芯2K0300久久派的OpenCV交叉编译实战:从虚拟机Ubuntu20.04到嵌入式视觉应用部署 1. 环境准备搭建Ubuntu20.04虚拟机在开始龙芯2K0300久久派的OpenCV交叉编译之前我们需要一个稳定的开发环境。我强烈推荐使用Ubuntu 20.04 LTS作为基础系统这个版本不仅长期支持而且社区资源丰富遇到问题容易找到解决方案。我自己在多个嵌入式项目中都使用这个版本稳定性确实没得说。安装虚拟机时建议分配至少40GB磁盘空间编译OpenCV及其依赖会占用大量空间内存最好给到4GB以上。我刚开始尝试时只分配了20GB空间结果编译到一半就提示磁盘空间不足不得不从头再来。处理器核心数建议设置为2-4个这样能显著加快编译速度。安装完成后第一件事就是更换软件源。国内用户可以使用清华源或阿里云镜像速度会快很多。这里有个小技巧先备份原来的sources.list文件再用sed命令一键替换sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak sudo sed -i s|http://.*archive.ubuntu.com|https://mirrors.tuna.tsinghua.edu.cn|g /etc/apt/sources.list sudo sed -i s|http://.*security.ubuntu.com|https://mirrors.tuna.tsinghua.edu.cn|g /etc/apt/sources.list sudo apt update2. 获取和配置龙芯交叉编译工具链龙芯2K0300久久派使用的是LoongArch64架构这意味着我们需要专门的交叉编译工具链。官方提供的工具链是loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.3这个版本经过我的实测与OpenCV 3.4.6兼容性最好。下载工具链后我建议将其安装到/opt目录下。这里有个细节要注意解压后的文件夹权限可能需要手动调整否则普通用户无法访问sudo tar -xvf loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.3-1.tar.gz -C /opt sudo chmod -R 755 /opt/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.3-1接下来需要将工具链添加到系统路径中。我更喜欢在~/.bashrc中添加环境变量而不是直接修改/etc/environment这样更灵活echo export PATH$PATH:/opt/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.3-1/bin ~/.bashrc source ~/.bashrc验证工具链是否安装成功可以运行loongarch64-linux-gnu-gcc --version如果看到正确的版本信息输出说明工具链已经准备就绪。我在第一次尝试时遇到了command not found错误后来发现是因为忘记执行source ~/.bashrc这个小细节浪费了我半小时。3. 准备OpenCV源码和依赖库OpenCV的版本选择很关键。经过多次测试3.4.6版本在龙芯2K0300上的稳定性最好。可以从OpenCV官网下载也可以直接使用wget命令wget -O opencv-3.4.6.zip https://github.com/opencv/opencv/archive/3.4.6.zip unzip opencv-3.4.6.zip我建议创建一个专门的工作目录来管理所有相关文件结构可以这样安排~/opencv_cross/ ├── build/ # 编译目录 ├── install/ # 安装目录 └── opencv-3.4.6/ # 源码目录安装依赖库是最容易出错的环节。根据我的经验以下命令可以一次性安装所有必需的依赖sudo apt-get install -y build-essential libopenblas-dev git pkg-config \ libavcodec-dev libavformat-dev libswscale-dev python-dev python-numpy \ libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff5-dev libdc1394-22-dev \ libv4l-dev liblapacke-dev libxvidcore-dev libx264-dev \ libatlas-base-dev gfortran ffmpeg特别提醒安装过程中如果遇到Unable to locate package错误可能是软件源没更新或者拼写错误。我曾经因为把libtiff5-dev错写成libtiff-dev而卡了很久。4. 配置和编译OpenCV进入build目录启动cmake-gui进行配置cd ~/opencv_cross/build cmake-gui ..在CMake界面中需要特别注意以下几个关键配置项工具链设置CMAKE_C_COMPILER:/opt/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.3-1/bin/loongarch64-linux-gnu-gccCMAKE_CXX_COMPILER:/opt/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.3-1/bin/loongarch64-linux-gnu-g安装路径CMAKE_INSTALL_PREFIX:~/opencv_cross/install额外标志CMAKE_EXE_LINKER_FLAGS:-lpthread -lrt -ldl禁用测试BUILD_TESTS:OFF(这个一定要关否则会编译失败)配置完成后需要手动修改一个源码文件才能继续。找到opencv-3.4.6/3rdparty/protobuf/src/google/protobuf/stubs/common.cc在文件开头添加#define HAVE_PTHREAD这个步骤很容易被忽略但如果不做编译时会报奇怪的pthread相关错误。我第一次编译时就栽在这里重试了三次才发现问题所在。开始编译前建议先清理一下之前的编译结果如果有的话make clean然后开始正式编译make -j$(nproc)-j$(nproc)参数会使用所有可用的CPU核心进行并行编译可以显著加快速度。在我的i7-10700上完整编译大约需要40分钟。如果遇到内存不足的情况可以尝试减少并行任务数比如-j4。编译完成后执行安装命令make install安装过程通常很快完成后检查~/opencv_cross/install目录应该能看到lib、include等子目录。这些就是我们要用到开发板上的文件。5. 验证和部署到龙芯2K0300编译生成的库文件需要通过SD卡或网络传输到龙芯2K0300开发板上。我更喜欢使用scp命令通过网络传输scp -r ~/opencv_cross/install user192.168.x.x:/home/user/opencv在开发板上需要设置环境变量让系统找到这些库文件。编辑~/.bashrc添加export LD_LIBRARY_PATH$LD_LIBRARY_PATH:/home/user/opencv/lib export PKG_CONFIG_PATH$PKG_CONFIG_PATH:/home/user/opencv/lib/pkgconfig验证OpenCV是否正常工作可以创建一个简单的测试程序#include opencv2/opencv.hpp #include iostream int main() { cv::Mat image cv::Mat::zeros(480, 640, CV_8UC3); cv::putText(image, Hello Loongson!, cv::Point(100,240), cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0,255,0), 2); cv::imwrite(test.jpg, image); std::cout OpenCV test completed! std::endl; return 0; }使用交叉编译器编译这个测试程序loongarch64-linux-gnu-g test.cpp -o test loongarch64-linux-gnu-pkg-config --cflags --libs opencv4将生成的可执行文件复制到开发板上运行。如果一切正常你会看到生成的test.jpg图片上面有Hello Loongson!的文字。6. 常见问题排查在实际操作中可能会遇到各种问题。这里分享几个我踩过的坑和解决方法问题1编译时出现undefined reference to png_init_filter_functions_neon这是因为PNG库的NEON优化代码与龙芯架构不兼容。解决方法是在CMake配置中添加-D PNG_TESTSOFF -D PNG_HARDWARE_OPTIMIZATIONSOFF问题2运行时报错libopencv_core.so.3.4: cannot open shared object file这通常是库路径没设置正确。确保库文件确实存在于开发板上的指定路径LD_LIBRARY_PATH环境变量设置正确执行ldconfig更新库缓存问题3视频相关功能无法使用如果项目需要视频处理功能需要确保开发板上安装了FFmpeg。可以通过以下命令检查ffmpeg -version如果没有安装需要先在开发板上安装FFmpeg和相关依赖。问题4编译时间过长OpenCV完整编译确实很耗时。如果只是做基础图像处理可以通过CMake关闭不需要的模块来加快编译速度比如-D BUILD_opencv_dnnOFF -D BUILD_opencv_pythonOFF -D BUILD_opencv_javaOFF7. 性能优化技巧在龙芯2K0300这样的嵌入式平台上性能优化尤为重要。以下是我总结的几个实用技巧启用NEON等效指令优化 虽然龙芯不支持ARM的NEON指令但它有自己的SIMD指令集。在CMake配置中添加-D ENABLE_LOONGARCH_ASMON调整线程数 OpenCV的很多算法支持多线程但在资源有限的嵌入式设备上太多线程反而会降低性能。可以通过环境变量控制export OMP_NUM_THREADS2 export OPENCV_FOR_THREADS_NUM2内存使用优化尽量复用Mat对象而不是频繁创建/销毁使用UMatOpenCL加速可能会获得更好性能对小图像处理考虑使用cv::parallel_for_并行化选择性编译 如果只需要部分功能可以在CMake中禁用不需要的模块。比如如果只用基础图像处理可以禁用dnn、videoio等模块-D BUILD_opencv_dnnOFF -D WITH_GTKOFF量化与降精度 对于实时性要求高的应用可以考虑使用16位整数或更低精度的浮点数运算牺牲一些精度换取速度。8. 实际项目应用示例最后分享一个我在龙芯车赛项目中实际应用的例子赛道边缘检测。这个例子展示了如何将我们编译的OpenCV库用于实际项目。首先我们需要捕获摄像头图像。龙芯2K0300久久派支持USB摄像头使用OpenCV的VideoCapture非常简单cv::VideoCapture cap(0); // 打开默认摄像头 if(!cap.isOpened()) { std::cerr 无法打开摄像头! std::endl; return -1; }接下来是图像处理的核心代码。我们使用Canny边缘检测算法找出赛道边界cv::Mat frame, gray, edges; cap frame; // 获取一帧图像 // 转换为灰度图并降噪 cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY); cv::GaussianBlur(gray, gray, cv::Size(5,5), 1.2); // Canny边缘检测 cv::Canny(gray, edges, 50, 150); // 显示结果 cv::imshow(Original, frame); cv::imshow(Edges, edges); cv::waitKey(1);为了优化性能我们可以添加一些改进降低图像分辨率龙芯2K0300处理高清图像会比较吃力使用ROIRegion of Interest只处理图像中感兴趣的区域采用多级处理先用低精度算法快速筛选再对关键区域使用高精度算法完整项目还需要考虑实时性、稳定性等因素。比如添加看门狗定时器防止程序卡死使用双缓冲机制避免图像撕裂等。这些都是在实际嵌入式视觉项目中需要考虑的问题。