基于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. 总结

相关推荐
2401_826097622 小时前
JavaEE-Linux环境部署
java·linux·java-ee
(:满天星:)3 小时前
第31篇:块设备与字符设备管理深度解析(基于OpenEuler 24.03)
linux·运维·服务器·网络·centos
爱莉希雅&&&3 小时前
shell编程之awk命令详解
linux·服务器·git
笑稀了的野生俊3 小时前
在服务器中下载 HuggingFace 模型:终极指南
linux·服务器·python·bash·gpu算力
渡我白衣3 小时前
Linux操作系统之文件(四):文件系统(上)
linux
ZZH1120KQ4 小时前
Linux系统安全及应用
linux·运维·系统安全
程序漫游人4 小时前
centos8.5安装jdk21详细安装教程
java·linux
小小小糖果人4 小时前
Linux云计算基础篇(5)
linux·运维·服务器
small_wh1te_coder5 小时前
硬件嵌入式学习路线大总结(一):C语言与linux。内功心法——从入门到精通,彻底打通你的任督二脉!
linux·c语言·汇编·嵌入式硬件·算法·c
小张是铁粉5 小时前
docker在Linux的安装遇到的问题
linux·docker·容器