基于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* [email protected]:/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. 总结

相关推荐
多多*24 分钟前
微服务网关SpringCloudGateway+SaToken鉴权
linux·开发语言·redis·python·sql·log4j·bootstrap
IT界小黑的对象2 小时前
virtualBox部署ubuntu22.04虚拟机 NAT+host only 宿主机ping不通虚拟机
linux·运维·服务器
SilentCodeY2 小时前
Ubuntu 系统通过防火墙管控 Docker 容器
linux·安全·ubuntu·系统防火墙
weixin_527550402 小时前
Linux 环境下高效视频切帧的实用指南
linux·运维·音视频
keson要进步2 小时前
CICD实战(二)-----gitlab的安装与配置
linux·运维·gitlab
藥瓿亭3 小时前
K8S认证|CKS题库+答案| 4. RBAC - RoleBinding
linux·运维·服务器·云原生·容器·kubernetes·cks
吐泡泡_3 小时前
Linux(线程控制)
linux
全干工程师—3 小时前
FreeRTOS实时操作系统学习笔记
嵌入式·freertos·实时操作系统
tasselyue4 小时前
Macbook M3 使用 VMware Fusion 安装 openEuler24.03LTS
linux
行止64 小时前
MySQL主从复制与读写分离
linux·数据库·mysql