void mvContours::get_hu_moments (CvSeq* contour1, HU_MOMENTS &hu_moments) { CvMoments moments; double hus[7]; cvContourMoments(contour1, &moments); cvGetHuMoments(&moments, (CvHuMoments*)hus); hu_moments = std::vector<double>(hus, hus+sizeof(hus)/sizeof(double)); }
bool ContoursProcessor::FindContours() { if (storage==NULL) { storage = cvCreateMemStorage(0); } else { cvClearMemStorage(storage); } cvFindContours( Tmp_img, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) ); if(ImageResult) cvClearSeq(ImageResult); if (contours) { if (ResultsStorage==NULL) { ResultsStorage = cvCreateMemStorage(0); } else { cvClearMemStorage(ResultsStorage); } ImageResult = cvCreateSeq(0,sizeof(CvSeq),sizeof(T_MEAS_RESULTS_REC),ResultsStorage); T_MEAS_RESULTS_REC ContourResult; int Idx=1; for( CvSeq* c=contours; c!=NULL; c=c->h_next ) { //for (i=0;i<contours->total;i++) //ImageResult if (ImageResult) { cvContourMoments(c,&Moments); if ((Moments.m00>3000.0)&&(Moments.m00<8000.0)) { memset(&ContourResult,0,sizeof(ContourResult)); ContourResult.ObjNo=Idx; ContourResult.Area = Moments.m00; ContourResult.Center.x = Moments.m10/Moments.m00; ContourResult.Center.y = Moments.m01/Moments.m00; cvSeqPushFront(ImageResult,&ContourResult); Idx++; } } } CalcResult(ImageResult); //PrintResults(0, res_img,ImageResult); cvDrawContours( cnt_img, contours, CV_RGB(128,0,0), CV_RGB(0,128,0), 3, 1, CV_AA, cvPoint(0,0) ); } return true; }
float mvContours::match_circle (IplImage* img, MvCircleVector* circle_vector, COLOR_TRIPLE color, int method) { assert (img != NULL); assert (img->nChannels == 1); int n_contours = find_contour_and_check_errors(img); if (n_contours < 1 || m_contours == NULL) return -1; bin_calc.start(); CvSeq* c_contour = m_contours; int n_circles = 0; // debug //mvWindow window("contours"); // examine each contour, put the passing ones into the circle_vector for (int C = 0; C < n_contours; C++, c_contour = c_contour->h_next) { // debug /*cvZero (img); draw_contours (c_contour, img); //window.showImage (img); cvWaitKey(0);*/ // check that there are at least 6 points if (c_contour->total < 6) { continue; } // check the contour's area to make sure it isnt too small double area = cvContourArea(c_contour); if (area < img->width*img->height/600) { DEBUG_PRINT ("Circle Fail: Contour too small!\n"); continue; } // do some kind of matching to ensure the contour is a circle CvMoments moments; cvContourMoments (c_contour, &moments); cv::Moments cvmoments(moments); double nu11 = cvmoments.nu11; double nu20 = cvmoments.nu02; double nu02 = cvmoments.nu20; double nu21 = cvmoments.nu21; double nu12 = cvmoments.nu12; double nu03 = cvmoments.nu03; double nu30 = cvmoments.nu30; double r03 = fabs(nu30 / nu03); r03 = (r03 > 1) ? r03 : 1.0/r03; double r12 = fabs(nu12 / nu21); r12 = (r12 > 1) ? r12 : 1.0/r12; double r02 = fabs(nu02 / nu20); r02 = (r02 > 1) ? r02 : 1.0/r02; double r11 = fabs( MEAN2(nu02,nu20) / nu11); double R = MEAN2(nu20,nu02) / std::max((MEAN2(nu21,nu12)), (MEAN2(nu30,nu03))); bool pass = true; pass = (r03 <= 25.0) && (r12 <= 12.0) && (r02 <= 12.0) && (r11 > 2.5) && (R > 25); if (!pass) { //DEBUG_PRINT ("Circle Moms: nu11=%lf, nu20=%lf, nu02=%lf, nu21=%lf, nu12=%lf, nu30=%lf, nu03=%lf\n", nu11, nu20, nu02, nu21, nu12, nu30, nu03); DEBUG_PRINT ("Circle Fail: \tn30/n03=%3.1lf, n21/n12=%3.1lf, nu20/nu02=%3.1lf, r11=%3.1f, R=%3.1f!\n", r03, r12, r02, r11, R); continue; } // get area and perimeter of the contour //double perimeter = cvArcLength (c_contour, CV_WHOLE_SEQ, 1); // get min enclosing circle and radius CvPoint2D32f centroid32f; float radius; cvMinEnclosingCircle(c_contour, ¢roid32f, &radius); if (radius > img->width/2 || radius < 0) { continue; } // do checks on area and perimeter double area_ratio = area / (CV_PI*radius*radius); //double perimeter_ratio = perimeter / (2*CV_PI*radius); if (area_ratio < 0.7) { DEBUG_PRINT ("Circle Fail: Area: %6.2lf\n", area_ratio); continue; } MvCircle circle; circle.center.x = static_cast<int>(centroid32f.x); circle.center.y = static_cast<int>(centroid32f.y); circle.radius = radius; circle.m1 = color.m1; circle.m2 = color.m2; circle.m3 = color.m3; assign_color_to_shape (color, &circle); circle.validity = area_ratio; circle_vector->push_back(circle); //cvCircle (img, cvPoint(x,y), static_cast<int>(radius), CV_RGB(50,50,50), 2); n_circles++; } bin_calc.stop(); return n_circles; }
int bw_detect_blobs(Tracker *tracker, struct StaticData *data) { /* circular kernel for dilation */ IplConvKernel *kernel = cvCreateStructuringElementEx(3,3,1,1,CV_SHAPE_ELLIPSE); /* temporary image to hold thresholded camera frame */ IplImage *thresh = cvCreateImage(cvGetSize(tracker->frame),IPL_DEPTH_8U,1); /* variables for contour finding */ CvMemStorage *mem = cvCreateMemStorage(0); CvSeq *contour; CvMoments moments; int it; /** * preprocessing **/ /* threshold image, reasonably stable since frame is highly underexposed and LEDs are very bright */ cvThreshold(tracker->frame,thresh,180,255,CV_THRESH_BINARY); /* Dilate image to increase size of responses from thresholding, gives more stable result in contour finding*/ cvDilate(thresh,thresh,kernel,2); // cvShowImage("thresh",thresh); /** * blob extraction (connected component finding) **/ /* find contours in image, should give one contour for each markers */ int nc = cvFindContours(thresh,mem,&contour,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE); // printf("nc = %d\n",nc); it = 0; /* if NUM_OF_MARKERS contours detected, compute mean position of each contour */ if(nc==data->NUM_OF_MARKERS) { if(contour) { // cvDrawContours(thresh,contour,cvScalarAll(255),cvScalarAll(0),100); CvSeq *c; for(c=contour; c!=NULL; c=c->h_next) { /* compute moments for each contour */ cvContourMoments(c,&moments); /* make sure the contour encloses some area */ if(moments.m00>0.0) { /* compute center of mass -> mean blob position */ /* even though the computed position is stored in the marker structs, it doesn't neccessarily correspond to that specific marker */ tracker->marker[it]->blob_pos.x = moments.m10/moments.m00; tracker->marker[it]->blob_pos.y = moments.m01/moments.m00; // printf("(%f %f)\n",tracker->marker[it]->blob_pos.x,tracker->marker[it]->blob_pos.y); } else { /* for stable marker recognition all markers must have been detected */ tracker->state = OFF_TRACK; break; } it++; } } } else { tracker->state = OFF_TRACK; for(int nm=0; nm<data->NUM_OF_MARKERS; ++nm) { tracker->marker[nm]->pos_is_set = 0; tracker->marker[nm]->blob_pos.x = 0; tracker->marker[nm]->blob_pos.y = 0; } } /* clean up memory */ cvReleaseMemStorage(&mem); cvReleaseImage(&thresh); return nc; }