firefly rk3588s+qt+海康摄像头部分问题记录

发布于:2025-02-11 ⋅ 阅读:(49) ⋅ 点赞:(0)

摄像头部分问题

        1、摄像头USB3.0和USB2.0的兼容性问题。

        摄像头的USB口使用3.0口。

        2、使用海康摄像头MVS相关包时,测试官方提供的QT代码,出现libQt5Core.so.5: version 'Qt_5.14' not found 错误。

        解决:改pro文件的Lib库路径。它里面加了 -L来指定,qt的lib那行注释掉让编译器去找环境变量就行。

QT环境部分问题

        下qt安装包的时候要看cpu的,一般不是amd64的都要自己从源码编译。 (qt源码包,交叉编译工具编译得到目标平台上可运行的qt的SDK)

        .run后缀的应该是AMD64的,ARM64、MIPS64这些电脑用不了。

        x86_64也称为x64或AMD64,是x86架构的64位扩展。使用CISC复杂指令集架构。

        ARM64适应RISC精简指令集。

        GNU交叉编译工具链有源码+/etc/profile环境变量指定安装和apt-get指令安装两种方式。指令安装自动适配,更方便。

Qt教程3-Ubuntu(x86_64)上配置arm64(aarch64)交叉编译环境及QT编译arm64架构工程_qt交叉编译arm-CSDN博客

Ubuntu20.04配置aarch64的Qt6环境(亲测有效)_ubuntu aarch64-CSDN博客

arm64板子的qt程序编写和烧录问题

        arm64架构的ubuntu系统高于16.0版本后,不怎么支持导出成 .iso镜像。

  而且查资料发现 vmware只支持AMD架构和x86_64架构的系统,不怎么支持 ARM64架构。

        采取的方法是直接板子上装qt写程序,然后导出 根文件系统镜像 .img做批量烧录。

从开发板导出根文件系统并修改(Ubuntu)_导出开发板上的ubuntu镜像-CSDN博客

        (其实就是用 rsync文件同步指令,远程同步开发板的根文件,然后制作成根文件系统。

        用dd指令,创建.img镜像文件。用mkfs.ext4指令转换文件系统那个文件夹的格式。

        mount指令 将镜像文件挂载到一个空文件中,文件系统复制到该空文件。就实现了文件系统的内容导入镜像文件的效果。

关于虚拟机的网络配置

Vmware Ubuntu找不到wifi适配器_虚拟机未发现wifi适配器-CSDN博客

注意防火墙问题。

#####我这里试了下,只有桥接模式下板子能ping通虚拟机,NAT模式下虚拟机能ping通板子,反过来不行。######

QT移植部分问题

矩形框绘图

scene()->removeItem(rubberBand);

导致程序崩溃。

修改:

if (rubberBand && scene() && scene()->items().contains(rubberBand)) {                         
    scene()->removeItem(rubberBand);             
    delete rubberBand; // 如果item是通过new分配的,需要进行清理 
}

        我出现这个问题是因为忘记在构造函数初始化 rubberBand=nullptr; 了,导致未初始化的变量进入了if代码块。  

QPainter常见问题

QWidget::paintEngine: Should no longer be called

        原因是对QWidget的绘图操作只能在paintEvent中进行。

相机画面添加准星

        尝试对相机扫描到的图片添加准星,由于我的相机的海康的SDK显示格式只能是灰白(存疑),导致原图上使用QPainter绘制准星后使用QPixmal得到的也是黑白,因此注释了海康的回调函数,将原图像传送给QLabel来显示QPixmal。

        结果原图像太大,多传了一次显示起来就卡很多。

        因此考虑准星和Widget上显示的原图像分别使用两个图层

        结果,QGraphesView,他娘的背景搞不透明,对原图像造成遮挡,多次测试无果。

        再考虑QLabel直接显示一个背景透明的准星图片,

        结果QLabel仍然是无法做到背景透明

        多番测试,解决方法,

        自定义QWidget组件,重写paintEvent方法,使用QPainter加载图片

/*该组件测试用*/
TranslucentWidget::TranslucentWidget(QWidget *parent) : QWidget(parent)
{
    this->setAttribute(Qt::WA_TranslucentBackground);
    QVBoxLayout *layout = new QVBoxLayout(this);
    QLabel *label = new QLabel("This is a translucent widget", this);
    layout->addWidget(label);
}


void TranslucentWidget::paintEvent(QPaintEvent *event)
{
//    QPainter painter(this);
//    painter.setOpacity(0);  // 设置透明度为 50%
//    painter.fillRect(this->rect(), Qt::blue);  // 绘制一个半透明的蓝色矩形

        //Q_UNUSED(event);//消除未使用参数导致的警告
        QPainter painter(this);
        painter.setOpacity(0.8);  //0.7
        painter.drawPixmap(rect(),QPixmap(":/imageResource/crossAim.png"), QRect());
}

        上述方法呢,图片确实是加载了,但是只要把组件的父类给成另一个QWidget或者给成MainWindow,仍然会遮挡,出现黑框,要不就是组件矩形背景加闪烁

        25.1.10,参考下面哥们儿的方法尝试,使用QStackLayout,

        Qt实现两个窗口重叠,下层播放视频,上次透明显示方框_qt视频叠加-CSDN博客

         Qt如何实现动态背景-视频背景_qt 动态背景-CSDN博客

         无果。

        再尝试

        qt 视频界面 创建 osd 的2种方法-CSDN博客

         测试了这位佬的方法,不行,海康的sdk采集的图像显示的窗口频繁刷新导致闪烁。

具体原因参考:

Qt在视频上方添加透明窗体_qt 透明窗口上写文本和图片,下面窗口可展示图片或播放视频-CSDN博客

Qt之libVLC或者海康SDK视频上显示透明控件_qt 海康sdk视频上显示透明控件-CSDN博客

唉,最终还是只能考虑做一个句柄不同的窗口,然后通过信号去调整窗口的位置

this->setAttribute(Qt::WA_TranslucentBackground);//设置窗口属性,背景为透明
this->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);//移除窗口的系统装饰 | 将窗口设置为工具窗口

