FFMPEG+SDL简单视频播放器——人脸检测
前言
最近突发奇想,给播放器加上一个人脸检测的功能(事情似乎朝着奇怪的方向发展了,谁家的播放器会需要去检测人脸啊😑!),主要的目的是为了学习opencv,尝试将ffmpeg和opencv融合在一起使用。这里着重展示opencv用于人脸检测部分的代码,播放器其余部分可以参考《FFMPEG+SDL简单视频播放器——视频播放》 和《FFMPEG+SDL简单视频播放器——视频快进》
实现
人脸检测
在之前写的播放器中,视频帧的格式为YUV420。在opencv处理图片前需要进行格式转化,将图片格式从YUV420转化成BGR。如果不进行格式转化,图片被opencv处理后的部分会出现颜色无法正常显示的问题
1 | cv::cvtColor(yuvimg, img, COLOR_YUV2BGR_I420); |
在检测到人脸后,用红框将人脸框起来
1 | if (faces.size() > 0) |
在opencv对图片处理完成后,将处理后的图片进行返回。这里用到了haarcascade_frontalface_alt2.xml文件,需要提前下载,或者从opecv的编译目录下复制过来。
完整的人脸检测函数如下
1 | cv::Mat detect_face(Mat yuvimg, int64_t times) |
视频播放
定义一个Mat,用于接收视频帧
1 | cv::Mat frameMat; |
在对AVFrame的格式进行转换后,将图像数据传递给Mat
1 | sws_scale(img_convert_ctx, (const unsigned char *const *)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize); |
调用detect_face函数对视频帧进行人脸检测,得到经过处理后的视频帧
1 | frameMat = detect_face(frameMat, pts); |
将视频帧传递给SDL,通过SDL进行播放
1 | SDL_UpdateTexture(sdlTexture, NULL, frameMat.data, frameMat.step); |
需要注意的地方是在ffmpeg,opencv和sdl之间进行图像数据的传递时,三者之间的图像数据格式。必要时需要进行图像格式转换,确保图像数据被正确的处理,否则会出现视频无法正常播放或者视频颜色无法正常显示的问题。
播放器的最新完整源码:https://github.com/canaconZion/streaming-practice/tree/main/opencv
在windows端编译opencv过程稍微有点繁琐,有空我会写一篇关于在windows端编译opencv源码的blog,帮大家避避坑
Makefile
1 | INC_DIR = ./include |
视频播放效果
- 标题: FFMPEG+SDL简单视频播放器——人脸检测
- 作者: HolyZion
- 创建于 : 2023-10-18 00:00:00
- 更新于 : 2023-11-18 00:11:07
- 链接: https://holyzion.host/2023/10/18/FFMPEG-SDL简单视频播放器——人脸检测/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。