Я изучаю opencv, используя одноименную книгу. Я хотел бы рассчитать площадь контура, но он всегда возвращает 0. Контуры окрашены как замкнутые многоугольники, поэтому это кажется правильным.
Там есть несколько образцов, но они используют vector<vector<Point>> contours
. Мой код ниже основан на образце книги. Образное изображение, которое я использую, является полутоновой.
Поэтому мой вопрос: что мне не хватает, чтобы получить площадь! = 0?
#include <opencv\cv.h>
#include <opencv\highgui.h>
#define CVX_RED CV_RGB(0xff,0x00,0x00)
#define CVX_BLUE CV_RGB(0x00,0x00,0xff)
int main(int argc, char* argv[]) {
cvNamedWindow( argv[0], 1 );
IplImage* img_8uc1 = cvLoadImage( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
IplImage* img_edge = cvCreateImage( cvGetSize(img_8uc1), 8, 1 );
IplImage* img_8uc3 = cvCreateImage( cvGetSize(img_8uc1), 8, 3 );
cvThreshold( img_8uc1, img_edge, 128, 255, CV_THRESH_BINARY );
CvMemStorage* storage = cvCreateMemStorage();
CvSeq* contours = NULL;
int num_contours = cvFindContours(img_edge, storage, &contours, sizeof(CvContour),
CV_RETR_LIST, CV_CHAIN_APPROX_NONE, cvPoint(0, 0));
printf("Total Contours Detected: %d\n", num_contours );
int n=0;
for(CvSeq* current_contour = contours; current_contour != NULL; current_contour=current_contour->h_next ) {
printf("Contour #%d\n", n);
int point_cnt = current_contour->total;
printf(" %d elements\n", point_cnt );
if(point_cnt < 20){
continue;
}
double area = fabs(cvContourArea(current_contour, CV_WHOLE_SEQ, 0));
printf(" area: %d\n", area );
cvCvtColor(img_8uc1, img_8uc3, CV_GRAY2BGR);
cvDrawContours(img_8uc3, current_contour, CVX_RED, CVX_BLUE, 0, 2, 8);
cvShowImage(argv[0], img_8uc3);
cvWaitKey(0);
n++;
}
printf("Finished contours.\n");
cvCvtColor( img_8uc1, img_8uc3, CV_GRAY2BGR );
cvShowImage( argv[0], img_8uc3 );
cvWaitKey(0);
cvDestroyWindow( argv[0] );
cvReleaseImage( &img_8uc1 );
cvReleaseImage( &img_8uc3 );
cvReleaseImage( &img_edge );
return 0;
}
Это произошло не потому, что "область" равна 0, а потому, что вы использовали printf с флагом% d (целое число) вместо% f (double). Если вы используете соответствующий флаг, вы увидите реальную ценность "области". По этой причине я всегда использую cout вместо printf. Это экономит много проблем такого рода.
На боковой ноте. Вы изучаете здесь интерфейс C OpenCV. Я бы рекомендовал вам изучить его C++ интерфейс (он был добавлен в OpenCV с версии 2.0). Во-первых, интерфейс C устарел и, скорее всего, полностью удаляется из следующей версии OpenCV. Во-вторых, это сложнее, чем интерфейс C++. В случае cvFindContours это намного сложнее. Здесь вы можете найти необходимую документацию для всех интерфейсов.