Find point of convexity defects in opencv c++ function - c++

I am trying to recover the point of convexity defect, but the function only returns me integer, can you give me a hint on how to find these points?
vector<vector<Point> >hull2( contours.size() );
vector<vector<int>> hull(contours.size());
std::vector<cv::Vec4i> convexityDefectsSet;
for( int i = 0; i < contours.size(); i++ ) {
convexHull( Mat(contours[i]), hull[i], false );
convexHull(Mat(contours[i]), hull2[i], false);
if (contours[i].size() > 3) {
cv::convexityDefects(Mat(contours[i]), hull[i], convexityDefectsSet);
for (int cDefIt = 0; cDefIt < convexityDefectsSet.size(); cDefIt++) {
int startIdx = convexityDefectsSet[cDefIt].val[0];
int endIdx = convexityDefectsSet[cDefIt].val[1];
int defectPtIdx = convexityDefectsSet[cDefIt].val[2];
double depth = static_cast<double>(convexityDefectsSet[cDefIt].val[3]) / 256.0;
std::cout << startIdx << ' ' << endIdx << ' ' << defectPtIdx << ' ' << depth << '\n' << '\n' << std::endl;
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
Point2f p(defectPtIdx, defectPtIdx);
circle(frame, p , 10, color, 2, 8, 0 );
}
}}

I think this my piece of code (should detect hand (color detector need to be tuned) and search conv. defects). But you can use it as base for your code:
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <ctype.h>
#include <time.h>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\video\tracking.hpp>
#include <opencv2\highgui\highgui.hpp>
using namespace cv;
using namespace std;
// Detect Skin from YCrCb
Mat DetectYCrCb(Mat img, Scalar min, Scalar max) {
Mat skin;
cvtColor(img, skin, cv::COLOR_BGR2YCrCb);
inRange(skin, min, max, skin);
Mat rect_12 = getStructuringElement(cv::MORPH_RECT, Size(12,12) , Point(6,6));
erode(skin, skin, rect_12,Point(),1);
Mat rect_6 = getStructuringElement(cv::MORPH_RECT, Size(6,6) , Point(3,3));
dilate(skin,skin,rect_6,Point(),2);
return skin;
}
void DetectContour(Mat img){
Mat drawing = Mat::zeros( img.size(), CV_8UC3 );
vector<vector<Point> > contours;
vector<vector<Point> > bigContours;
vector<Vec4i> hierarchy;
findContours(img,contours, hierarchy, cv::RETR_LIST, cv::CHAIN_APPROX_SIMPLE, Point());
if(contours.size()>0)
{
vector<std::vector<int> >hull( contours.size() );
vector<vector<Vec4i>> convDef(contours.size() );
vector<vector<Point>> hull_points(contours.size());
vector<vector<Point>> defect_points(contours.size());
for( int i = 0; i < contours.size(); i++ )
{
if(contourArea(contours[i])>5000)
{
convexHull( contours[i], hull[i], false );
convexityDefects( contours[i],hull[i], convDef[i]);
for(int k=0;k<hull[i].size();k++)
{
int ind=hull[i][k];
hull_points[i].push_back(contours[i][ind]);
}
for(int k=0;k<convDef[i].size();k++)
{
if(convDef[i][k][3]>20*256) // filter defects by depth
{
int ind_0=convDef[i][k][0];
int ind_1=convDef[i][k][1];
int ind_2=convDef[i][k][2];
defect_points[i].push_back(contours[i][ind_2]);
cv::circle(drawing,contours[i][ind_0],5,Scalar(0,255,0),-1);
cv::circle(drawing,contours[i][ind_1],5,Scalar(0,255,0),-1);
cv::circle(drawing,contours[i][ind_2],5,Scalar(0,0,255),-1);
cv::line(drawing,contours[i][ind_2],contours[i][ind_0],Scalar(0,0,255),1);
cv::line(drawing,contours[i][ind_2],contours[i][ind_1],Scalar(0,0,255),1);
}
}
drawContours( drawing, contours, i, Scalar(0,255,0), 1, 8, vector<Vec4i>(), 0, Point() );
drawContours( drawing, hull_points, i, Scalar(255,0,0), 1, 8, vector<Vec4i>(), 0, Point() );
}
}
}
imshow( "Hull demo", drawing );
}
int main( int argc, char** argv )
{
Mat frame,copyFrame;
VideoCapture capture(0);
namedWindow( "Hull demo", cv::WINDOW_AUTOSIZE );
namedWindow( "Video", cv::WINDOW_AUTOSIZE );
if (capture.isOpened()){
while(true)
{
capture >> frame;
imshow( "Video", frame);
Mat skinYCrCb = DetectYCrCb(frame,Scalar(0, 100, 80), Scalar(255, 185, 135));
DetectContour(skinYCrCb);
int c = waitKey(10);
if( (char)c == 27 )
{
break;
}
}
}
cv::destroyAllWindows();
return 0;
}

