运动目标检测 帧差法

帧差法是在连续的图像序列中两个或三个相邻帧间采用基于像素的时间差分并且二值化来提取图像中的运动区域。

#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

//计算二值化图中白色像素点个数
double bSums(Mat src)
{

    int counter = 0;
    //迭代器访问像素点  
    Mat_<uchar>::iterator it = src.begin<uchar>();
    Mat_<uchar>::iterator itend = src.end<uchar>();
    for (; it != itend; ++it)
    {
        if ((*it)==255) counter += 1;//二值化后,像素点是0或者255  
    }
    int size = src.cols*src.rows;
    return 1.0*counter/size;
}


int main(int argc, char** argv)
{
    VideoCapture capture(0);
    if (!capture.isOpened())
    {
        cout << "No camera !\n" << endl;
        return -1;
    }
    Mat frame;
    Mat gray;
    Mat gray_dilate1;
    Mat gray_dilate2;
    Mat gray_dilate3;
    Mat background, foreground, foreground_BW;
    Mat mid_filer;   //中值滤波法后的照片
    Mat frame_0, frame_1;//Mat m(3, 5, CV_32FC1, 1);
    int num = 0;
    //---------------------------------------------------------------------
    while (1)
    {
        capture >> frame;
        imshow("frame_resize", frame);
        cvtColor(frame, gray, CV_RGB2GRAY);
        //选择前一帧作为背景(读入第一帧时,第一帧作为背景)
        if (num == 0)
        {
            background = gray.clone();
            frame_0 = background;
        }
        else
        {
            background = frame_0;
        }
        absdiff(gray, background, foreground);//用帧差法求前景  做差求绝对值
        imshow("foreground", foreground);

        threshold(foreground, foreground_BW, 30, 255, 0);//二值化通常设置为50  255
        //threshold(foreground, foreground_BW, 0, 255 ,CV_THRESH_BINARY | CV_THRESH_OTSU) ;  //此处使用大津法  自适应取阈值
        imshow("foreground_BW", foreground_BW);
        medianBlur(foreground_BW, mid_filer, 3);     //中值滤波法

        double whilenum = bSums(mid_filer);
        cout << "white pixel num rate:" << whilenum << endl;

        //寻找最外层轮廓  
        vector<vector<Point>> contours;
        vector<Vec4i> hierarchy;
        findContours(mid_filer, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point());
        //Mat imageContours = Mat::zeros(mid_filer.size(), CV_8UC1); //最小外接矩形画布  

        for (int i = 0; i<contours.size(); i++)
        {
            //绘制轮廓  
            drawContours(mid_filer, contours, i, Scalar(255), 1, 8, hierarchy);
            //绘制轮廓的最小外结矩形  
            RotatedRect rect = minAreaRect(contours[i]);
            Point2f P[4];
            rect.points(P);
            for (int j = 0; j <= 3; j++)
            {
                line(mid_filer, P[j], P[(j + 1) % 4], Scalar(255), 2);
            }
        }
        imshow("mid_filer", mid_filer);
        frame_0 = gray.clone();
        num++;
        char c = waitKey(33);
        if (c == 27) break;

    }
}
  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值