随笔,很随的那种。

1.复习一下shell编程。幸狐mpi例程里面的build.sh更新下,在编译完成之后可以使用ADB自动上传自动运行,提升效率。具体添加的在make install后面。

Build.sh

2.交叉编译一下数据库sqlite,方便以后用。buildroot系统基于uclibc构建,注意不要使用glibc。

去官网下载sqlite-autoconf开头的源码,tar -zxvf解压,然后进行配置。参数可以这样借鉴

./configure CC=FULL_PATH_OF_SDK/luckfox-pico/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/bin/arm-rockchip830-linux-uclibcgnueabihf-gcc --prefix=WHERE_YOU_WANT_TO_INSTALL --host=arm-rockchip830-linux-uclibcgnueabihf

3. 关于camke的示例,弄好之后cmake .制作makefile,接着make -j2 就ok了,至于install下次再学吧。copilot做小任务真好用。

cmake_minimum_required(VERSION 3.10)

# 项目信息
project(SQLiteTest)

# 设置交叉编译器,记得改FULL_PATH_OF_SDK
set(CMAKE_C_COMPILER FULL_PATH_OF_SDK/luckfox-pico/tools/linux/toolchain/arm-rockchip830-linux-uclibcgnueabihf/bin/arm-rockchip830-linux-uclibcgnueabihf-gcc)

# 设置SQLite的路径,记得改YOUR_PREFIX_PATH
set(SQLITE_PREFIX YOUR_PREFIX_PATH/sqlite-autoconf-3470000/Build)
set(SQLITE_LIB ${SQLITE_PREFIX}/lib)
set(SQLITE_INC ${SQLITE_PREFIX}/include)

# 包含目录
include_directories(${SQLITE_INC})

# 添加可执行文件
add_executable(main main.c)

# 链接库
target_link_libraries(main ${SQLITE_LIB}/libsqlite3.a)

附上copilot的测试代码。

#include <stdio.h>
#include <sqlite3.h>
#include <assert.h>

// Function to test SQLite connection, create table, insert and read data
int testSQLite() {
    sqlite3 *db;
    char *errMsg = 0;
    int rc;
    const char *sql;

    // Open database connection
    rc = sqlite3_open(":memory:", &db);
    if (rc) {
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        return 0;
    }

    // Create SQL table
    sql = "CREATE TABLE TEST (ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL);";
    rc = sqlite3_exec(db, sql, 0, 0, &errMsg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "SQL error: %s\n", errMsg);
        sqlite3_free(errMsg);
        sqlite3_close(db);
        return 0;
    }

    // Insert data into table
    sql = "INSERT INTO TEST (ID, NAME) VALUES (1, 'Alice');";
    rc = sqlite3_exec(db, sql, 0, 0, &errMsg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "SQL error: %s\n", errMsg);
        sqlite3_free(errMsg);
        sqlite3_close(db);
        return 0;
    }

    // Read data from table
    sql = "SELECT ID, NAME FROM TEST;";
    sqlite3_stmt *stmt;
    rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "Failed to fetch data: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return 0;
    }

    while (sqlite3_step(stmt) == SQLITE_ROW) {
        int id = sqlite3_column_int(stmt, 0);
        const unsigned char *name = sqlite3_column_text(stmt, 1);
        printf("ID: %d, Name: %s\n", id, name);
    }

    sqlite3_finalize(stmt);
    sqlite3_close(db);
    return 1;
}

// Main function for running the test
int main() {
    int result = testSQLite();
    assert(result && "SQLite test failed");
    printf("SQLite test passed\n");
    return 0;
}

4. RTSP测试

Rk的RTSP是udp协议的,不知道是不是因为pc的原因,延迟很大很大。目前vlc在ubuntu上有bug,需要用ffmpeg去播放。ffplay rtsp://192.168.10.200/live/0

5.视频性能和帧率的测试

I. 造成10帧的罪魁祸首已经找到了,不是我当初认为的文件写入,而是opencv。只要是牵扯到opencv的解码和打字幕帧率直接暴降不到10帧。目前来看文件不是瓶颈,需要做的就是放弃opencv,使用rk官方加速的库和OSD。

