OpenCV CUDA对象跟踪

背景差分法是在一系列视频帧中将前景对象从背景中分离出来的过程。它广泛应用于对象检测和跟踪应用中去除背景部分。背景差分法分四步进行:
1.图像预处理
2.背景建模
3.检测前景
4.数据验证
图像预处理通常用于去除图像中存在的各种噪声。第二步是对背景进行建模,以便将其与前景分离。在某些应用中,视频的第一帧作为背景不更新,后面每帧和第一帧之间的绝对差被用来分离前景和背景。
在其他技术中,通过对算法所看到的所有帧的平均值或中间值对背景进行建模,并将该背景与前景分离。与第一种方法相比,它对光照变化的鲁棒性更高,并且会产生更多动态背景。其他更具统计密集度的模型,如高斯模型和使用帧的历史的支持向量模型,也可以用于背景建模。
第三步是利用当前帧和背景之间的绝对差,将前景与模型背景分离。将这个绝对差与设置的阈值进行比较:如果大于阈值,则对象被认为是移动的;如果小于阈值,那么对象被认为是静止的。

MOG背景差分法

高斯混合法(MoG)是一种广泛使用的基于高斯混合的背景减法,用于分离前景和背景。背景从帧序列中不断更新,混合K高斯分布用于将像素分类为前景或背景,同时对帧的时间序列进行加权,以改善背景建模。连续变化的强度被归类为前景强度,静态强度被归类为背景强度。

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/cudabgsegm.hpp>

int main()
{
    cv::VideoCapture cap("abc.avi");
    if (!cap.isOpened())
    {
        std::cout << "can not open camera or video file" << std::endl;
        return -1;
    }

	cv::Mat frame;
    cap.read(frame);
	cv::cuda::GpuMat d_frame;
	d_frame.upload(frame);
	cv::Ptr<cv::BackgroundSubtractor> mog = cv::cuda::createBackgroundSubtractorMOG();
	cv::cuda::GpuMat d_fgmask,d_fgimage,d_bgimage;
	cv::Mat h_fgmask,h_fgimage,h_bgimage;
    mog->apply(d_frame, d_fgmask, 0.01);
    while(1)
    {
        cap.read(frame);
        if (frame.empty())
            break;
        d_frame.upload(frame);
        int64 start = cv::getTickCount();
        mog->apply(d_frame, d_fgmask, 0.01);
        mog->getBackgroundImage(d_bgimage);
        double fps = cv::getTickFrequency() / (cv::getTickCount() - start);
        std::cout << "FPS : " << fps << std::endl;
        d_fgimage.create(d_frame.size(), d_frame.type());
        d_fgimage.setTo(cv::Scalar::all(0));
        d_frame.copyTo(d_fgimage, d_fgmask);
        d_fgmask.download(h_fgmask);
        d_fgimage.download(h_fgimage);
        d_bgimage.download(h_bgimage);
		cv::imshow("image", frame);
		cv::imshow("foreground mask", h_fgmask);
		cv::imshow("foreground image", h_fgimage);
		cv::imshow("mean background image", h_bgimage);
        if (cv::waitKey(1) == 'q')
            break;
    }

    return 0;
}

createBackgroundSubtractorMOG类用于创建实现MoG的对象,它可以在创建对象时提供一些可选参数。这些参数包括history、nmixtures、backgroundRatio和 noiseSigma。history参数表示用于为背景建模的前一帧的数量,默认值是200; nmixture参数指定用于分离像素的高斯混合数,默认值是5。你可以根据应用程序使用这些值。
所创建对象的apply方法用于从第一帧创建前景掩码,需要一个输入图像和一个图像数组来存储作为输入的前景掩码和学习速率。在 while循环中的每一帧之后,这个前景掩码和背景图像都会不断更新。getBackgroundImage函数用于获取当前背景模型。
前景掩码用于创建前景图像,该图像指示当前正在移动的对象。它的基本逻辑是在原始帧和前景掩码之间操作。在每一帧之后,前景掩码、前景图像和建模的背景将被下载到主机内存中,以便在屏幕上显示。

GMG背景差分法

GMG算法的名称源自该算法发明人的姓名首字母,这个算法结合了背景估计与贝叶斯图像分割,使用贝叶斯推断将背景与前景分离,还使用帧的历史来建模背景。它再次基于帧的时间序列进行加权。新的观测比旧的观测的权重更高。

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/cudabgsegm.hpp>
#include <opencv2/cudalegacy.hpp>

int main()
{
	cv::VideoCapture cap("abc.avi");
    if (!cap.isOpened())
    {
        std::cout << "can not open video file" << std::endl;
        return -1;
    }
	cv::Mat frame;
    cap.read(frame);
	cv::cuda::GpuMat d_frame;
	d_frame.upload(frame);
	cv::Ptr<cv::BackgroundSubtractor> gmg = cv::cuda::createBackgroundSubtractorGMG(40);
	cv::cuda::GpuMat d_fgmask,d_fgimage,d_bgimage;
	cv::Mat h_fgmask,h_fgimage,h_bgimage;
    gmg->apply(d_frame, d_fgmask);

    while(1)
    {
        cap.read(frame);
        if (frame.empty())
            break;
        d_frame.upload(frame);
        int64 start = cv::getTickCount();
        gmg->apply(d_frame, d_fgmask, 0.01);
        double fps = cv::getTickFrequency() / (cv::getTickCount() - start);
        std::cout << "FPS : " << fps << std::endl;
        d_fgimage.create(d_frame.size(), d_frame.type());
        d_fgimage.setTo(cv::Scalar::all(0));
        d_frame.copyTo(d_fgimage, d_fgmask);
        d_fgmask.download(h_fgmask);
        d_fgimage.download(h_fgimage);
		cv::imshow("image", frame);
		cv::imshow("foreground mask", h_fgmask);
		cv::imshow("foreground image", h_fgimage);
        if (cv::waitKey(30) == 'q')
            break;
    }
    return 0;
}

createBackgroundSubtractorGMG类用于实现GMG创建的对象。它可以在创建对象时提供两个参数:第一个参数用于对背景建模的前一帧的数量,上面代码中取40﹔第二个参数是决策阈值,用于将像素分类为前景,其默认值为0.8。
所创建对象的 apply方法用于第一帧以创建前景掩码。通过使用帧的历史在while循环中不断更新前景掩码和前景图像,前景掩码用于与MoG类似的方式创建前景图像。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

给算法爸爸上香

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值