Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Motion detection using OpenCV/C++, threshold always become zero

I work on C++ crowd detection code with “OpenCV”, that takes 2 frames and subtracts them. Then compare the result with threshold.

This is the first time I deal with “OpenCV” for C++ and I don't have much information about it.

These are the steps of the code:

  1. Take two video frames with α minutes in between.
  2. Convert frames to black and white images.
  3. Subtract the two frames.
  4. Compare the difference with the threshold.
  5. If Difference <= threshold then crowd detected else--> there is no crowd.

c++ code:

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

using namespace std;
using namespace cv;

int main (int argc, const char * argv[])
{
//first frame.
Mat current_frame = imread("image1.jpg",CV_LOAD_IMAGE_GRAYSCALE);

//secunde frame.
Mat previous_frame = imread("image2.jpg",CV_LOAD_IMAGE_GRAYSCALE);

//Minus the current frame from the previous_frame and store the result.
Mat result = current_frame-previous_frame;

//compare the difference with threshold, if the deference <70 -> there is crowd.
//if it is > 70 there is no crowd
int threshold= cv::threshold(result,result,0,70,CV_THRESH_BINARY);

if (threshold==0) {
    cout<< "crowd detected \n";
}
else {
    cout<<" no crowd detected \n ";
}   
}

The problem is : The threshold always be zero! and the output always: crowd detected even if there is no crowd

We don't care about the output image because we won't use it, and we just want to know the last value of threshold.

My aim is to know how much deference between 2 frames. I want to compare the deference with threshold to detect the human crowd in specific place

I hope that one of you can help me

Thank you

like image 455
Afnan Avatar asked Feb 03 '26 20:02

Afnan


1 Answers

there's a couple of flaws in your usage of the threshold function

  • it just returns the threshold value ( not what you expected )
  • 'We don't care about the output image' - well, you'd better!
  • if you want to threshold against a value of 70, that should be your 3rd arg, not the 4th (the 4th arg is the value, anything >thresh is set to

what you probably wanted, is :

cv::threshold(result,result,70,1, CV_THRESH_BINARY); // same as : result = result>70;
int on_pixels = countNonZero(result);
// or:
int on_pixels = sum(result)[0];

[sidenote: if you really want to detect human crowds, you'll have to put much more sweat into this. just diff'ing frames is prone to err with illumination changes, also, there's birds, cars and traffic lights]

like image 186
berak Avatar answered Feb 05 '26 10:02

berak