Here is an example to find largest contour from the input image. A contour can be considered as a sequence of points that define a specific object in an image. Here I took contours as the brightest object in the image. Contours can be easily extracted by thresholding the gray scale image.
After creating the contour images the function to find biggest contour is called where contour scanner used to scan through each contour and find biggest contour.
If you want C++ code, see my new post , OpenCV Find Biggest Contour Using C++
Here is the C code
Result:
Hope these help.
After creating the contour images the function to find biggest contour is called where contour scanner used to scan through each contour and find biggest contour.
If you want C++ code, see my new post , OpenCV Find Biggest Contour Using C++
Here is the C code
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv/cv.h"
using namespace cv;
using namespace std;
cv::Mat FC_FindBiggestContours(cv::Mat src);
CvRect R;
int main()
{
cv::Mat src;
cv::Mat src_binary;
src=cv::imread("src.jpeg");
if(src.empty()){
cout<<"Cannot load the image !"<<endl;
return 0;
}
cvtColor(src, src_binary, CV_BGR2GRAY); // Convert BGR to gray
cv::threshold(src_binary, src_binary, 200, 255, 0); // Threshold the image to convert binary image
imshow("src_binary",src_binary);
src_binary=FC_FindBiggestContours(src_binary);
rectangle(src, Point(R.x,R.y), Point(R.x+R.width,R.y+R.height), Scalar(0,255,0),2,8, 0);
imshow("Largest Contour", src_binary);
imshow("Source",src);
cvWaitKey(0); // Wait for key press
return 0;
}
cv::Mat FC_FindBiggestContours(cv::Mat mat_src)
{
IplImage temp=mat_src;
IplImage *src_img=cvCreateImage(cvSize(temp.width,temp.height),IPL_DEPTH_32S,1);
IplImage *dest=cvCreateImage(cvSize(temp.width,temp.height),IPL_DEPTH_8U,1);
CvArr* _mask=&temp;
int poly1Hull0=1;
CvPoint offset;
offset.x=0;
offset.y=0;
CvMat mstub, *mask = cvGetMat( _mask, &mstub );
CvMemStorage* tempStorage = cvCreateMemStorage();
CvSeq *contours, *c;
int nContours = 0;
double largest_length = 0,len = 0;
CvContourScanner scanner;
// clean up raw mask
cvMorphologyEx( mask, mask, 0, 0, CV_MOP_OPEN, 1 );
cvMorphologyEx( mask, mask, 0, 0, CV_MOP_CLOSE, 1 );
// find contours around only bigger regions
scanner = cvStartFindContours( mask, tempStorage,
sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, offset );
while( (c = cvFindNextContour( scanner )) != 0 )
{
len = cvContourPerimeter( c );
if(len > largest_length)
{
largest_length = len;
}
}
contours=cvEndFindContours( &scanner );
scanner = cvStartFindContours( mask, tempStorage,
sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, offset );
while( (c = cvFindNextContour( scanner )) != 0 )
{
len = cvContourPerimeter( c );
double q = largest_length ;
if( len < q ) //Get rid of blob if it's perimeter is too small
cvSubstituteContour( scanner, 0 );
else //Smooth it's edges if it's large enough
{
CvSeq* newC;
if( poly1Hull0 ) //Polygonal approximation of the segmentation
newC = cvApproxPoly( c, sizeof(CvContour), tempStorage, CV_POLY_APPROX_DP, 2, 0 );
else //Convex Hull of the segmentation
newC = cvConvexHull2( c, tempStorage, CV_CLOCKWISE, 1 );
cvSubstituteContour( scanner, newC );
nContours++;
R=cvBoundingRect(c,0);
}
}
contours = cvEndFindContours( &scanner );
// paint the found regions back into the image
cvZero( src_img );
cvZero( _mask );
for( c=contours; c != 0; c = c->h_next )
{
cvDrawContours( src_img, c, cvScalarAll(1), cvScalarAll(1), -1, -1, 8,
cvPoint(-offset.x,-offset.y));
}
cvReleaseMemStorage( &tempStorage );
// convert to 8 bit IplImage
for( int i = 0; i < src_img->height; i++ )
for( int j = 0; j < src_img->width; j++ )
{
int idx = CV_IMAGE_ELEM( src_img, int, i, j ); //get reference to pixel at (col,row),
uchar* dst = &CV_IMAGE_ELEM( dest, uchar, i, j ); //for multi-channel images (col) should be multiplied by number of channels */
if( idx == -1 || idx == 1 )
*dst = (uchar)255;
else if( idx <= 0 || idx > 1 )
*dst = (uchar)0; // should not get here
else {
*dst = (uchar)0;
}
}
cvReleaseImage(&src_img);
Mat ret=cvarrToMat(dest);
return ret;
}
The source image:src.jpeg |
Result:
Hi, thanks for the post...
ReplyDeleteI want to ask, what about moving object, how to find the biggest contour?
Regards & Thanks
This is working well.
ReplyDeletewhat about python
ReplyDeletei want know
Delete