how to track foreground in video and draw rectangle on it - c++

I'm working in a motion detection script that tracking people.
I used foreground function MOG2 and it does what I want to do. In the next step, I want to draw a rectangle around moving people but I get an error when I run it.
Are there any ideas on how to fix it?
The error:
OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat, file /home/shar/opencv/modules/core/src/array.cpp, line 2494
terminate called after throwing an instance of 'cv::Exception'
what(): /home/shar/opencv/modules/core/src/array.cpp:2494: error: (-206) Unrecognized or unsupported array type in function cvGetMat
Aborted
This is my code:
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector>
#include <iostream>
#include <sstream>
#include <opencv2/video/background_segm.hpp>
#include <opencv2/video/background_segm.hpp>
using namespace std;
using namespace cv;
int main()
{
//Openthevideofile
cv::VideoCapture capture(0);
cv::Mat frame;
Mat colored;
//foregroundbinaryimage
cv::Mat foreground;
int largest_area=0;
int largest_contour_index=0;
Rect bounding_rect;
cv::namedWindow("ExtractedForeground");
vector<vector<Point> > contours; // Vector for storing contour
vector<Vec4i> hierarchy;
findContours( frame, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
//checkifvideosuccessfullyopened
if (!capture.isOpened())
return 0;
//currentvideoframe
//TheMixtureofGaussianobject
//used with all default parameters
cv::Ptr<cv::BackgroundSubtractorMOG2> pMOG2 = cv::createBackgroundSubtractorMOG2();
bool stop(false);
// testing the bounding box
//forallframesinvideo
while(!stop){
//readnextframeifany
if(!capture.read(frame))
break;
//updatethebackground
//andreturntheforeground
float learningRate = 0.01; // or whatever
cv::Mat foreground;
pMOG2->apply(frame, foreground, learningRate);
//learningrate
//Complementtheimage
cv::threshold(foreground,foreground,128,255,cv::THRESH_BINARY_INV);
//showforeground
for( int i = 0; i< contours.size(); i++ )
{
// Find the area of contour
double a=contourArea( contours[i],false);
if(a>largest_area){
largest_area=a;cout<<i<<" area "<<a<<endl;
// Store the index of largest contour
largest_contour_index=i;
// Find the bounding rectangle for biggest contour
bounding_rect=boundingRect(contours[i]);
}
}
Scalar color( 255,255,255); // color of the contour in the
//Draw the contour and rectangle
drawContours( frame, contours,largest_contour_index, color, CV_FILLED,8,hierarchy);
rectangle(frame, bounding_rect, Scalar(0,255,0),2, 8,0);
cv::imshow("ExtractedForeground",foreground);
cv::imshow("colord",colored);
//introduceadelay
//orpresskeytostop
if(cv::waitKey(10)>=0)
stop=true;
}
}

Your code fails because you are calling findContours on frame, which is not initialized until the while loop.
You have also issues in finding the largest contour, since you don't reset largest_area and largest_contour_index at each iteration, so it will fail in case you don't find a contour in the current frame.
This code should be what you meant to do.
You can find a related answer here.
The code here is the port to OpenCV 3.0.0, plus noise removal using morphological open.
#include <opencv2\opencv.hpp>
#include <vector>
using namespace cv;
using namespace std;
int main(int argc, char *argv[])
{
Ptr<BackgroundSubtractorMOG2> bg = createBackgroundSubtractorMOG2(500, 16, false);
VideoCapture cap(0);
Mat3b frame;
Mat1b fmask;
Mat kernel = getStructuringElement(MORPH_RECT, Size(3,3));
for (;;)
{
// Capture frame
cap >> frame;
// Background subtraction
bg->apply(frame, fmask, -1);
// Clean foreground from noise
morphologyEx(fmask, fmask, MORPH_OPEN, kernel);
// Find contours
vector<vector<Point>> contours;
findContours(fmask.clone(), contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE);
if (!contours.empty())
{
// Get largest contour
int idx_largest_contour = -1;
double area_largest_contour = 0.0;
for (int i = 0; i < contours.size(); ++i)
{
double area = contourArea(contours[i]);
if (area_largest_contour < area)
{
area_largest_contour = area;
idx_largest_contour = i;
}
}
if (area_largest_contour > 200)
{
// Draw
Rect roi = boundingRect(contours[idx_largest_contour]);
drawContours(frame, contours, idx_largest_contour, Scalar(0, 0, 255));
rectangle(frame, roi, Scalar(0, 255, 0));
}
}
imshow("frame", frame);
imshow("mask", fmask);
if (cv::waitKey(30) >= 0) break;
}
return 0;
}

Related

Detect different types of drops on a card Using OpenCV findContours

I'm trying to identify drops on a water-sensitive card, as you can see in the figure below, in addition to the drops there are water risks that I don't want to account for. I'm using OpenCV's findContours function to detect these contours, the question is: can I separate the real drops, from the water drips on the card? Here is an excerpt from my code.
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
Mat src; Mat src_gray; Mat binary_image, goTo;
int thresh = 100;
int max_thresh = 255;
RNG rng(12345);
cv::Scalar min_color_scanner = Scalar(0,0,0);
cv::Scalar max_color_scanner = Scalar(255,175,210);
int main(int argc, char** argv){
cv::Mat image, gray, thresh;
// MARK:- Load image, grayscale, Otsu's threshold
image = imread("/Users/user/Documents/Developer/Desktop/OpenCV-Teste3.3.1/normal1.png");
Mat circles_detect;
cvtColor( image, circles_detect, CV_BGR2GRAY );
GaussianBlur( circles_detect, circles_detect, Size(9, 9), 2, 2 );
//END CIRCLES
cvtColor(image, gray, CV_BGR2GRAY);
threshold(gray, thresh, 0, 255, THRESH_BINARY_INV + THRESH_OTSU);
Mat mask(image.rows, image.cols, CV_8UC3, Scalar(255,255,255));
cv::Mat bgr_image, inRangeImage;
cv::cvtColor(image, bgr_image, CV_RGB2BGR);
cv::inRange(bgr_image, min_color_scanner, max_color_scanner, binary_image);
//Find contours and filter using contour area
vector<vector<Point>> contours;
cv::findContours(thresh, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
// MARK:- data from image
double largest_area=0.0;
int largest_contour_index=0;
double smallest_area=0.0;
int smallest_contour_index=0;
int drop_derive=0;
Rect boundig_rect;
for(int i=0;i<contours.size();i++){
double area = contourArea(contours[i]);
if(area > largest_area){
largest_area=area;
largest_contour_index = i;
//boundig_rect = boundingRect(contourArea(contours[i]));
}
}
smallest_area = largest_area;
for(int i=0;i<contours.size();i++){
double area = contourArea(contours[i]);
if(area < smallest_area){
smallest_area=area;
smallest_contour_index = i;
//boundig_rect = boundingRect(contourArea(contours[i]));
}
if (area < 4){
drop_derive++;
cv::drawContours(image, contours, i, Scalar(255,0,0));
}
}
//show datas and images..
return(0);
}

opencv getPerspectiveTransform not working

so I am working on an assignment in which I have to classify road signs based on input images. So naturally I used the canny function, and findContours, followed by approxPolyPD in order to get the corners of the image that I will be transforming.
However for some reason, I keep getting an error when I attempt to use getPerspectiveTransform for the next step. Please help.
Error:
OpenCV Error: Assertion failed (0 <= i && i < (int)vv.size()) in getMat_, file /home/path_to_opencv/opencv/modules/core/src/matrix.cpp, line 1192
terminate called after throwing an instance of 'cv::Exception'
what(): /home/path_to_opencv/opencv/modules/core/src/matrix.cpp:1192: error: (-215) 0 <= i && i < (int)vv.size() in function getMat_
Aborted (core dumped)
Code used:
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define WARPED_XSIZE 200
#define WARPED_YSIZE 300
using namespace cv;
using namespace std;
Mat src; Mat src_gray, warped_result; Mat dst;
Mat speed_80, speed_40;
int canny_thresh = 154;
#define VERY_LARGE_VALUE 100000
#define NO_MATCH 0
#define STOP_SIGN 1
#define SPEED_LIMIT_40_SIGN 2
#define SPEED_LIMIT_80_SIGN 3
RNG rng(12345);
/** #function main */
int main(int argc, char** argv)
{
int sign_recog_result = NO_MATCH;
speed_40 = imread("speed_40.bmp", 0);
speed_80 = imread("speed_80.bmp", 0);
// you run your program on these three examples (uncomment the two lines below)
//string sign_name = "stop4";
string sign_name = "speedsign12";
//string sign_name = "speedsign3";
//string sign_name = "speedsign4";
string final_sign_input_name = sign_name + ".jpg";
string final_sign_output_name = sign_name + "_result" + ".jpg";
/// Load source image and convert it to gray
src = imread(final_sign_input_name, 1);
/// Convert image to gray and blur it
cvtColor(src, src_gray, COLOR_BGR2GRAY);
blur(src_gray, src_gray, Size(3, 3));
warped_result = Mat(Size(WARPED_XSIZE, WARPED_YSIZE), src_gray.type());
// here you add the code to do the recognition, and set the variable
// sign_recog_result to one of STOP_SIGN, SPEED_LIMIT_40_SIGN, SPEED_LIMIT_80_SIGN, or NO_MATCH
// PART 1 of Assignment 2
Mat canny_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
Canny(src_gray, canny_output, canny_thresh, canny_thresh*2, 3);
findContours(canny_output, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(0, 0));
vector<vector<Point> > contours_poly(contours.size());
for (unsigned int i = 0; i < contours.size(); ++i) {
approxPolyDP(Mat(contours[i]), contours_poly[i], contours_poly[i].size()*.02, true);
}
// Part 2 of Assignment 2
vector<vector<Point> > transform_result(contours_poly.size());
warped_result = getPerspectiveTransform(contours_poly, transform_result);
warpPerspective(src, dst, warped_result, dst.size());
//imshow("input", src);
//imshow("output", dst);
/*
Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
for(unsigned int i = 0; i< contours_poly.size(); i++ ) {
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
drawContours( drawing, contours_poly, i, color, 2, 8, hierarchy, 0, Point() );
}
// Show in a window
namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
imshow( "Contours", drawing );
//*/
// Returning to the predetermined code.
string text;
if (sign_recog_result == SPEED_LIMIT_40_SIGN) text = "Speed 40";
else if (sign_recog_result == SPEED_LIMIT_80_SIGN) text = "Speed 80";
else if (sign_recog_result == STOP_SIGN) text = "Stop";
else if (sign_recog_result == NO_MATCH) text = "Fail";
int fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX;
double fontScale = 2;
int thickness = 3;
cv::Point textOrg(10, 130);
cv::putText(src, text, textOrg, fontFace, fontScale, Scalar::all(255), thickness, 8);
/// Create Window
char* source_window = "Result";
namedWindow(source_window, WINDOW_AUTOSIZE);
imshow(source_window, src);
imwrite(final_sign_output_name, src);
waitKey(0);
return(0);
}

Object detection with simpleBlobDetector, but it doesn't work

I have a problem with the code for the simpleBlobDetector. I can build and run all the code just fine, but the blobs that the program detects are only the size of a pixel or so. I've already tried to change the param.minArea and maxArea but it doesn't work. So Im asking you guys for help. By the way the image i was using is in grayscale already so it isn't because of my threshold command that it isn't working. Thanks before hand!
Martin.
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main(){
Mat src;
Mat dst;
src = imread("C:\\Users\\martin\\Desktop\\ThermalImage2.png", CV_LOAD_IMAGE_GRAYSCALE); //Load an image from directory path
if (! src.data){
cout << "Could not open or find the image" << endl ; // Look for invalid input
return -1;
}
else{
double thresh = 130; // Threshold
double maxValue = 255; // Value assigned to the pixel if it is over 'thresh'
threshold(src, dst, thresh, maxValue, THRESH_BINARY); // threshold the picture src and call it dst
namedWindow("thresholdedPicture", WINDOW_AUTOSIZE); // Create a window
imshow("thresholdedPicture", dst); // display thresholded picture in the window
}
SimpleBlobDetector::Params params; // Set parameters for the object detection
params.minDistBetweenBlobs = 10; //Minimum distance between blobs
params.filterByColor = true;
params.blobColor = 255;
params.filterByArea = true; // filter by area of the blob
params.minArea = 1 ;// Minimum area of the blob
params.maxArea = 100000; // Maximum area of the blob
vector<KeyPoint> keypoints;
cv::SimpleBlobDetector detector(params); // Set up the blob detector with the parameters (params)
detector.detect(dst, keypoints); // Input thresholded picture for detection of the blobs
Mat dst_blob_dect; // New array to store the picture with the blobs detected
drawKeypoints( dst, keypoints, dst_blob_dect, Scalar(0,0,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS ); //Drawing a red line around the detected objects
namedWindow("keypoints", WINDOW_AUTOSIZE); // Create a window
imshow("keypoints", dst_blob_dect); // Show the picture with the blobs detected in the window "keypoints"
waitKey(0); // Press any key and the main function returns 0
return 0;}
Try this and use different values for params.minDistBetweenBlobs.
#include "stdafx.h"
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <opencv2/opencv.hpp>
#include <stdio.h>
using namespace std;
using namespace cv;
int main(){
Mat src;
Mat dst;
src = imread("C:\\Users\\sanche8x\\Pictures\\gather.png", CV_LOAD_IMAGE_GRAYSCALE); //Load an image from directory path
if (! src.data){
cout << "Could not open or find the image" << endl ; // Look for invalid input
return -1;
}
else{
double thresh = 130; // Threshold
double maxValue = 255; // Value assigned to the pixel if it is over 'thresh'
threshold(src, dst, thresh, maxValue, THRESH_BINARY); // threshold the picture src and call it dst
namedWindow("thresholdedPicture", WINDOW_AUTOSIZE); // Create a window
imshow("thresholdedPicture", dst); // display thresholded picture in the window
}
SimpleBlobDetector::Params params; // Set parameters for the object detection
params.minDistBetweenBlobs = 10; //Minimum distance between blobs
params.filterByColor = true;
params.blobColor = 255;
params.filterByCircularity = false;
params.filterByConvexity = false;
params.filterByInertia = false;
params.filterByArea = true; // filter by area of the blob
params.minArea = 1 ;// Minimum area of the blob
params.maxArea = 100000; // Maximum area of the blob
vector<KeyPoint> keypoints;
cv::SimpleBlobDetector detector(params); // Set up the blob detector with the parameters (params)
detector.detect(dst, keypoints); // Input thresholded picture for detection of the blobs
Mat dst_blob_dect; // New array to store the picture with the blobs detected
drawKeypoints( dst, keypoints, dst_blob_dect, Scalar(0,0,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS ); //Drawing a red line around the detected objects
namedWindow("keypoints", WINDOW_AUTOSIZE); // Create a window
imshow("keypoints", dst_blob_dect); // Show the picture with the blobs detected in the window "keypoints"
waitKey(0); // Press any key and the main function returns 0
return 0;
}

opencv HoughCircle and trackbar

I am looking into the Hough Circle function. There are basically 4 parameters that i can play with to get the correct circle I wish.
So it come to my mind that I want to create a trackbar to monitor the status of the image being processed.
So I altered my code like this
#include <sstream>
#include <string>
#include <iostream>
#include <vector>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv\cv.h>
#include <opencv\highgui.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
using namespace cv;
int main(int argc, char** argv) {
//Create a window for trackbars
namedWindow("Trackbar Window", CV_WINDOW_AUTOSIZE);
//Create trackbar to change brightness
int iSliderValue1 = 50;
createTrackbar("Brightness", "Trackbar Window", &iSliderValue1, 100);
//Create trackbar to change contrast
int iSliderValue2 = 50;
createTrackbar("Contrast", "Trackbar Window", &iSliderValue2, 100);
int param1 = 10;
createTrackbar("param1", "Trackbar Window", &param1, 300);
int param2 = 10;
createTrackbar("param2", "Trackbar Window", &param2, 300);
Mat src;
VideoCapture capture;
capture.open("movingBall.wmv");
capture.read(src);
capture.set(CV_CAP_PROP_FRAME_HEIGHT, 480);
capture.set(CV_CAP_PROP_FRAME_WIDTH, 640);
if (!src.data) {
std::cout << "ERROR:\topening image" << std::endl;
return -1;
}
cv::namedWindow("image1", CV_WINDOW_AUTOSIZE);
cv::namedWindow("image2", CV_WINDOW_AUTOSIZE);
while (true){
capture.read(src);
Mat dst;
int iBrightness = iSliderValue1 - 50;
double dContrast = iSliderValue2 / 50.0;
src.convertTo(src, -1, dContrast, iBrightness);
cv::imshow("image1", src);
Mat src_gray2;
cvtColor(src, src_gray2, CV_BGR2GRAY);
GaussianBlur(src_gray2, src_gray2, cv::Size(9, 9), 2, 2);
vector<Vec3f> circles;
HoughCircles(src_gray2, circles, CV_HOUGH_GRADIENT,
2, // accumulator resolution (size of the image / 2)
5, // minimum distance between two circles
param1, // Canny high threshold
param2, // minimum number of votes
0, 0); // min and max radius
std::cout << circles.size() << std::endl;
std::cout << "end of test" << std::endl;
for (size_t i = 0; i < circles.size(); i++)
{
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
circle(src, center, 3, Scalar(0, 255, 0), -1, 8, 0);
// circle outline
circle(src, center, radius, Scalar(0, 0, 255), 3, 8, 0);
}
/*std::vector<cv::Vec3f>::
const_iterator itc = circles.begin();
while (itc != circles.end()) {
cv::circle(src_gray2,
cv::Point((*itc)[0], (*itc)[1]), // circle centre
(*itc)[2], // circle radius
cv::Scalar(0,0,0), // color
2); // thickness
++itc;
}*/
cv::imshow("image2", src_gray2);
cvWaitKey(33);
}
return 0;
}
As seen at the Hough Circle function there, i used int param1; as the value i wish to change. However, the code has no syntax errors but it is unable to be compiled.
I wish to know if is there something wrong with my trackbar setup..
Thank you
Here i have tried it using Python you can try to port from it...
import cv2
import numpy as np
img = cv2.imread('C:/Python34/images/2.jpg',0)
cv2.namedWindow('image')
def nothing(x):
pass
cv2.createTrackbar('Param 1','image',0,100,nothing)
cv2.createTrackbar('Param 2','image',0,100,nothing)
switch = '0 : OFF \n1 : ON'
cv2.createTrackbar(switch, 'image',0,1,nothing)
while(1):
cv2.imshow('image',img)
k = cv2.waitKey(1) & 0xFF
if k == 27:
break
#To Get Parameter values from Trackbar Values
para1 = cv2.getTrackbarPos('Param 1','image')
para2 = cv2.getTrackbarPos('Param 2','image')
s = cv2.getTrackbarPos(switch,'image')
if s == 0:
cv2.imshow('image', img)
else:
#For finding Hough Circles according to trackbar parameters
circles = cv2.HoughCircles(img,cv2.HOUGH_GRADIENT,1,20,para1,para2,minRadius=0,maxRadius=0)
circles = np.uint16(np.around(circles))
#For drawing Hough Circles
for i in circles[0,:]:
cv2.circle(img,(i[0],i[1]),i[2],(0,255,0),2)
cv2.circle(img,(i[0],i[1]),2,(0,0,255),3)
cv2.imshow('image', img)
cv2.waitKey(0)
img = cv2.imread('C:/Python34/images/2.jpg',0)
cv2.destroyAllWindows()
You can use the above code as your refrence, firstly it creates a window and trackbars for switch and two parameter for hough circle.
then in the while loop para1 and para2 will store position of trackbars as value of canny parameter.
this is then used in cv2.HoughCircles function and the circles are drawn.
the image is again loaded so that every time you change parameter the output is given on fresh image to avoid confusing.
hope this might be useful.

OpenCV: record footage in one window and Display the same video in 2nd window but with contours only

I want to capture a video and display it on one window and have second window in which contours are displayed simultaneous. I am struggling with how to have the processed video displayed in the second window. Please analyze my code and suggest a solution or indicate where am going wrong maybe give me some directions to an online tutorial or sources. Thanks.
#include "iostream"
#include<opencv\cv.h>
#include<opencv\highgui.h>
#include<opencv\ml.h>
#include<opencv\cxcore.h>
#include <iostream>
#include <vector>
#include <string>
#include <opencv2/core/core.hpp> // Basic OpenCV structures (cv::Mat)
#include <opencv2/highgui/highgui.hpp> // Video write
using namespace cv;
using namespace std;
Mat image; Mat image_gray; Mat image_gray2; Mat threshold_output;
Mat frame;
int thresh=100, max_thresh=255;
int main(int argc, char** argv) {
//Capture Video
VideoCapture capCam(1);
if (!capCam.isOpened()){
cout<<"ERROR: Failed to Initialize Camera"<<endl;
return 1;
}
else{
cout<<"Camera Initialized"<<endl;
}
//Create Window
char* ImputFootage = "Source";
namedWindow(ImputFootage, CV_WINDOW_AUTOSIZE);
imshow(ImputFootage, frame);
char* OutputFootage = "Processed";
namedWindow(OutputFootage, CV_WINDOW_AUTOSIZE);
imshow(OutputFootage, frame);
while(1){
capCam>> frame;
imshow("Source", frame);
return(1);
if(capCam.read(ImputFootage)){
//Convert Image to gray & blur it
cvtColor( image,
image_gray,
CV_BGR2GRAY );
blur( image_gray,
image_gray2,
Size(3,3) );
//Threshold Gray&Blur Image
threshold(image_gray2,
threshold_output,
thresh,
max_thresh,
THRESH_BINARY);
//2D Container
vector<vector<Point>> contours;
//Fnd Countours Points, (Imput Image, Storage, Mode1, Mode2, Offset??)
findContours(threshold_output,
contours, // a vector of contours
CV_RETR_EXTERNAL,// retrieve the external contours
CV_CHAIN_APPROX_NONE,
Point(0, 0)); // all pixels of each contours
// Draw black contours on a white image
Mat result(threshold_output.size(),CV_8U,Scalar(255));
drawContours(result,contours,
-1, // draw all contours
Scalar(0), // in black
2); // with a thickness of 2
}
}
char CheckForEscKey = waitKey(10);
return 1;
}
You should call imshow("Processed", result); after calling drawContours
You were trying to show frames even before they were captured with camera. Compiler was not giving you error because Mat were declared ,but they were without value (null), Moreover you were trying to display Mat image, but what you capture from camera is Mat frame. Also, you lack exit (esc sequence, and your wait key was OUT of camera loop.
Anyway, here is your code (rewritten), I hope this is what you wanted.
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <cstdio>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
using namespace cv;
Mat image;
Mat image_gray;
Mat image_gray2;
Mat threshold_output;
Mat frame;
int thresh = 100, max_thresh = 255;
int main(int argc, char** argv)
{
//Capture Video
VideoCapture capCam(0);
if (!capCam.isOpened())
{
cout << "ERROR: Failed to Initialize Camera" << endl;
return 1;
}
else
{
cout << "Camera Initialized" << endl;
}
//Create Window
char* ImputFootage = "Source";
namedWindow(ImputFootage, CV_WINDOW_AUTOSIZE);
char* OutputFootage = "Processed";
namedWindow(OutputFootage, CV_WINDOW_AUTOSIZE);
while (1)
{
capCam >> frame;
imshow(ImputFootage, frame);
if (capCam.read(frame))
{
//Convert Image to gray & blur it
cvtColor(frame, image_gray, CV_BGR2GRAY);
blur(image_gray, image_gray2, Size(3, 3));
//Threshold Gray&Blur Image
threshold(image_gray2, threshold_output, thresh, max_thresh, THRESH_BINARY);
//2D Container
vector<vector<Point> > contours;
//Fnd Countours Points, (Imput Image, Storage, Mode1, Mode2, Offset??)
findContours(threshold_output, contours, // a vector of contours
CV_RETR_EXTERNAL, // retrieve the external contours
CV_CHAIN_APPROX_NONE, Point(0, 0)); // all pixels of each contours
// Draw black contours on a white image
Mat result(threshold_output.size(), CV_8U, Scalar(255));
drawContours(result, contours, -1, // draw all contours
Scalar(0), // in black
2); // with a thickness of 2
imshow(OutputFootage, result);
char CheckForEscKey = waitKey(10);
//If the key pressed by user is Esc(ASCII is 27) then break out of the loop
if (CheckForEscKey == 27)
{
break;
}
}
}
return 0;
}