According to the documentation:
In C++ and the new Python/Java interface each convexity defect is represented
as 4-element integer vector [...]: (start_index, end_index, farthest_pt_index,
fixpt_depth), where indices are 0-based indices in the original contour of
the convexity defect...
They correspond to indices in the original contour that was used to generate the convex hull, i.e., your contours[i] variable.
For example, the coordinates of the first point are obtained with:
cv::Point start = contours.at(startIdx);

Related

how to remove small contour from the frame?

I have written the program to detect the object in the water(swimming pool). But I am getting lot of other contours like as shown in this screenshot. But this is the actual image. Please help me to get rid of other unwanted contours detected in the video. Below is the code that I have written.
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
string window_name = "Captured rectangle block";
RNG rng(12345);
double fps;
int thresh = 100;
int main( int argc, const char** argv )
{
VideoCapture cap("IMGP2850.MOV"); // open the video file for reading
if ( !cap.isOpened() ) // if not success, exit program
{
cout << "Cannot open the video file" << endl;
return -1;
}
fps = cap.get(CV_CAP_PROP_FPS); //get the frames per seconds of the video
cout << "Frame per seconds : " << fps << endl;
double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH);
double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
Size S(dWidth,dHeight);
while(1)
{
Mat frame;
Mat threshold_output;
int skip_frame = 4;
while(skip_frame)
{
printf("inside while loop\n");
bool bSuccess = cap.read(frame); // read a new frame from video
skip_frame--;
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read the frame from video file" << endl;
break;
}
}
//-- 3. Apply the classifier to the frame
if( frame.empty() )
{ printf(" --(!) No captured frame -- Break!"); break; }
std::vector<Rect> faces;
Mat frame_gray;
cvtColor( frame, frame_gray, CV_BGR2GRAY );
equalizeHist( frame_gray, frame_gray);
blur( frame_gray, frame_gray, Size(3,3) );
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
printf("before finding countrs\n");
threshold( frame_gray, threshold_output, thresh, 255, THRESH_BINARY );
findContours( threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
vector<vector<Point> > contours_poly( contours.size() );
vector<Rect> boundRect( contours.size() );
vector<Point2f>center( contours.size() );
vector<float>radius( contours.size() );
// contours.resize(contours.size());
printf("after finding countrs\n");
for( unsigned int i = 0; i < contours.size(); i++ )
{
printf("inside for loop\n");
approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
printf("after poly\n");
boundRect[i] = boundingRect( Mat(contours_poly[i]) );
printf("after bondrec\n");
minEnclosingCircle( (Mat)contours_poly[i], center[i], radius[i] );
}
Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
for( unsigned int i = 0; i< contours.size(); i++ )
{
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
drawContours( drawing, contours_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 );
circle( drawing, center[i], (int)radius[i], color, 2, 8, 0 );
}
/// Show in a window
namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
imshow( "Contours", drawing );
int c = waitKey(10);
if( (char)c == 'c' ) { break; }
}
return 0;
}

Crop Triangle with opencv c++

