使用Absdiff的OpenCV背景减法

时间:2016-01-28 12:38:37

标签: c++ opencv camera

我一直在研究一种通过背景减少来检测手的程序。 我试图将相机的第一帧保存为背景并用当前帧减去,但似乎它们以某种方式具有不同的亮度。 我已经尝试了好几次而且没有变光,可能是什么问题? image1 image2

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include "Camera.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/background_segm.hpp>
using namespace cv;
using namespace std;
int main() {
    const int LAPTOP_CAM = 0;
    const int LIFECAM = 1;
    const int MAX_FPS = 25;
    Camera cam(LIFECAM);
    Mat backGround;

    cam.TakeShot();
    cam.MirrorImage();

    cam.getFrame().copyTo(backGround); //Deep Copy
    imshow("Background", backGround);
    Mat diff;
    while (true) {
        cam.TakeShot();
        cam.MirrorImage();
        absdiff(cam.getFrame(),backGround , diff);

        imshow("Result", cam.getFrame());
        imshow("Diff", diff);

        cam.Set_FPS(MAX_FPS);

        if (waitKey(1) == 27)
            break;

    }

}

这是“Camera.cpp”:

#include "Camera.h"
Camera::Camera()
{
}


Camera::~Camera()
{

}
Camera::Camera(int camNum)
{
    VideoCapture cap(camNum);
    _capture = cap;
}
void Camera::TakeShot()
{
    _capture >> _frame;
}
void Camera::Set_FPS(int fps)
{
    if (fps > 25)
        fps = 25;
    else if (fps < 1)
        fps = 1;
    _capture.set(CV_CAP_PROP_FPS, fps);
}
Mat Camera::getFrame()
{
    return _frame;
}
void Camera::MirrorImage()
{
    flip(_frame, _frame, 1);
}

3 个答案:

答案 0 :(得分:1)

应始终存在细微的光照变化,绝对减法几乎不会起作用。如果必须使用绝对不同,则可能需要阈值diff

但是,你应该研究一些背景减法算法。 OpenCV有一些内置方法:MOG2,KNN。

此外,您可以使用皮肤(颜色)检测来检测手。

答案 1 :(得分:0)

除了相机中的曝光补偿(可能是图像2中的问题 - 前景物体改变整体场景亮度),如果您使用荧光灯(可能还有LED)照明,还应该看一下闪烁的效果;由于灯光以AC线路频率开启和关闭,并且您的相机快门速度可能高于此值,因此在一张图像中可能会将灯光“打开”而在另一张图像中则“关闭”。

答案 2 :(得分:0)

我同意Quang Hoang使用背景减法算法会更好。 但是如果你想手动完成,那么你必须将最后一帧复制到背景中。

您可以尝试添加一行cam.getFrame().copyTo(backGround);,如下所示

while (true) {
    cam.TakeShot();
    cam.MirrorImage();
    absdiff(cam.getFrame(),backGround , diff);

    cam.getFrame().copyTo(backGround); // add this line

    imshow("Result", cam.getFrame());
    imshow("Diff", diff);