简体   繁体   English

使用Absdiff的OpenCV背景扣除

[英]OpenCV Background substraction using Absdiff

I've been working about a program to detect hands by background substracting. 我一直在研究通过背景扣除来检测手的程序。 I have tried to save the first frame of a camera as Background and substract with current frame, but it appeared that they have different brightness somehow. 我试图将相机的第一帧保存为背景,并用当前帧减去,但看起来它们的亮度有所不同。 I've tried it several times and I dont have and light changing, what can be the problem? 我已经尝试过几次了,但是没有,而且灯光也没有变化,这可能是什么问题? image1 image2 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;

    }

}

here is "Camera.cpp": 这是“ 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);
}

There should always be subtle lighting change and absolute subtraction would hardly work. 始终应该有细微的灯光变化,绝对减法几乎不起作用。 If you have to use absolute different, you might want to threshold diff . 如果必须使用绝对不同,则可能需要对diff设置阈值。

However, you should look into some background subtraction algorithm. 但是,您应该研究一些背景减法算法。 OpenCV has some built-in methods: MOG2, KNN. OpenCV具有一些内置方法:MOG2,KNN。

Also, you can detect hands using skin (color) detection. 另外,您可以使用皮肤(颜色)检测来检测手。

Apart from exposure compensation in the camera (which could be the problem in image2 — the foreground object changes the overall scene brightness), you should also look at the effect of flickering if you're using fluorescent (and possibly LED) lighting; 除了相机中的曝光补偿(这可能是image2中的问题-前景物体会改变整个场景的亮度)之外,如果您使用的是荧光灯(可能还有LED)照明,还应该查看闪烁的效果; since the light turns on and off at your AC line frequency, and your camera shutter speed could be higher than that, it's possible that in one image it catches the light "on" and in another it's "off". 由于灯光会以AC线频率打开和关闭,并且您的相机快门速度可能会更高,因此,在一张图像中它可能会“打开”,而在另一张图像中会“关闭”。

i agree to Quang Hoang using background subtraction algorithm will be better. 我同意光背景使用背景减除算法会更好。 but if you want to do it manually then you must copy last frame to background. 但是如果要手动执行操作,则必须将最后一帧复制到背景。

could you try by adding a line cam.getFrame().copyTo(backGround); 你可以通过添加一行cam.getFrame().copyTo(backGround);来尝试cam.getFrame().copyTo(backGround); as seen below 如下所示

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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM