You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenCV人脸检测调用aplay反复播放音频,如何实现每5秒播放一次?

问题分析与修改方案

当前问题是每帧只要检测到人脸就会触发播放逻辑,视频流高帧率下会重复调用aplay导致回声问题,我们通过新增时间间隔控制逻辑即可实现连续检测到人脸时每5秒仅播放一次音频的需求。

修改思路

  • 新增3个全局变量:记录上次播放音频的时间戳、固定播放间隔(5秒)
  • 将播放逻辑从人脸遍历循环中移出,避免同时检测到多个人脸时重复触发播放
  • 每次检测到人脸后,先计算当前时间与上次播放时间的差值,差值大于等于5秒时才执行播放操作,同时更新上次播放时间
  • 若当前帧未检测到人脸,重置上次播放时间,保证人脸再次出现时可以立即触发首次播放

修改后的完整代码

#include "opencv2/objdetect.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"

#include <iostream>
#include <stdio.h>
#include <ctime>

using namespace std;
using namespace cv;

/** Global variables */
String faceCascadePath;
CascadeClassifier faceCascade;
time_t lastPlayTime = 0;
const int PLAY_INTERVAL = 5; // 播放间隔,单位为秒

void detectFaceOpenCVHaar(CascadeClassifier faceCascade, Mat &frameOpenCVHaar, int inHeight=300, int inWidth=0)
{
    int frameHeight = frameOpenCVHaar.rows;
    int frameWidth = frameOpenCVHaar.cols;
    if (!inWidth)
        inWidth = (int)((frameWidth / (float)frameHeight) * inHeight);

    float scaleHeight = frameHeight / (float)inHeight;
    float scaleWidth = frameWidth / (float)inWidth;

    Mat frameOpenCVHaarSmall, frameGray;
    resize(frameOpenCVHaar, frameOpenCVHaarSmall, Size(inWidth, inHeight));
    cvtColor(frameOpenCVHaarSmall, frameGray, COLOR_BGR2GRAY);

    std::vector<Rect> faces;
    faceCascade.detectMultiScale(frameGray, faces);

    // 绘制人脸框
    for ( size_t i = 0; i < faces.size(); i++ )
    {
      int x1 = (int)(faces[i].x * scaleWidth);
      int y1 = (int)(faces[i].y * scaleHeight);
      int x2 = (int)((faces[i].x + faces[i].width) * scaleWidth);
      int y2 = (int)((faces[i].y + faces[i].height) * scaleHeight);
      rectangle(frameOpenCVHaar, Point(x1, y1), Point(x2, y2), Scalar(0,255,0), (int)(frameHeight/150.0), 4);
    }

    // 新增播放控制逻辑
    if (faces.size() > 0) {
        time_t now = time(NULL);
        if (difftime(now, lastPlayTime) >= PLAY_INTERVAL) {
            string str1 = "aplay out.wav & ";
            const char *command = str1.c_str();
            system(command);
            lastPlayTime = now;
        }
    } else {
        // 无人脸时重置时间,下次人脸出现可立即触发播放
        lastPlayTime = time(NULL) - PLAY_INTERVAL;
    }
}


int main( int argc, const char** argv )
{
    faceCascadePath = "haarcascade_frontalface_default.xml";
    if(!faceCascade.load(faceCascadePath))
    {
        printf("--(!)Error loading face cascade\n");
        return -1;
    }

    VideoCapture source(1);
    //if (argc == 1)
    //    source.open(0, CAP_V4L);
    //else
    //    source.open(argv[1]);  
    Mat frame;

    double tt_opencvHaar = 0;
    double fpsOpencvHaar = 0;

    while (true)
    {
        source >> frame;
        if (frame.empty())
            break;

        double t = cv::getTickCount();
        detectFaceOpenCVHaar(faceCascade, frame);
        tt_opencvHaar = ((double)cv::getTickCount() - t)/cv::getTickFrequency();
        fpsOpencvHaar = 1/tt_opencvHaar;
         
        putText(frame, format("OpenCV HAAR ; FPS = %.2f",fpsOpencvHaar), Point(10, 50), FONT_HERSHEY_SIMPLEX, 1.3, Scalar(0, 0, 255), 4);

        imshow("OpenCV - HAAR Face Detection", frame);

        int k = waitKey(5);
        if(k == 27)
        {
            destroyAllWindows();
            break;
        }
    }
}

编译运行命令

g++ face_detection_.cpp -o face_det `pkg-config --cflags --libs opencv4`
./face_det

内容的提问来源于stack exchange,提问作者anshika singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 16:45:04