FFmpeg与openCV绝对是绝配。前面我们已经基本熟悉了FFmpeg的工作流程,这一章我们重点来看看openCV。
在前面,我们已经使用openCV打开过摄像头并在MFC中显示图像,但openCV能做的要远超你的想像,比如可以用它来实现人脸检测、车牌识别等,在AI领域,openCV早已声名鹊起。
这节课,我们先来看一个简单的例子:数豆豆。这个小例子可以让你领略openCV的强悍。
1.复制demo4并改名为demo12。
2.修改init函数:
//capCamHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)capCamThread, (LPVOID)this, 0, NULL);
capImgHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)capImgThread, (LPVOID)this, 0, NULL);
3.添加对应的数豆豆函数:
DWORD WINAPI fmle::capImgThread(LPVOID lpParam) {
fmle *pThis = (fmle*)lpParam;
pThis->capImg();
return 0;
}
int fmle::capImg() {
videoCap.open(0);
cv::Mat imgMat;
imgMat = cv::imread("Bean.jpg");
// 转换为HSV颜色空间
cv::Mat hsvMat;
cv::cvtColor(imgMat, hsvMat, cv::COLOR_BGR2HSV);
// 定义黄色范围的HSV阈值
cv::Scalar lowerColor(26, 43, 46);
cv::Scalar upperColor(34, 255, 255);
// 对图像进行颜色过滤
cv::Mat maskMat;
cv::inRange(hsvMat, lowerColor, upperColor, maskMat);
// 对二值图像进行形态学操作,去除噪点
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(5, 5));
cv::morphologyEx(maskMat, maskMat, cv::MORPH_OPEN, kernel);
// 寻找轮廓
std::vector<std::vector<cv::Point>> contours;
cv::findContours(maskMat, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
// 统计豆子数量
int beanCount = contours.size();
cv::Mat resultMat = imgMat.clone();
cv::drawContours(resultMat, contours, -1, cv::Scalar(0, 0, 255), 2);
cv::putText(resultMat, "Total: " + std::to_string(beanCount), cv::Point(0, 290), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 255, 255), 2);
mainDlg->drawMatOfPub(resultMat);
return 0;
}
4.调试运行,豆豆数量立即就显示出来了,是不是很简单?