Created
June 9, 2016 18:17
-
-
Save ymuv/092e2a700c4ce6841e2384ed1ae2be03 to your computer and use it in GitHub Desktop.
opencv_tests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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