Reputation: 405
So here is the code that i used to detect the contours:
IplImage* DetectAndDrawQuads(IplImage* img)
{
CvSeq* contours;
CvSeq* result;
CvMemStorage *storage = cvCreateMemStorage(0);
IplImage* ret = cvCreateImage(cvGetSize(img), 8, 3);
IplImage* temp = cvCreateImage(cvGetSize(img), 8, 1);
cvCvtColor(img, temp, CV_BGR2GRAY);
cvFindContours(temp, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
while(contours)
{
result = cvApproxPoly(contours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.10, 0); //*0.2
if((result->total) == 4)
{
CvPoint *pt[4];
for(int i=0;i<4;i++)
pt[i] = (CvPoint*)cvGetSeqElem(result, i);
cvLine(ret, *pt[0], *pt[1], cvScalar(255));
cvLine(ret, *pt[1], *pt[2], cvScalar(255));
cvLine(ret, *pt[2], *pt[3], cvScalar(255));
cvLine(ret, *pt[3], *pt[0], cvScalar(255));
}
contours = contours->h_next;
}
cvReleaseImage(&temp);
cvReleaseMemStorage(&storage);
return ret;
}
int main()
{
IplImage* img = cvLoadImage("D:\\Database\\eye2.jpg");
IplImage* contourDrawn = 0;
cvNamedWindow("original");
cvShowImage("original", img);
contourDrawn = DetectAndDrawQuads(img);
cvNamedWindow("contours");
cvShowImage("contours", contourDrawn);
cvWaitKey(0);
return 0;
}
And this is the Pic that I used to test the program: Input
I am trying to get the contours as a preliminary step in finding the facial expression of an inputted face. And this is the Result when i tried to run the program (Original [left] and Output [right]): Result
As you can see there seems to be some noise left in the binary image (Which I actually preprocessed before it is being inputted in my find contours program (the codes above)).
Thank you very much if you will help me. So far, this is the best output i could generate regarding finding contours. Also if you can help me extract the contours more accurately then that will be very much appreciated. Thank you. :)
Upvotes: 2
Views: 2486
Reputation: 1348
cvPoint rightMost = (0, 0);
cvPoint leftMost = (gray->width, 0);
cvPoint bottom = (0, gray->height);
cvPoint top = (0, 0);;
for( CvSeq* current = contours; current != NULL; current = current->h_next )
{
for( int i = 0; i < current->total; i++ )
{
CvPoint* pt = (CvPoint*)cvGetSeqElem( current, i );
int pixVal = (int)(gray->imageData + pt->x * gray->widthStep)[pt->y];
//find the point, which coordinate X is the biggest
if( pt->x > rightMost )
{
rightMost->x = pt->x;
rightMost->y = pt->y;
}
//find the point, which coordinate X is the smallest
if( pt->x < leftMost )
{
leftMost->x = pt->x;
leftMost->y = pt->y;
}
//find the point, which coordinate Y is the biggest
if( pt->y > top )
{
top->x = pt->x;
top->y = pt->y;
}
//find the point, which coordinate Y is the smallest
if( pt->x < bottom )
{
bottom->x = pt->x;
bottom->y = pt->y;
}
}
}
cvPoint ptCenter(cvRound(( rightMost + leftMost ) / 2), ( top + bottom ) / 2 );
I haven't tried this code, but I think it will be helpfull!
Upvotes: 2