User,
I want to crop that Triangle on the image and show it in another window with opencv c++. I know all three Coordinates.
Can anyone help me? I did not find any answer on the Internet about "triangle cropping". Thanks!
EDIT: The Problem here is that i cannot use ROI for cropping the Triangle. I have to copy just the triangle without any background or something around. Is it possible to create my own ROI by knowing the Coordinates of the triangle [p1(302,179), p2(329,178), p3(315,205)]?
cv::Mat inputImage = cv::imread("input.png");
if (inputImage.channels() > 1)
{
cv::cvtColor(inputImage, inputImage, CV_RGB2GRAY);
}
// replace these values with your actual coordinates
// I found these by first saving your provided image, then
// using Microsoft Paint
int x0 = 242;
int y0 = 164;
int x1 = 314;
int y1 = 38;
int x2 = 387;
int y2 = 164;
// then create a line masking using these three points
cv::Mat lineMask = cv::Mat::zeros(inputImage.size(), inputImage.type());
cv::line(lineMask, cv::Point(x0, y0), cv::Point(x1, y1), cv::Scalar(255, 255, 0), 1, 8, 0);
cv::line(lineMask, cv::Point(x0, y0), cv::Point(x2, y2), cv::Scalar(255, 255, 0), 1, 8, 0);
cv::line(lineMask, cv::Point(x1, y1), cv::Point(x2, y2), cv::Scalar(255, 255, 0), 1, 8, 0);
// perform contour detection on your line mask
cv::vector<cv::vector<cv::Point>> contours;
cv::vector<cv::Vec4i> hierarchy;
cv::findContours(lineMask, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0));
// calculate the distance to the contour
cv::Mat raw_dist(lineMask.size(), CV_32FC1);
for (int i = 0; i < lineMask.rows; i++)
{
for (int j = 0; j < lineMask.cols; j++)
{
raw_dist.at<float>(i, j) = cv::pointPolygonTest(contours[0], cv::Point2f(j, i), true);
}
}
double minVal; double maxVal;
cv::minMaxLoc(raw_dist, &minVal, &maxVal, 0, 0, cv::Mat());
minVal = std::abs(minVal);
maxVal = std::abs(maxVal);
// depicting the distances graphically
cv::Mat mask = cv::Mat::zeros(inputImage.size(), CV_8UC1);
for (int i = 0; i < mask.rows; i++)
{
for (int j = 0; j < mask.cols; j++)
{
if (raw_dist.at<float>(i, j) < 0)
{
mask.at<uchar>(i, j) = static_cast<uchar>(0);
continue;
}
mask.at<uchar>(i, j) = static_cast<uchar>(255);
}
}
// inverse the input image
cv::Mat invInput;
cv::bitwise_not(inputImage, invInput);
// then get only the region of your triangle
cv::Mat outputImage;
invInput.copyTo(outputImage, mask);
cv::bitwise_not(outputImage, outputImage);
// display for debugging purpose
cv::imshow("inputImage", inputImage);
cv::imshow("lineMask", lineMask);
cv::imshow("mask", mask);
cv::imshow("outputImage", outputImage);
cv::waitKey();
This is your inputImage:
This is your lineMask:
This is your created binary mask:
And this is your final outputImage:
References:
OpenCV draw line
OpenCV findContours
Point Polygon Test
you can do it by using mask as shown with the code below
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main( int, char** argv )
{
Mat src = imread( argv[1] );
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY );
gray = gray < 127;
vector<vector<Point> > contours;
findContours(gray, contours,
RETR_EXTERNAL,
CHAIN_APPROX_SIMPLE);
for( size_t i = 0; i< contours.size(); i++ )
{
Rect rect = boundingRect(contours[i]);
Mat mask = gray(rect);
Mat srcROI = src(rect);
srcROI.setTo(Scalar(0,0,255),mask);
imshow("srcROI",srcROI);
waitKey();
}
imshow( "result", src );
waitKey(0);
return(0);
}
EDIT: according the change on the question i suggest the test code below
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
int main( int, char** argv )
{
Mat src = imread("lena.jpg");
vector<Point> points;
points.push_back( Point(200,200));
points.push_back( Point(370,370));
points.push_back( Point(220,410));
Mat mask = Mat::zeros( src.size(), CV_8UC1 );
fillConvexPoly( mask, points, Scalar( 255 ));
Rect rect = boundingRect( points );
Mat roi = src( rect ).clone();
mask = mask( rect ).clone();
rect.x = rect.x - 180;
rect.y = rect.y - 180;
Mat srcROI = src( rect );
roi.copyTo( srcROI, mask );
imshow( "result", src );
waitKey(0);
return(0);
}
As you told that you know co-ordinates of the triangle, using below code you can find triangle.
Mat image = imread("imagePath");
bitwise_not(image, image);
Mat grayImage;
cv::cvtColor(image, grayImage, CV_RGB2GRAY);
cv::vector<cv::vector<cv::Point> > contours;
cv::vector<cv::Vec4i> hierarchy;
cv::findContours(grayImage, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cv::Point(0, 0));
Mat contourMat(grayImage.size(), grayImage.type(), Scalar(255));
for(int i = 0; i < contours.size(); i++)
{
if(contours[i].data()->x == 314 && contours[i].data()->y == 37)
drawContours(contourMat, contours, i, Scalar(0), CV_FILLED, 8, hierarchy);
}
imshow("WindowName", contourMat);
Hope this will help.

