一、opencv 交叉编译没有 ffmpeg ,会导致视频打不开
在交叉编译时候,发现在 pc 端能用 opencv 打开的视频,但是在 rv1126 上打不开。在网上查了很久,原因可能是 交叉编译过程 ffmpeg 造成的。之前 ffmpeg 是直接用 apt 安装的,opencv 编译也是直接用 Cmake 命令行进行的。
网上特别推荐用命令行进行编译,但是本次交叉编译,我发现使用 CMake-gui 进行编译,能更好地找出错误,因为不管是警告还是错误,CMake-gui 都会用红字来表示。
二、准备工作
创建一个目录:/opt/software,把 opencv4.5.5、x264、ffmpeg-4.x 都下载到该目录
再创建一个目录:/opt/out-arm,用作 x264、ffmpeg的安装目录
三、交叉编译x264
opencv交叉编译静态库,支持ffmpeg、libjpeg,实现取流及写入jpeg文件_交叉编译 生成静态库_程序员阿周的博客-CSDN博客
1、解压源码并且进入源码目录
2、编译动态库,目的是编译ffmpeg使用,命令如下:
#./configure --prefix=/opt/software/opencv --host=arm-linux --cross-prefix=arm-linux-gnueabihf- --disable-asm --enable-shared
#make -j6
#make install
3、编译静态库,目的是最后我们的应用程序链接使用,命令如下:
#./configure --prefix=/home/cxyazhou/work/opencv --host=arm-linux --cross-prefix=arm-linux-gnueabihf- --disable-asm
#make clean;make -j6
#make install
注意:静态库编译时,make install只会拷贝bin下的文件到install目录,所以这里需要手动拷贝头文件、静态库到install目录,基于上面已经编译了动态库,会自动拷贝头文件,这里我们只要拷贝静态库到install的lib目录就可以:
#cp libx264.a /opt/out-arm/lib/
四、交叉编译 ffmpeg
opencv交叉编译静态库,支持ffmpeg、libjpeg,实现取流及写入jpeg文件_交叉编译 生成静态库_程序员阿周的博客-CSDN博客
0、配置下环境变量,防止编译 ffmpeg 时候找不到 x264库
#export PKG_CONFIG_PATH=/opt/out_arm/lib/pkgconfig/
1、解压源码并且进入源码目录
2、编译静态库,命令如下:
#./configure --cross-prefix=arm-linux-gnueabihf- --enable-cross-compile --target-os=linux --cc=arm-linux-gnueabihf-gcc --arch=arm64 --prefix=/opt/out-arm --enable-ffmpeg --disable-armv5te --disable-armv6 --disable-armv6t2 --disable-asm --enable-swscale --enable-avresample --enable-gpl --enable-libx264 --extra-cflags=-I/opt/out-arm/include --extra-ldflags=-L/opt/out-arm/lib
#make -j6
#make install
五、交叉编译 OpenCV
Configure 前工作
按照上述块引用中的博客来,另外我还通过 Add Entry 指定了安装目录:
docker 容器中 /mnt 目录 会映射整个开发板
Configure
Configure 过程中的一些 Warning 不用太在意,只要 Configure 能完成就行:
检查 Configure 结果,FFMPEG 为 YES ,欧耶:
Generate
Generate 在上面的博客中没有报错,但是我这里报错:
CMake Error in modules/videoio/CMakeLists.txt: Imported target "ocv.3rdparty.ffmpeg" includes non-existent path "/mnt/opt/software/opencv/include" in its INTERFACE_INCLUDE_DIRECTORIES. Possible reasons include: * The path was deleted, renamed, or moved to another location. * An install or uninstall procedure did not complete successfully. * The installation package was faulty and references files it does not provide.
解决方法是把 x264、 ffmpeg库的安装目录下的 include 文件夹的内容 copy 过去
copy /opt/out-arm/include/* /mnt/opt/software/opencv/include -r
在构建目录下执行的工作
Generate 完成后,关闭 cmkae-gui,回到构建目录,执行:
make -j8
make install
安装完毕:
六、检查是否能打开视频
CMakLists.txt
cpp
cmake_minimum_required(VERSION 2.8.4)
STRING(REGEX REPLACE ".*/(.*)" "\\1" CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR} )
MESSAGE("current project: " ${CURRENT_FOLDER})
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_CROSSCOMPILING TRUE)
cmake_host_system_information(RESULT arch_value QUERY OS_PLATFORM)
if(NOT "${arch_value}" STREQUAL "armv7l")
include ($ENV{HOME}/configs/cross.cmake)
endif()
project(video_test)
# 设置链接器路径
link_directories(/mnt/usr/lib/arm-linux-gnueabihf)
set(CMAKE_PREFIX_PATH "/mnt/usr" ${CMAKE_PREFIX_PATH})
find_package(OpenCV REQUIRED)
add_executable(video_test test.cpp )
target_include_directories(video_test PUBLIC ${OpenCV_INCLUDE_DIRS} )
target_link_libraries(video_test PRIVATE ${OpenCV_LIBS} /mnt/usr/lib/ogdi/libgdal.so)
target_link_libraries(video_test PRIVATE -Wl,-rpath,/mnt/usr/lib/arm-linux-gnueabihf/)
test.cpp
cpp
#include <opencv2/opencv.hpp>
#include <iostream>
int main()
{
cv::VideoWriter outputVideo("/userdata/result.mp4",
cv::VideoWriter::fourcc('m', 'p', '4', 'v'),
double(1000/30),
cv::Size(640,480));
// int camera_id =0;
std::string video_path = "/userdata/test.avi";
cv::VideoCapture camera(video_path);
if(!camera.isOpened()){
printf("camera %s cann't open\n", video_path.c_str());
return 1;
}
else
printf("camra %s opened\n", video_path.c_str());
int frame_num = camera.get(cv::CAP_PROP_FRAME_COUNT);
int frame=0;
cv::Mat img;
while(1){
frame +=1;
camera >> img;
if (img.empty()){
printf("camera cann't get image!\n");
}
// cv::imshow("result", img);
outputVideo.write(img);
if(frame == frame_num - 2) break;
}
camera.release();
outputVideo.release();
return 0;
}
交叉编译的可执行文件,video_test 可以在开发板上打开视频文件:
七、其他
**在编译和安装源代码时,常常会使用 pkg-config 工具来帮助 CMake 在构建过程中找到所需的库和头文件路径。**pkg-config 是一个用于管理编译时和运行时依赖关系的工具,它提供了一个标准的接口来查询所需库的相关信息。
当安装一个库时,通常会将库的元数据信息(如库路径、版本号、依赖关系等)保存在对应的 .pc
文件中 ,并将该文件安装到系统的 pkg-config 目录中。pkg-config 目录是一个包含所有项目所需的 .pc
文件的目录,CMake 可以通过查询这些文件来获取库的信息。
在 CMake 中,可以使用 find_package
命令来查找并配置依赖库的设置。当传递库的名称给 find_package
,CMake 将通过 pkg-config 查询相应的库信息,并将结果存储在变量中,例如:
find_package(OpenCV REQUIRED)
上述代码中,find_package(OpenCV REQUIRED)
将在 pkg-config 目录中查找名为 opencv.pc
的文件,并从中提取出 OpenCV 库的信息,包括库的路径、版本号和所需的其他依赖关系。然后,CMake 将使用这些信息来配置 OpenCV 库的设置,以便在构建过程中可以找到和链接 OpenCV。
需要注意的是,并非所有的库都使用 pkg-config 进行管理和配置。有些库可能使用其他方式来提供编译和运行时的元数据信息,例如 CMake 配置文件或环境变量。因此,在使用特定库时,应查阅该库的文档或官方指南,以了解正确的配置方法。