Skip to content

Instantly share code, notes, and snippets.

@ymuv
Created June 9, 2016 18:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ymuv/092e2a700c4ce6841e2384ed1ae2be03 to your computer and use it in GitHub Desktop.
Save ymuv/092e2a700c4ce6841e2384ed1ae2be03 to your computer and use it in GitHub Desktop.
opencv_tests
/**
* Program to detection motion using simple background substraction
* get 2 images [3 image - diff]
*/
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#define SHOW
#define AREA_MIN_SIXE 1800
#define AREA_MAX_SIZE 1000000
cv::Mat aGlobal, bGlobal;
int minTreshHoldValue = 35;
int cameraId = 1;
bool writeDiff = false;
using namespace cv;
bool intruderAlarm(cv::Mat& a, cv::Mat& b)
{
// Blur images to reduce noise
cv::Mat a_blurred, b_blurred;
//cv::blur(a, a_blurred, cv::Size(4,4));
//cv::blur(b, b_blurred, cv::Size(4,4));
a_blurred = a;
b_blurred = b;
// Get absolute difference image
cv::Mat c;
cv::absdiff(b_blurred, a_blurred, c);
// Split image to each channels
std::vector<cv::Mat> channels;
cv::split(c, channels);
// Apply threshold to each channel and combine the results
cv::Mat d = cv::Mat::zeros(c.size(), CV_8UC1);
int size = channels.size();
//lower CPU
if (size == 3)
size = 2;
for (int i = 0; i < size; i++)
{
cv::Mat thresh;
cv::threshold(channels[i], thresh, minTreshHoldValue, 255, CV_THRESH_BINARY);
d |= thresh;
}
// Perform morphological close operation to filling in the gaps
cv::Mat kernel, e;
cv::getStructuringElement(cv::MORPH_RECT, cv::Size(10,10));
cv::morphologyEx(d, e, cv::MORPH_CLOSE, kernel, cv::Point(-1,-1), 5);
// Find all contours
std::vector<std::vector<cv::Point> > contours;
cv::findContours(e.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
// Select only large enough contours
std::vector<std::vector<cv::Point> > intruders;
for (int i = 0; i < contours.size(); i++)
{
double area = cv::contourArea(contours[i]);
if (area > AREA_MIN_SIXE && area < AREA_MAX_SIZE) {
//std::cout << " area: " << area << std::endl;
#ifndef __SHOW__
if (!writeDiff) {
//return true;
}
#endif
intruders.push_back(contours[i]);
}
}
std::cout << "size " << contours.size() << " " << intruders.size() << std::endl;
//std::cout << "size " << contours.size() << std::endl;
//std::cout << "size " << intruders.size() << std::endl;
// Use the filtered blobs above to create a mask image to
// extract the foreground object
cv::Mat mask = cv::Mat::zeros(b.size(), CV_8UC3);
cv::drawContours(mask, intruders, -1, CV_RGB(255,255,255), -1);
cv::imshow("mask", mask);
// Highlight the foreground object by darken the rest of the image
if (intruders.size())
{
//b = (b/4 & ~mask) + (b & mask);
//cv::drawContours(b, intruders, -1, CV_RGB(255,255, 0), 2);
bGlobal = (bGlobal/4 & ~ mask) + (bGlobal & mask);
cv::drawContours(bGlobal, intruders, -1, CV_RGB(255,0, 0), 2);
cv::drawContours(c, intruders, -1, CV_RGB(255,0, 0), 2);
cv::imshow("c", c);
return true;
}
//cv::imshow("c", c);
return false;
}
int main() {
CvCapture* capture;
Mat frame;
Mat prev;
cv::Mat prevGrey, curGrey;
capture = cvCaptureFromCAM(cameraId);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 1280);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 1024);
if(capture) {
while(true) {
frame = cvQueryFrame(capture);
if(!frame.empty()) {
if (prev.empty()) {
frame.copyTo(prev);
continue;
}
frame.copyTo(bGlobal);
cv::cvtColor(bGlobal, curGrey, CV_BGR2GRAY);
cv::cvtColor(prev, prevGrey, CV_BGR2GRAY);
if (intruderAlarm(curGrey, prevGrey)) {
std::cout << "move fountd " << std::endl;
}
cv::imshow("cur", bGlobal);
cv::imshow("curGrey", curGrey);
cv::imshow("prevGrey", prevGrey);
frame.copyTo(prev);
cv::waitKey(300);
}
}
}
}
int mainOld(int argc, char **argv) {
#if 0
for (int i = 0; i < argc; i++) {
std::cout << " " << argv[i];
}
std::cout << std::endl;
#endif
if (!(argc == 3 || argc == 4)) {
std::cout << "argv must == 3 || == 4, but = " << argc << std::endl;
return 100;
}
if (argc == 4) {
writeDiff = true;
}
char *aImg = argv[1];
char *bImg = argv[2];
// Load images
aGlobal = cv::imread(aImg);
bGlobal = cv::imread(bImg);
if (aGlobal.empty()) {
std::cout << " failed to open image1 " << aImg << std::endl;
return 0;
}
if (bGlobal.empty()) {
std::cout << " failed to open image2 " << bImg << std::endl;
return 0;
}
cv::Mat aGrey, bGrey;
cv::cvtColor(aGlobal, aGrey, CV_BGR2GRAY);
cv::cvtColor(bGlobal, bGrey, CV_BGR2GRAY);
// Start motion detection
// bool hasMove = intruderAlarm(a, b);
bool hasMove = intruderAlarm(aGrey, bGrey);
// Display result
#ifdef __SHOW__
cv::imshow("a", aGlobal);
cv::imshow("b", bGlobal);
#endif
if (writeDiff && hasMove) {
cv::imwrite(argv[3], bGlobal);
}
#ifdef __SHOW__
cv::waitKey(0);
cv::waitKey(0);
#endif
if (hasMove) {
std::cout << "move detection on " << aImg << " and " << bImg << std::endl;
}
return hasMove;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment