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
相关产品推荐
相关产品推荐

