【发布时间】:2021-06-19 20:02:40
【问题描述】:
每当使用 C++ (LINUX) 中的 opencv 在相机中检测到人脸时,我都会尝试播放一个小音频 (.wav) 文件。
#include "opencv2/objdetect.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
/** Global variables */
String faceCascadePath;
CascadeClassifier faceCascade;
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);
//// ==== AUDIO PLAY CODE BEGINS ======= ////
string str1 = "aplay ";
str1 = str1 + " out.wav" + " & ";
const char *command = str1.c_str();
system(command);
//// ==== AUDIO CODE ENDS ======== /////
}
}
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;
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;
}
}
}
现在发生的情况是,每当一个人在镜头前停留更长时间时,相机就会不断检测面部,并且声音文件会不断尝试播放,但由于设备已经忙于播放声音,因此在控制台上会出现错误。当然我可以听到警报,但是如何在警报已经播放时停止同时播放警报,或者如何让他们在声音文件完成之前等待。 这种对声音文件播放的持续调用也会减慢代码的速度。如何修复此错误并优化音频播放使其不会对 cpu 造成压力?
错误:-
Playing WAVE 'out.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
Playing WAVE 'out.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
aplay : audio open error: Device or resource busy
我需要帮助:使声音播放流畅且不占用 CPU。人脸检测以大约 30fps 的速度发生,因此对于每一帧,声音都在尝试播放,这是不可能的,并且可能会减慢代码速度。
【问题讨论】:
标签: c++ linux asynchronous audio