How to find coordinate points of images using findcontours methods in opencv

Here I did coding for finding the edge and their all coordinate points of the image but I need only two or three coordinate point of each quadrant in image.
using namespace cv;
using namespace std;
Mat src;
Mat src_gray;
int thresh = 172;
int max_thresh = 255;
RNG rng(12345);
void thresh_callback(int, void* );
int main( int argc, char** argv ){
src = imread("Led50.jpg",1);
cvtColor( src, src_gray, CV_BGR2GRAY );
blur( src_gray, src_gray, Size(3,3) );
char* source_window = "Source";
namedWindow( source_window, CV_WINDOW_AUTOSIZE );
imshow( source_window, src );
createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback );
thresh_callback( 0, 0 );
waitKey(0);
return(0);}
void thresh_callback(int, void* ){
Mat canny_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
Canny( src_gray, canny_output, thresh, thresh*2, 3 );
findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
for(unsigned int i=0;i<contours.size();i++){
for(unsigned int j=0;j<contours[i].size();j++)
{
cout << "Point(x,y)=" << contours[i][j].x << "," << contours[i][j].y << endl;
}}}
Source file:
Result and i get all the coordinate point:
And I need only marked coordinate point but not in exact position as well as each quadrant atleast have two points:
The above code is based on the canny and findcontours, I need few coordinates from images.
#include "highgui.hpp"
#include "imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv ){
Mat src_gray;
src_gray = imread("EXnc1.jpg",0);
blur( src_gray, src_gray, Size(3,3) );
Mat bwimg = src_gray > 127;
vector<vector<Point> > contours;
findContours( bwimg, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE );
for(unsigned int i=0;i<contours.size();i++){
approxPolyDP(Mat(contours[i]), contours[i], 10, true);
if(i > 0)
{
cout << "Outer contour points \n";
}
else cout << "Inner contour points \n";
for(unsigned int j=0;j<contours[i].size();j++)
{
cout << "Point(x,y)=" << contours[i][j].x << "," << contours[i][j].y << endl;
circle( src_gray, contours[i][j], 3, Scalar(0, 0, 255), FILLED, LINE_AA );
}
imshow( "Result", src_gray );
waitKey(0);
}
return(0);}
output :
Inner contour points
Point(x,y)=343,148
Point(x,y)=419,160
Point(x,y)=461,208
Point(x,y)=457,276
Point(x,y)=403,322
Point(x,y)=322,322
Point(x,y)=269,262
Point(x,y)=279,190
Outer contour points
Point(x,y)=371,133
Point(x,y)=289,159
Point(x,y)=251,224
Point(x,y)=271,298
Point(x,y)=351,341
Point(x,y)=436,320
Point(x,y)=481,247
Point(x,y)=456,172

