FFmpeg与openCV绝对是绝配。前面我们已经基本熟悉了FFmpeg的工作流程,这一章我们重点来看看openCV。
在前面,我们已经使用openCV打开过摄像头并在MFC中显示图像,但openCV能做的要远超你的想像,比如可以用它来实现人脸检测、车牌识别等,在AI领域,openCV早已声名鹊起。
在实际应用中,我们常需要判断物体是否运动了,这可以利用openCV实现。
1.复制demo4并改名为demo12。
2.修改capCam函数:
int fmle::capCam() {
videoCap.open(0);
cv::Mat frame1, frame2;
BOOL ifSuccess = videoCap.read(frame1);
while (true)
{
BOOL ifSuccess = videoCap.read(frame2);
cv::Mat diff;
cv::absdiff(frame1, frame2, diff); // 计算两帧图像的差异
cv::Mat gray;
cv::cvtColor(diff, gray, cv::COLOR_BGR2GRAY); // 转换为灰度图像
cv::Mat blurred;
cv::GaussianBlur(gray, blurred, cv::Size(5, 5), 0); // 高斯模糊
cv::Mat thresholded;
cv::threshold(blurred, thresholded, 20, 255, cv::THRESH_BINARY); // 二值化
cv::Mat dilated;
cv::dilate(thresholded, dilated, cv::Mat(), cv::Point(-1, -1), 2); // 膨胀
std::vector<std::vector<cv::Point>> contours;
cv::findContours(dilated, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); // 查找轮廓
bool objectMoved = false;
for (const auto& contour : contours)
{
double area = cv::contourArea(contour);
if (area > 1000) // 设置最小轮廓面积阈值
{
objectMoved = true;
break;
}
}
if (objectMoved)
{
TRACE("物体移动了\n");
cv::putText(dilated, "Moving... ", cv::Point(0, 40), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 255, 255), 2);
}
else
{
cv::putText(dilated, "Stopping... ", cv::Point(0, 40), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 255, 255), 2);
TRACE("物体未移动\n");
}
frame1 = frame2.clone(); // 更新上一帧图像
mainDlg->drawMatOfPub(dilated);
Sleep(40);
}
videoCap.release();
return 0;
}
3.调试运行,当手挥动时会显示Moving,停止时则显示Stoping。