II. 今天也尝试了一下使用opencv进行运动检测,帧率更是直接掉到1.5帧,这也是不可以接受的。(倒是内存还挺够用哈哈

III. rk官方的图像库是带有顺序和异步模式的,这个很值得研究。下一步就是阅读手册,尝试学会使用rk的图像库,再进行优化。另外看起来rk官方还提供了windows下的模拟器(vs2022的项目),可以模拟rk芯片的环境,使用高性能设备来降低开发的时间成本,可能能用上,再研究。

IV. 码力下降了,使用cpp的opencv有点眼花缭乱,还是要练习啊!贴上cpp版本的代码,算法的提供者为Renu Khandelwal,文章链接在这里https://towardsdev.com/motion-detection-within-a-boundary-using-opencv-bd430516957

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 打开默认摄像头
    cv::VideoCapture cap(0);
    if (!cap.isOpened()) {
        std::cerr << "Error: Could not open webcam." << std::endl;
        return -1;
    }

    int frame_count = 0;
    int motion = 0;

    // 读取第一帧作为初始图像
    cv::Mat Prev_frame;
    cap >> Prev_frame;
    if (Prev_frame.empty()) {
        std::cerr << "Error: Could not read frame from webcam." << std::endl;
        return -1;
    }

    cv::Mat Prev_frame_gray;
    cv::cvtColor(Prev_frame, Prev_frame_gray, cv::COLOR_BGR2GRAY);
    cv::GaussianBlur(Prev_frame_gray, Prev_frame_gray, cv::Size(21, 21), 0);

    while (cap.isOpened()) {
        frame_count++;

        // 捕获每一帧
        cv::Mat Current_frame;
        cap >> Current_frame;
        if (Current_frame.empty()) {
            break;
        }

        cv::Mat Current_frame_gray;
        cv::cvtColor(Current_frame, Current_frame_gray, cv::COLOR_BGR2GRAY);
        cv::GaussianBlur(Current_frame_gray, Current_frame_gray, cv::Size(21, 21), 0);

        // 计算当前帧与前一帧的绝对差异
        cv::Mat frame_diff;
        cv::absdiff(Prev_frame_gray, Current_frame_gray, frame_diff);

        // 阈值化差异图像
        cv::Mat thresh;
        cv::threshold(frame_diff, thresh, 25, 255, cv::THRESH_BINARY);

        // 膨胀图像以填补空隙
        cv::dilate(thresh, thresh, cv::Mat(), cv::Point(-1, -1), 4);

        // 查找轮廓
        std::vector<std::vector<cv::Point>> contours;
        cv::findContours(thresh, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);

        for (const auto& cnt : contours) {
            if (cv::contourArea(cnt) < 500) {
                continue;
            }

            cv::Rect bounding_box = cv::boundingRect(cnt);
            if (bounding_box.x <= 840 && bounding_box.y >= 150 && bounding_box.y <= 350) {
                motion++;
                cv::rectangle(Prev_frame, bounding_box, cv::Scalar(255, 255, 0), 3);
                cv::putText(Prev_frame, "Motion detected", cv::Point(10, 20), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 255), 2);
            }
        }

        // 显示结果帧
        cv::imshow("feed", Prev_frame);

        // 更新前一帧
        Prev_frame_gray = Current_frame_gray.clone();

        if (cv::waitKey(1) == 'q') {
            break;
        }
    }

    cap.release();
    cv::destroyAllWindows();
    return 0;
}

6. 网络通讯问题,以及对SDK 结构的理解

根据幸狐的文档,修改优先级应该是没有问题的,但是没有说明原因。今天在执行rk_lunch.sh这个脚本的时候就发现问题了,这个脚本自己就有初始化网络的功能。所以把更新ip的脚本优先级挂的太高,提前进行年设置的ip地址会被rk_lunch替换。

方便自己找在这里也写一遍吧,

这也是幸狐官方没有点出来的问题,就是如何去建立自己的project

RK的设计其实就是在/project/app里面新建自己的项目文件夹,里面有完整的初始化和启动配置。具体怎么新建自己的项目目前还没有具体研究,但是SDK快速开发指南里面有提及。因为整合项目对我来说优先级比较低,就先把程序跑起来,自己再写启动脚本达到开机自启的效果。

所以我的下一步做什么呢?目前的想法是做视频录制后对文件手动rtsp,进程和阻塞这种系统编程技术的学习,然后把opencv移植到rk_MPI平台吧。这些干累了看看webServer(nginx,Angular,fastcgi,appweb,Uhttp这样的)。

散会。

Views: 34

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.