唉,用这low方法的时候注意设置成工具窗体,不然显示不置顶....

这里要是有佬看到了,有更好的办法,麻烦评论区指导一下....

1.10 晚更新,在MainWindow的closeEvent中加入了 "准星"窗体的Close函数,程序运行时就只有MainWindow的窗体弹出来,不再是之前出来两个窗体,还要自己手动杀死的效果了

uchar*转cv::Mat导致程序崩溃

        uchar数组转cv::Mat导致程序卡死,cv::Mat的构造函数是拿到了数组的指针,需要注意变量的作用域问题。

        但我的原因是new字符指针的时候大小给的不对,以及某个对象忘记初始化的问题。

        cv::Mat内部使用智能指针进行了内存的封装,不需要手动管理内存

指针的大小

        32位系统中指针自身占4字节,64位系统中指针占8字节。

VSCode编辑器

        巨峰摄像头,SDK我拿到手时仅支持Linux_86_64和Windos_86_64,和Andriod。

        想在Linux_aarch64架构上使用只能考虑交叉编译。

        先用VSCode测试SDK的可行性。

测试C/C++环境

VS Code 配置 C/C++ 编程运行环境(保姆级教程)_vscode c++配置-CSDN博客

测试交叉编译 

        巨峰提供了linux-amd和windos-64俩版本sdk,windos的sdk需要Dll文件支持,铁定没法交叉编译到arm64架构上运行了,因此考虑使用Linux版本sdk。

        VSCode配置好了,配置一个VScode的CMake环境,然后下载个编译工具,编译工具给个环境变量,CMake Quick创建个工程,自动生成Build文件夹,这个complie_command文件里面指定了使用的交叉编译工具,可能会和tasks.json指定的不一致。

        这个下方的debug是CMakeFiles拓展,用的就是complie_command的配置 

                这个右上方的是VScode调试器的配置,用的就是tasks.json的配置

Windows+VSCode交叉编译在Linux-Arm环境上运行的程序 - 朔月の流光 - 博客园

VSCode与CMake搭配使用之交叉编译_vscode cmake 交叉编译-CSDN博客

