基于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 "\033[9;0]" > /dev/tty0

6. 总结

相关推荐
刘一说10 分钟前
CentOS 系统 Java 开发测试环境搭建手册
java·linux·运维·服务器·centos
wdxylb6 小时前
云原生俱乐部-shell知识点归纳(1)
linux·云原生
飞雪20077 小时前
Alibaba Cloud Linux 3 在 Apple M 芯片 Mac 的 VMware Fusion 上部署的完整密码重置教程(二)
linux·macos·阿里云·vmware·虚拟机·aliyun·alibaba cloud
路溪非溪7 小时前
关于Linux内核中头文件问题相关总结
linux
Lovyk10 小时前
Linux 正则表达式
linux·运维
Fireworkitte10 小时前
Ubuntu、CentOS、AlmaLinux 9.5的 rc.local实现 开机启动
linux·ubuntu·centos
sword devil90011 小时前
ubuntu常见问题汇总
linux·ubuntu
ac.char11 小时前
在CentOS系统中查询已删除但仍占用磁盘空间的文件
linux·运维·centos
淮北也生橘1213 小时前
Linux的ALSA音频框架学习笔记
linux·笔记·学习
华强笔记16 小时前
Linux内存管理系统性总结
linux·运维·网络