简体   繁体   中英

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

#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":

#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 .

However, you should look into some background subtraction algorithm. OpenCV has some built-in methods: 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; 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".

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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