OpenCV c++ assertion failed <i < 0> in cv::_InputArray::getMat

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/background_segm.hpp>
#include <iostream>
#include <windows.h>
using namespace cv;
using namespace std;
//initial min and max HSV filter values.
//these will be changed using trackbars
Mat src; Mat HSV; Mat roi; Mat range; Mat eroded; Mat gray;
int thresh = 100;
int max_thresh = 255;
/** #function main */
int main(int argc, char** argv)
{
createTrackbars();
VideoCapture cap(0); // open the default camera
if (!cap.isOpened()) // check if we succeeded
return -1;
namedWindow("background", 1);
int waitTime = 50;
int counter = 101;
int roiLeft = 20;
int roiTop = 50;
int roiRight = 200;
int roiBottom = 200;
Rect rRoi = Rect(roiLeft, roiTop, roiRight, roiBottom);
Mat background;
cap >> background;
background = background(rRoi);
//cvtColor(background, background, CV_BGR2HSV);
//imshow("background", background);
vector<vector<Point> > contours;
vector<vector < cv::Point >> hull(1);
vector<Vec4i> hierarchy;
vector<CvConvexityDefect> defects;
while (true)
{
cap >> src;
//Create the region of interest.
Mat iRoi = src.clone()(rRoi);
Mat iRoiSRC = src(rRoi);
//Draw a rectangle there.
rectangle(src, rRoi, Scalar(255, 128, 0), 1, 8, 0);
//imshow("roi", iRoi);
//Subtract the static background.
absdiff(iRoi, background, iRoi);
//imshow("diff", iRoi);
//Convert it to a GrayScale and threshold it.
cvtColor(iRoi, iRoi, CV_BGR2GRAY);
threshold(iRoi, gray, 15, 255, CV_THRESH_BINARY);
//Perform a closing.
Mat erodeElement = getStructuringElement(MORPH_ELLIPSE, Size(erodeSize, erodeSize));
Mat dilateElement = getStructuringElement(MORPH_ELLIPSE, Size(dilateSize, dilateSize));
for (int index = 0; index < loopAmount; index++)
{
erode(gray, gray, erodeElement);
dilate(gray, gray, dilateElement);
}
//imshow("range", gray);
//Find the contours.
findContours(gray, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
//Pick the biggest contour.
int biggestContourIndex = 0;
int largestArea = 0;
for (int i = 0; i < contours.size(); i++)
{
if (contours[i].size() > largestArea)
{
largestArea = contours[i].size();
biggestContourIndex = i;
}
}
vector<int> hullsI;
vector<Point> hullsP;
vector<Vec4i> defects;
//Find the convex hull.
if (contours.size() > 0)
{
convexHull(contours[biggestContourIndex], hullsI, true, true);
convexHull(contours[biggestContourIndex], hullsP, true, true);
}
//Find the convexity defects.
if (contours.size() > 0)
{
if (contours[biggestContourIndex].size() > 3)
{
convexityDefects(contours[biggestContourIndex], hullsI, defects);
}
}
//Draw the biggest contour and its convex hull.
Scalar colorOne = Scalar(255, 128, 0);
Scalar colorTwo = Scalar(0, 0, 255);
if (contours.size() > 0)
{
drawContours(iRoiSRC, contours, biggestContourIndex, colorOne, 2, 8, hierarchy, 0, Point());
drawContours(iRoiSRC, hullsP, 0, colorTwo, 1, 8, vector<Vec4i>(), 0, Point());
rectangle(iRoiSRC, boundingRect(contours[biggestContourIndex]), Scalar(0, 255, 0), 1, 8, 0);
}
imshow("src", src);
if (waitKey(waitTime) >= 0) break;
}
return(0);
}
There is a rectangle in the upper left of the screen, where my hand will be recognized once I hold it there.
The error that i get appears at the first drawContours. The full error which is given to me by the console is: OpenCV Error: Assertion failed <i <0> in cv::_InputArray::getMat, file C:\buildslave64\win64_amdoc1\2_4_PackSlave-win64-vc11-shared\opencv\modules\core\src\matrix.cpp, line 963
I've been extensively searching for a solution on multiple sites, including stackoverflow but none of the solution seem to be working.
Any help would be appreciated.
I use Visual studio 2013 with OpenCV-2.4.10
converting vector<CvConvexityDefect> defects; to a point seemed to do the trick

blob tracking with kalman filter in opencv

Well, I am trying to create a small example of blob tracking using the kalman filter. I am using openCV in order to accomplish this task, however it does not seem to work as it supposed to, since when I am hiding the object which tracking the output with, the kalman filter does not try to estimate where the object should be. I am attaching the code below, I hope that someone can give a hint on what I am doing wrong.
Thanks in advance.... :-)
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/video/tracking.hpp>
using namespace std;
using namespace cv;
#define drawCross( img, center, color, d )\
line(img, Point(center.x - d, center.y - d), Point(center.x + d, center.y + d), color, 2, CV_AA, 0);\
line(img, Point(center.x + d, center.y - d), Point(center.x - d, center.y + d), color, 2, CV_AA, 0 )\
int main()
{
Mat frame, thresh_frame;
vector<Mat> channels;
VideoCapture capture;
vector<Vec4i> hierarchy;
vector<vector<Point> > contours;
capture.open("capture.avi");
if(!capture.isOpened())
cerr << "Problem opening video source" << endl;
KalmanFilter KF(4, 2, 0);
Mat_<float> state(4, 1);
Mat_<float> processNoise(4, 1, CV_32F);
Mat_<float> measurement(2,1); measurement.setTo(Scalar(0));
KF.statePre.at<float>(0) = 0;
KF.statePre.at<float>(1) = 0;
KF.statePre.at<float>(2) = 0;
KF.statePre.at<float>(3) = 0;
KF.transitionMatrix = *(Mat_<float>(4, 4) << 1,0,1,0, 0,1,0,1, 0,0,1,0, 0,0,0,1); // Including velocity
KF.processNoiseCov = *(cv::Mat_<float>(4,4) << 0.2,0,0.2,0, 0,0.2,0,0.2, 0,0,0.3,0, 0,0,0,0.3);
setIdentity(KF.measurementMatrix);
setIdentity(KF.processNoiseCov, Scalar::all(1e-4));
setIdentity(KF.measurementNoiseCov, Scalar::all(1e-1));
setIdentity(KF.errorCovPost, Scalar::all(.1));
while((char)waitKey(1) != 'q' && capture.grab())
{
capture.retrieve(frame);
split(frame, channels);
add(channels[0], channels[1], channels[1]);
subtract(channels[2], channels[1], channels[2]);
threshold(channels[2], thresh_frame, 50, 255, CV_THRESH_BINARY);
medianBlur(thresh_frame, thresh_frame, 5);
findContours(thresh_frame, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
Mat drawing = Mat::zeros(thresh_frame.size(), CV_8UC1);
for(size_t i = 0; i < contours.size(); i++)
{
// cout << contourArea(contours[i]) << endl;
if(contourArea(contours[i]) > 500)
drawContours(drawing, contours, i, Scalar::all(255), CV_FILLED, 8, vector<Vec4i>(), 0, Point());
}
thresh_frame = drawing;
findContours(thresh_frame, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
drawing = Mat::zeros(thresh_frame.size(), CV_8UC1);
for(size_t i = 0; i < contours.size(); i++)
{
// cout << contourArea(contours[i]) << endl;
if(contourArea(contours[i]) > 500)
drawContours(drawing, contours, i, Scalar::all(255), CV_FILLED, 8, vector<Vec4i>(), 0, Point());
}
thresh_frame = drawing;
// Get the moments
vector<Moments> mu(contours.size() );
for( size_t i = 0; i < contours.size(); i++ )
{ mu[i] = moments( contours[i], false ); }
// Get the mass centers:
vector<Point2f> mc( contours.size() );
for( size_t i = 0; i < contours.size(); i++ )
{ mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); }
Mat prediction = KF.predict();
Point predictPt(prediction.at<float>(0),prediction.at<float>(1));
for(size_t i = 0; i < mc.size(); i++)
{
drawCross(frame, mc[i], Scalar(255, 0, 0), 5);
measurement(0) = mc[i].x;
measurement(1) = mc[i].y;
}
Point measPt(measurement(0),measurement(1));
Mat estimated = KF.correct(measurement);
Point statePt(estimated.at<float>(0),estimated.at<float>(1));
drawCross(frame, statePt, Scalar(255, 255, 255), 5);
vector<vector<Point> > contours_poly( contours.size() );
vector<Rect> boundRect( contours.size() );
for( size_t i = 0; i < contours.size(); i++ )
{ approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
boundRect[i] = boundingRect( Mat(contours_poly[i]) );
}
for( size_t i = 0; i < contours.size(); i++ )
{
rectangle( frame, boundRect[i].tl(), boundRect[i].br(), Scalar(0, 255, 0), 2, 8, 0 );
}
imshow("Video", frame);
imshow("Red", channels[2]);
imshow("Binary", thresh_frame);
}
return 0;
}