I want to write a program which can correct an answer sheet by opencv in C++.
But as I use cvFindContours()
the contours' border-points hasn't been completely found.
I mean, I don't have closed-objects. (I use cvDilate
and cvErode
, without know their real functionality, but dilate omit some contours and erode add some extra, unwanted contours)
And the bigger problem is that I want to find a center-dot in each contour (to compare the location of answers with predefined left & down sidebars), but some contours are not symmetric so the center-dot's location is not exactly in the middle.
Look at the black picture, on the left, in the second contour, some of the bottom points are detected but the top ones are not detected.
cvCvtColor(pic, blackpic, CV_BGR2GRAY);
cvResize(blackpic, src0);
cvSmooth(src0, src0, CV_GAUSSIAN, 3, 3);
cvThreshold(src0, src, 140, 255, CV_THRESH_BINARY);
//Find Contour
CvMemStorage* st = cvCreateMemStorage();
CvSeq* first_contour = NULL;
cvFindContours(src, st, &first_contour, sizeof(CvContour), CV_RETR_LIST);
vector <vector <CvPoint> > cont;
vector <CvPoint> dot;
for (CvSeq* s = first_contour; s != NULL; s = s->h_next)
if (s -> total > C_MIN_SIZE && cvContourArea(s) > C_MIN_AREA)
{
cont.push_back(vector <CvPoint>()); //convert seq to vector
CvPoint c = cvPoint(0,0);
for (int i = 0; i < s -> total; i++)
{
CvPoint* p = CV_GET_SEQ_ELEM(CvPoint, s, i);
cont.back().push_back(*p);
CV_IMAGE_ELEM(test, uchar, p -> y, p -> x) = 255; //drawing each contour's point
c.x += p -> x; //find the center point by average
c.y += p -> y;
}
c.x = floor(c.x / s -> total);
c.y = floor(c.y / s -> total);
dot.push_back(c);
}
Although I am using C++, but I use IplImage* and CvPoint (c structres for opencv) insted of cv::Mat and cv::Point (C++ stractures), if it is possible, please don't use Mat and C++ mode.
I don't understand that when I draw contours by
cvDrawContours()
the contours are completely drawn, but when I personally iterate over the contours' points and draw them point by point, it seems that most of them are not detected!
findContours
has different ways to represent the contour. One way (default) is to only save "some" of the points and interpolate between them by assuming straight lines. Most probably, drawContours will fill those lines but you don't. In c++ to save ALL points, use methodCV_CHAIN_APPROX_NONE
. According to docs.opencv.org/modules/imgproc/doc/… C syntax uses exatcly the same parameter. – Micka