基于V4L2摄像头智能识别拍照(人脸和手掌)

1. 代码整个结构

2. 智能识别模块

c 复制代码
摄像头 → 读取 → 转换 → 缩放 → 🎯识别人脸/手掌 → 如有目标:保存图像
                                                    ↓
                                                合并 → 显示
c 复制代码
// detect_and_save.cpp
#include <opencv2/opencv.hpp>
#include <vector>
#include <string>
#include <ctime>
#include <unistd.h>

using namespace cv;
using namespace std;

static CascadeClassifier face_cascade;
static CascadeClassifier palm_cascade;
static bool initialized = false;

// 将像素数据(RGB)转为 OpenCV 图像,并检测人脸或手掌
extern "C" int DetectAndSaveIfNeeded(unsigned char *rgb_data, int width, int height)
{
    if (!initialized)
    {
        // 注意:路径需根据你系统中模型文件位置修改
        if (!face_cascade.load("/usr/share/opencv4/haarcascades/haarcascade_frontalface_default.xml"))
        {
            fprintf(stderr, "Failed to load face cascade\n");
            return -1;
        }
        if (!palm_cascade.load("/usr/share/opencv4/haarcascades/palm.xml")) // 自定义路径或手动下载
        {
            fprintf(stderr, "Failed to load palm cascade\n");
            return -1;
        }
        initialized = true;
    }

    // 构建 Mat 图像,RGB 格式
    Mat frame(height, width, CV_8UC3, rgb_data);

    // 转灰度图
    Mat gray;
    cvtColor(frame, gray, COLOR_BGR2GRAY);
    equalizeHist(gray, gray);

    // 检测人脸与手掌
    vector<Rect> faces, palms;
    face_cascade.detectMultiScale(gray, faces, 1.1, 3, 0, Size(30, 30));
    palm_cascade.detectMultiScale(gray, palms, 1.1, 3, 0, Size(50, 50));

    if (!faces.empty() || !palms.empty())
    {
        // 获取当前时间作为文件名
        time_t now = time(NULL);
        struct tm *t = localtime(&now);

        char filename[128];
        snprintf(filename, sizeof(filename), "/mnt/data/capture_%04d%02d%02d_%02d%02d%02d.jpg",
                 t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
                 t->tm_hour, t->tm_min, t->tm_sec);

        imwrite(filename, frame);
        printf("Saved: %s\n", filename);
        return 1;  // 表示检测成功
    }

    return 0; // 没检测到目标
}

3. 下载模型

下载手掌检测模型 palm.xml

c 复制代码
wget https://raw.githubusercontent.com/Aravindlivewire/Opencv/master/haarcascade/haarcascade_palm.xml -O ~/opencv/data/haarcascades/palm.xml

拷贝到目标板

c 复制代码
cp /home/book/opencv/data/haarcascades/palm.xml ~/nfs_rootfs/haarcascade/

4. 编译:

在# V4L2摄像头数据采集(读取、转换、缩放、合并、显示)的基础上

4.1 修改Makefire

  1. 添加对 C++ 编译器支持:
c 复制代码
CXX := $(CROSS_COMPILE)g++
export CXX
  1. 添加 OpenCV 头文件和链接库
c 复制代码
CFLAGS := -Wall -O2 -g
CFLAGS += -I $(shell pwd)/include
CFLAGS += -I/home/book/opencv-arm-install/include

LDFLAGS := -lm -ljpeg
LDFLAGS += -L/home/book/opencv-arm-install/lib \
           -Wl,-rpath=/home/book/opencv-arm-install/lib \
           -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_objdetect -lopencv_imgcodecs
  1. 添加 detect_and_save.o 到编译对象中(在 obj-y 区)
c 复制代码
obj-y += main.o
obj-y += detect_and_save.o       # ✅ 添加这一行
obj-y += convert/
obj-y += display/
obj-y += render/
obj-y += video/

4.2 修改Makefire.build

  1. 添加 .cpp 文件的编译规则(添加在其后)
c 复制代码
%.o : %.cpp
	$(CXX) $(CFLAGS) -Wp,-MD,$(dep_file) -c -o $@ $<

4.3 编译测试命令

c 复制代码
make clean
make

5. 运行

1. 出现错误:./video2lcd: error while loading shared libraries: libopencv_core.so.412: cannot open shared object file: No such file or directory

2. 原因: 在Ubuntu上交叉编译opencv得到的库没有拷贝到开发板

3. 拷贝到开发板:

确保目标目录在开发板存在且有权限:mkdir -p /usr/lib/opencv

使用scp拷贝

bash 复制代码
# 方法 1:NFS 挂载方式
cp /home/book/opencv-arm-install/lib/libopencv_*.so* /home/book/nfs_rootfs/opencv-lib/

# 方法 2:通过 scp 拷贝
scp /home/book/opencv-arm-install/lib/libopencv_*.so* root@192.168.x.x:/usr/lib/opencv/

运行错误:

bash 复制代码
/dev/video1 supports streaming i/o Convert yuv2rgb, ret = 0 terminate called after throwing an instance of 'cv::Exception' 
what(): OpenCV(4.12.0-dev) /home/book/opencv/modules/core/src/persistence.cpp:742: 
error: (-215:Assertion failed) buf in function 'open'

原因:模型下载失败,需重新下载

c 复制代码
wget https://raw.githubusercontent.com/Aravindlivewire/Opencv/master/haarcascade/palm.xml -O ~/opencv/data/haarcascades/palm.xml

复制到开发板

cp /home/book/opencv/data/haarcascades/haarcascade_frontalface_default.xml ~/nfs_rootfs/haarcascade/

移除GUI

bash 复制代码
mv  /etc/init.d/S99myirhmi2  /root
mv  /etc/init.d/S05lvgl  /root

实验过程中LCD过几分钟就黑屏,这是正常的。 可以关闭黑屏的功能,执行以下命令即可: echo -e "\0339;0" > /dev/tty0

6. 总结

相关推荐
AlfredZhao17 小时前
生产环境里,为什么不建议把普通端口直接暴露到公网?
linux·https·443·80
ForTime18 小时前
HAL库大雷预警!STM32 HAL库CAN启动超时解决办法
嵌入式
大辉狼_音频架构19 小时前
Vol. NXP SOF Arch
嵌入式
戴为沐2 天前
Linux内存扩容指南
linux
zylyehuo2 天前
Linux 彻底且安全地删除文件
linux
用户805533698033 天前
主线 U-Boot 上 RK3506:和闭源 rkbin 拔河的三个隐性契约
linux·嵌入式
用户034095297913 天前
linux fcitx 5 雾凇拼音 设置在中文输入法下仍然输入英文标点
linux
Web3探索者5 天前
可视化服务器管理和传统命令行区别是什么?新手教程:Linux 运维到底该用图形界面还是 SSH 命令行?
linux·ssh
zylyehuo5 天前
Linux系统中网线与USB网络共享冲突
linux
荣--6 天前
在 strip 二进制 + 基址随机化的栈里做崩溃去重 —— 三阶段算法与一行 Crash Flag
嵌入式·崩溃分析·栈指纹·去重算法