#opencv基于混合高斯的算法计算背景和前景
============================================
边遍历图像边抽取背景和前景
cv::Mat matFrame;
cv::Mat matForegroundMask;//前景图,黑白,0-255
cv::Mat matBackground;
//创建背景前景分割基类对象
cv::Ptr<cv::BackgroundSubtractor> pMog2;
//采用基于高斯混合的背景/前景分割算法实现前景后景分割。
pMog2 = cv::createBackgroundSubtractorMOG2();
//按照帧循环
for (int f = 0; f < m_VideoCtl.m_oWebCamData.m_iColectFCnt; f++)
{
//获取帧图像(假设图像内存是byColorImgDat)
matFrame = cv::Mat(m_iHeight, m_iWidth, CV_8UC3, byColorImgDat);
//采用基于混合高斯的算法计算前景蒙版
pMog2->apply(matFrame, matForegroundMask);
pMog2->getBackgroundImage(matBackground);
// 输出的前景图片并不是2值图片,要处理一下显示
cv::threshold(matForegroundMask, matForegroundMask, 220, 255, cv::THRESH_BINARY);
//腐蚀去掉小点
cv::Mat kenelMorph = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
cv::morphologyEx(matForegroundMask, matForegroundMask,cv::MORPH_OPEN, kenelMorph);//腐蚀
cv::morphologyEx(matForegroundMask, matForegroundMask,cv::MORPH_CLOSE, kenelMorph);//膨胀
cv::imshow("background", matBackground);
cv::imshow("frame", matFrame);
//显示前景蒙版
cv::imshow("fg mask mog2", matForegroundMask);
cv::waitKey(1);
}
============================================
先根据几帧图像获得背景,然后背景不变,抽取前景
cv::Mat matFrame;
cv::Mat matForegroundMask;//前景图,黑白,0-255
cv::Mat matBackground;
//创建背景前景分割基类对象
cv::Ptr<cv::BackgroundSubtractor> pMog2;
//采用基于高斯混合的背景/前景分割算法实现前景后景分割。
pMog2 = cv::createBackgroundSubtractorMOG2();
//一帧数据的缓存
int iPixCnt = m_VideoCtl.m_iWidth*m_VideoCtl.m_iHeight*3;
BYTE *byColorImgDat = new BYTE[iPixCnt];
//先根据平均的10帧图像,计算背景
int iStep = m_VideoCtl.m_oWebCamData.m_iColectFCnt / 10;
for (int f = 0; f < 10; f++)
{
m_VideoCtl.m_oWebCamData.GetFrmData(f*10, byColorImgDat, m_VideoCtl.m_bColorImgLeftRightTurn, NULL);
matFrame = cv::Mat(m_VideoCtl.m_iHeight, m_VideoCtl.m_iWidth, CV_8UC3, byColorImgDat);
//采用基于混合高斯的算法计算前景蒙版
pMog2->apply(matFrame, matForegroundMask);
}
//获取背景
pMog2->getBackgroundImage(matBackground);
cv::imshow("background", matBackground);
//逐帧与背景作差
for (int f = 0; f < m_VideoCtl.m_oWebCamData.m_iColectFCnt; f++)
{
m_VideoCtl.m_oWebCamData.GetFrmData(f * 10, byColorImgDat, m_VideoCtl.m_bColorImgLeftRightTurn, NULL);
matFrame = cv::Mat(m_VideoCtl.m_iHeight, m_VideoCtl.m_iWidth, CV_8UC3, byColorImgDat);
//最后一个参数取0-1.0,默认-1(自动), 0:代表背景不更新 1:代表把上一张图作为背景,不考虑之前的图
pMog2->apply(matFrame, matForegroundMask,0);
// 输出的前景图片并不是2值图片,要处理一下显示
cv::threshold(matForegroundMask, matForegroundMask, 220, 255, cv::THRESH_BINARY);
//腐蚀去掉小点
cv::Mat kenelMorph = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
cv::morphologyEx(matForegroundMask, matForegroundMask, cv::MORPH_OPEN, kenelMorph);//腐蚀
cv::morphologyEx(matForegroundMask, matForegroundMask, cv::MORPH_CLOSE, kenelMorph);//膨胀
//cv::imshow("background", matBackground);
cv::imshow("frame", matFrame);
//显示前景蒙版
cv::imshow("fg mask mog2", matForegroundMask);
cv::waitKey(100);
}
delete[]byColorImgDat;