问题

c_cpp_properties.json

        这个文件用于配置 C/C++ 代码的智能提示(IntelliSense)、编译器路径、包括的头文件路径等。它控制了 VSCode 中 C/C++ 代码的代码分析和自动补全功能。

常见的配置项:

        includePath:指定头文件的搜索路径,VSCode 会根据这些路径提供代码补全和智能提示。

        defines:定义编译时使用的宏。

        compilerPath:指定编译器的路径,通常是 gcc 或 clang,用于解析代码。

        intelliSenseMode:指定 VSCode 使用的 IntelliSense 模式,例如 gcc-x64 或 clang-x64。

{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**"
            ],
            "defines": [],
            "compilerPath": "C:/Program Files/MinGW/bin/gcc.exe",
            "cStandard": "c11",
            "cppStandard": "c++17",
            "intelliSenseMode": "gcc-x64"
        }
    ],
    "version": 4
}

        compilerPath:指定 C 编译器的路径(如 gcc)。

        includePath:头文件的查找路径,VSCode 会根据这些路径为你提供代码补全。

        intelliSenseMode:控制智能提示和代码解析器的行为,通常与编译器保持一致。 

launch.json

        launch.json 是调试配置文件,用于控制如何启动和调试 C/C++ 程序。它配置了调试器的运行环境,包括执行程序的路径、调试参数、调试类型等。

        program:要调试的可执行文件路径。

        args:传递给程序的命令行参数。

        cwd:运行调试时的工作目录。

        stopAtEntry:是否在程序入口点(如 main 函数)处停住,等待用户操作。

        miDebuggerPath:调试器的路径,通常是 gdb。

tasks.json

        tasks.json 文件用于配置编译任务。它告诉 VSCode 如何编译 C/C++ 代码。通过这个文件,你可以配置各种自动化任务,比如编译、清理项目等。

        label:任务的名称,用于在其他文件中引用(如 launch.json 中的 preLaunchTask)。

        command:执行的命令,例如 gcc。 args:传递给命令的参数,例如编译选项和源文件。

        group:任务的类型,可以是 build 或 test。

        problemMatcher:用于匹配编译器输出中的错误信息,以便在 VSCode 中高亮错误。

找不到头文件

        c-cpp-properties.json影响的是敲代码时候的智能感知功能,tasks.json才是编译时候去找头文件的主子。

        再就是对于CMake工程来讲,CMakeLists.txt的路径才是编译和链接时正确的路径。

vscode 找不到头文件 No such file or directory_vscode找不到头文件-CSDN博客

        七搞八搞找不到头文件,于是直接乱七八糟的都放到工程目录下,最后编译报错

../libXCloudSDK.so: error adding symbols: File in wrong format

         使用

 readelf -h .\libXCloudSDK.so

        发现 巨峰摄像头提供的linux库.so文件只适用于x86-64之类的架构,交叉编译思路卒。

            经过测试,对于CMakeLists.txt,是判断条件没起效果导致找不到头文件

# 针对顶层项目添加额外路径
if (${PROJECT_NAME}_IS_TOP_LEVEL)   #${PROJECT_NAME}_IS_TOP_LEVEL 这是个变量,需要明确设置set(${PROJECT_NAME}_IS_TOP_LEVEL TRUE)为真
    target_include_directories(${PROJECT_NAME} PUBLIC ../../include)
    target_link_directories(${PROJECT_NAME} PUBLIC ../../lib/${Internal_ARCH}/${CMAKE_BUILD_TYPE})
endif()

找不到外部库

        -L指定库路径,-l指定库文件

【.lib.dll / .a.so】Windows和Linux两个系统下的库文件_windows怎么使用.a静态库-CSDN博客

【C++】DLL和LIB的含义及使用场景和区别_window c++使用lib-CSDN博客

编译生成exe可执行,但是debug报错

ERROR: Unable to start debugging. Unexpected GDB output from command "-exec-run". During startup program exited with code 0xc0000135.

        我是把 .dll文件放到 main.c目录下再编译,就没这个错误了。

Linux操作系统vscode配置c++交叉编译环境