主要用于摄像头固定,可以有效的更新背景,减少光照的因素的影响。
背景更新主要使用到了addweight这个函数
背景更新的公式
background = background + (frame - background) * alpha = background * (1 - alpha) + frame * alpha
alpha 更新速度
在opencv中也存在accumulateWeighted函数,与addweight函数实现功能一样,使用时候需要注意数据类型
src 输入图像 dst 输出图像
src.depth() == CV_8U && dst.depth() == CV_32F
src.depth() == CV_8U && dst.depth() == CV_64F
src.depth() == CV_16U && dst.depth() == CV_32F
src.depth() == CV_16U && dst.depth() == CV_64F
src.depth() == CV_32F && dst.depth() == CV_32F
src.depth() == CV_32F && dst.depth() == CV_64F
src.depth() == CV_64F && dst.depth() == CV_64F
Mat.converto(Mat,数据类型);实现图像的数据类型转换。
convertScaleAbs(src,dst) 先缩放元素再取绝对值,最后转换格式为8bit型
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include<iostream>
#include<string>
using namespace cv;
using namespace std;
int main()
{
string videofilename = "00011.AVI";
VideoCapture video;
video.open(videofilename);
if (!video.isOpened()) //判断视频是否读入
{
cout << "video open false" << endl;
return 1;
}
float alpha = 0.01;
int threhold = 25;
Mat frame;
Mat grayframe;
Mat grayMat;
Mat background;
Mat grayback;
Mat fromground;
Mat grayfrom;
while (video.read(frame)) //读入每一帧视频给frame
{
cvtColor(frame, grayframe, CV_RGB2GRAY);
grayframe.convertTo(grayMat,CV_32FC1); //变图片的数据格式
if (grayback.empty())
{
grayframe.copyTo(background);
grayframe.convertTo(grayback, CV_32FC1);
}
absdiff(grayMat, grayback, grayfrom); //图片对应像素相减取绝对值
addWeighted(grayback, alpha, grayfrom, 1 - alpha, 0, grayback);
threshold(grayfrom, grayfrom, threhold, 255, CV_THRESH_BINARY);
convertScaleAbs(grayfrom, fromground); //
convertScaleAbs(grayback, background);
convertScaleAbs(grayMat, frame);
imshow("frame", frame);
imshow("background", background);
imshow("fromground", fromground);
waitKey(30);
}
return 0;
}
frame图片
background图片
fromground图片
opencv当中还有高斯混合模型,后续