I am working on circles/ellipse detection for a set of points and reconstruction of the detected points. I am struck at a specific image processing problem. The following is the sample image upon which the processing is to be performed,
Click here (The red points in the image are manually drawn to emphasize the 16x16 grid)
The task to be performed is to mask the image with black outside the 16x16 grid point rectangle. I have obtained the center points and radius of all the circles/Ellipses based on the Moments and Fit Ellipse methods. Now I need to detect the corners of the rectangle, and mask the image outside the rectangle to black.
My code till detecting the centers of the circles can be seen below,
int ImgProcessor::Do_BoundBoxes(Mat IpImg)
{
//Parameter Initialization________________________________________________________
double thresh=100, max_thresh = 255;
int ksize_w = 3 ;
int ksize_h = 3;
//Read the image as a matrix
Mat TempImg;
//resize(IpImg, IpImg ,Size(), 0.5,0.5, INTER_AREA);
//Preprocessing__________________________________________________________
GaussianBlur( IpImg, TempImg, Size(ksize_w, ksize_h),2,2);
threshold(TempImg,TempImg, thresh,max_thresh, 0);
GaussianBlur( TempImg, TempImg, Size(ksize_w, ksize_h),2,2);
vector<vector<Point> > contours;
vector<vector<Point> > updated_contours;
vector<Vec4i> hierarchy;
vector<int> contour_arealist;
double contour_area;
RNG rng(12345);
double threshold_area = 10;
findContours( TempImg, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );
//Update the contour vector elliminating those less than thresholds
for( int i = 0; i < contours.size(); i++ )
{
contour_area = contourArea(contours[i]);
if (contour_area >= threshold_area)
{
//contour_arealist.push_back(contour_area);
updated_contours.push_back(contours[i]);
}
else
{ continue ;
}
}
/// Approximate contours to polygons + get bounding rects and circles
vector<vector<Point> > contours_poly( updated_contours.size() );
vector<Rect> boundRect( updated_contours.size() );
vector<Point2f>center( updated_contours.size() );
vector<float>radius( updated_contours.size() );
//Get the bounding rectangles, minimum enclosing circles for the updated contours
for( int i = 0; i < updated_contours.size(); i++ )
{
approxPolyDP( Mat(updated_contours[i]), contours_poly[i], 3, true );
boundRect[i] = boundingRect( Mat(contours_poly[i]) );
minEnclosingCircle( (Mat)contours_poly[i], center[i], radius[i] );
}
/// Draw polygonal contour + bonding rects + circles
Mat drawing = Mat::zeros( TempImg.size(), CV_8UC3 );
for( int i = 0; i< updated_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 );
}
printf("\t Info: Area and Contour Length \n");
for( size_t i = 0; i< center.size(); i++ )
{
printf(" %.2f %.2f %.2f \n", center[i].x, center[i].y,radius[i]) ;
}
}
How this can be really approached ? I was thinking to draw rectangles by finding the diagonal points of the rectangle, but the entire set of grid points are not always present. I also tried implementing the Pick's theorem, but then I need to remove the points outside the grid. Can I use k-nearest neighbours approach.