Пример #1
0
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));
}
Пример #2
0
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;
}
Пример #3
0
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, &centroid32f, &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;
}