示例#1
0
//在图像srcImg上根据contour轮廓画上最小外接椭圆
CvBox2D DrawMinAreaEllipse(IplImage *srcImg,CvSeq *contour,CvScalar color/*=CV_RGB(255,0,0)*/)
{
	int count = contour->total; // This is number point in contour
	CvPoint center;
	CvSize size;
	CvBox2D box;

	if( count < 6 )
		return box;

	CvMat* points_f = cvCreateMat( 1, count, CV_32FC2 );
	CvMat points_i = cvMat( 1, count, CV_32SC2, points_f->data.ptr );
	cvCvtSeqToArray( contour, points_f->data.ptr, CV_WHOLE_SEQ );
	cvConvert( &points_i, points_f );
	// 椭圆拟合
	box = cvFitEllipse2( points_f );
	cout<<"拟合的椭圆参数:angle="<<box.angle<<",center=("<<box.center.x<<","
		<<box.center.y<<")"<<",size(w,h)=("<<box.size.width<<","<<box.size.height<<")"<<endl;
	// 获得椭圆参数
	center = cvPointFrom32f(box.center);
	size.width = cvRound(box.size.width*0.5)+1;
	size.height = cvRound(box.size.height*0.5)+1;
	// 画椭圆
	cvEllipse(srcImg, center, size,
		-box.angle, 0, 360,	color, 1, CV_AA, 0);
	cvReleaseMat(&points_f);
	return box;
}
示例#2
0
// Define trackbar callback functon. This function find contours,
// draw it and approximate it by ellipses.
void process_image(int h)
{
    CvMemStorage* storage;
    CvSeq* contour;

    // Create dynamic structure and sequence.
    storage = cvCreateMemStorage(0);
    contour = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , storage);

    // Threshold the source image. This needful for cvFindContours().
    cvThreshold( image03, image02, slider_pos, 255, CV_THRESH_BINARY );

    // Find all contours.
    cvFindContours( image02, storage, &contour, sizeof(CvContour),
                    CV_RETR_LIST, CV_CHAIN_APPROX_NONE, cvPoint(0,0));

    // Clear images. IPL use.
    cvZero(image02);
    cvZero(image04);

    // This cycle draw all contours and approximate it by ellipses.
    for(;contour;contour = contour->h_next)
    {
        int count = contour->total; // This is number point in contour
        CvPoint center;
        CvSize size;
        CvBox2D box;

        // Number point must be more than or equal to 6 (for cvFitEllipse_32f).
        if( count < 6 )
            continue;

        CvMat* points_f = cvCreateMat( 1, count, CV_32FC2 );
        CvMat points_i = cvMat( 1, count, CV_32SC2, points_f->data.ptr );
        cvCvtSeqToArray( contour, points_f->data.ptr, CV_WHOLE_SEQ );
        cvConvert( &points_i, points_f );

        // Fits ellipse to current contour.
        box = cvFitEllipse2( points_f );

        // Draw current contour.
        cvDrawContours(image04,contour,CV_RGB(255,255,255),CV_RGB(255,255,255),0,1,8,cvPoint(0,0));

        // Convert ellipse data from float to integer representation.
        center = cvPointFrom32f(box.center);
        size.width = cvRound(box.size.width*0.5);
        size.height = cvRound(box.size.height*0.5);

        // Draw ellipse.
        cvEllipse(image04, center, size,
                  -box.angle, 0, 360,
                  CV_RGB(0,0,255), 1, CV_AA, 0);

        cvReleaseMat(&points_f);
    }

    // Show image. HighGUI use.
    cvShowImage( "Result", image04 );
}
示例#3
0
/*
 * PlatoFilter combines some of the other pre-defined filters to
 * determine if a given contour belongs to a plastic Dish
 */
int Contours::platoFilter(){
	
	CvMemStorage* mem = cvCreateMemStorage(0);
	
	//Number of points should be at least 6.
	if(this->c->total<6)
		return false;
	
	CvBox2D box=cvMinAreaRect2(this->c,mem);
	CvBox2D box2=cvFitEllipse2(this->c);
	
	cvReleaseMemStorage(&mem);
	
	double majorAxis,minorAxis;
	double majorAxis2,minorAxis2;
	
	
	if(box2.size.width>box2.size.height){
		majorAxis=box2.size.width;
		minorAxis=box2.size.height;
	}else{
		minorAxis=box2.size.width;
		majorAxis=box2.size.height;
	}
	
	if(box.size.width>box.size.height){
		majorAxis2=box.size.width;
		minorAxis2=box.size.height;
	}else{
		minorAxis2=box.size.width;
		majorAxis2=box.size.height;
	}
	
	double boxDiff=fabs(majorAxis - majorAxis2) + fabs(minorAxis-minorAxis2);
	//eccentricity formula
	double ecc=sqrt(majorAxis*majorAxis -minorAxis*minorAxis)/majorAxis;
	
	
	double calcArea=miPI*(majorAxis/2)*(minorAxis/2);
	double realArea=this->getArea();
	
	//Area of approximated elipse and of the contour should be similar.
	if(fabs(calcArea-realArea)/realArea > 0.2)
		return false;
	
	//gets circularity
	double circ=this->getCircularity();
	
	if(circ<10 || circ>20)
		return false;
	
	if(ecc<0.65 || ecc>0.95)
		return false;
	
	return true;
}
示例#4
0
/**
- FUNCTION: GetEllipse
- FUNCTIONALITY: Calculates the ellipse that best fits the edges of the blob
- PARAMETERS:
- RESULT:
	- CvBox2D struct with the calculated ellipse
- RESTRICTIONS:
- AUTHOR: Ricard Borr�
- CREATION DATE: 25-05-2005.
- MODIFICATION: Date. Author. Description.
*/
CvBox2D CBlob::GetEllipse() const
{
	CvBox2D elipse;
	// necessitem 6 punts per calcular l'elipse
	if( edges != NULL && edges->total > 6)
	{
		elipse = cvFitEllipse2( edges );
	}
	else
	{
		elipse.center.x = 0.0;
		elipse.center.y = 0.0;
		elipse.size.width = 0.0;
		elipse.size.height = 0.0;
		elipse.angle = 0.0;
	}
	return elipse;
}
void defense::ImageToEllipseList(IplImage* TheInput,int PlaneNumber){

    priority_queue<TheEllipse, vector<TheEllipse>,less<vector<TheEllipse>::value_type> > EllipQueue;
    
    TheTargetsEllipses.clear();
    
    CvMemStorage* G_storage=NULL;
	G_storage=cvCreateMemStorage(0);   
    CvSeq* contour = 0;
    IplImage * Maska;
    Maska = cvCreateImage( cvGetSize(TheInput),IPL_DEPTH_8U,1); 
    int TotalEllip=0;
    
    for (int k=0;k<PlaneNumber;k++){ 
        cvInRangeS(TheInput,cvScalarAll((k-1)*255/(float)PlaneNumber),cvScalarAll(k*255/(float)PlaneNumber),Maska);
        cvSmooth(Maska,Maska,CV_MEDIAN,3);  
        int NC=cvFindContours( Maska, G_storage, &contour, sizeof(CvContour), 
                              CV_RETR_EXTERNAL, CV_CHAIN_APPROX_TC89_L1 );
            for( ; contour != 0; contour = contour->h_next )
            {
                
                if ((contour->total > 10 )&&(TotalEllip<MaxEllip)){
                    
                    CvMat* CountArray;
                    CvBox2D Ellipdesc;
                    CvPoint2D32f * OtroArray;
                    OtroArray = new CvPoint2D32f[contour->total];
                    for(int q=0;q<contour->total;q++){
                        CvPoint* p = (CvPoint*)cvGetSeqElem( contour, q );
                        OtroArray[q].x = (float)p->x;
                        OtroArray[q].y=(float)p->y;
                    }
                    CountArray=cvCreateMatHeader(contour->total,1,CV_32FC2);
                    cvInitMatHeader(CountArray,contour->total,1,CV_32FC2,OtroArray);
                    // calculating the best ellipse	
                    Ellipdesc=cvFitEllipse2(CountArray);
                    
                    
                    EllipQueue.push(TheEllipse(Ellipdesc.center.x,
                                               Ellipdesc.center.y,
                                               Ellipdesc.size.width,
                                               Ellipdesc.size.height,
                                               Ellipdesc.angle,
                                               k*255/PlaneNumber));
                    TotalEllip++;
                    delete [] OtroArray;
                    cvReleaseMat(&CountArray);  
                } // end of if contour-> total
                
                
            } // end of for contours
            

        
    } // end For the Planes
    while (!EllipQueue.empty()){
        TheTargetsEllipses.push_back(EllipQueue.top());
        EllipQueue.pop();
    }
    
    cvReleaseImage(&Maska);
    
    // releasing mem storages
    if (contour!=NULL){cvClearSeq(contour);}
    //cvClearMemStorage(storage);
    if (G_storage!=NULL){cvReleaseMemStorage(&G_storage);}
    
    
    

}
示例#6
0
WSNATIVE_EXPORT bool ProcessFrame(IplImage * detection, IplImage * image, float m_GSD = 20, bgfg_cb_t bgfg_cb = 0)
{
    //too few or too much detection?
    float mask_area = image->width*image->height;
    int width = image->width, height = image->width;
    float det_area = cvCountNonZero(detection);
    if (det_area < mask_area*0.00001 || det_area > mask_area*0.5 )
        return false;
    
    CvMemStorage* storage, *storage1;        
    storage = cvCreateMemStorage(0);
    storage1 = cvCreateMemStorage(0);
    CvSeq* contour;
    
    cvFindContours( detection, storage, &contour, sizeof(CvContour), CV_RETR_TREE, CV_CHAIN_APPROX_NONE);

    CvRect rectBlob[MAXBLOBCNT];
    CvBox2D rectBlob2D[MAXBLOBCNT];

    int nBlobNum = 0;

    
    //note: this line erase all detected foreground pixels
    cvZero(detection);

    //go over all the blobs
    for( ; contour != 0; contour = contour->h_next )
    {
        double fContourArea = fabs(cvContourArea(contour, CV_WHOLE_SEQ ));
        CvRect tmpRect = cvBoundingRect(contour, 1);
        float fRatio = 1.0*tmpRect.height/tmpRect.width;
        float occupy = fContourArea/(tmpRect.height*tmpRect.width);

        //TODO: make it an option
        cvDrawContours(detection,contour,CV_RGB(255,255,255),CV_RGB(255,255,255),0,CV_FILLED,8);
        
        //get the GSD(Ground Sampling Distance) for that location
        float GSD = 20;
        /*
        if (tmpRect.height/2.0 +tmpRect.y < m_Y1 )
            GSD = m_GSD1;
        else if (tmpRect.height/2.0 +tmpRect.y > m_Y2 )
            GSD = m_GSD2;
        else
            GSD = 1.0*m_GSD1*(m_Y2 - tmpRect.y - tmpRect.height/2.0 )/(m_Y2-m_Y1)+ 1.0*m_GSD2*(tmpRect.height/2.0 +tmpRect.y -m_Y1)/(m_Y2-m_Y1);
        */
        
        CvRect tmpROI = cvBoundingRect( contour, 1);
        float boundary = 3; //pixels
        float min_area = GSD*GSD*0.10 /*0.25 for regular*/, max_area = width*height;
        
        if ( ( (tmpROI.x >= boundary && tmpROI.x+tmpROI.width <= width-boundary) || fContourArea > std::min<float>(1600.0 ,max_area/36) ) && 
             fContourArea<max_area && fContourArea >= min_area && 
             !( (occupy < 0.5 &&  fContourArea/(GSD*GSD) > 4.0 ) || occupy <0.33 ) && //TODO: make it adaptive?
            nBlobNum< MAXBLOBCNT)
        {
            rectBlob[nBlobNum] = tmpROI;

            CvBox2D box2d = cvFitEllipse2( contour);
            rectBlob2D[nBlobNum] = box2d;

            nBlobNum++;

            //draw outline
            //cvDrawContours(showimage,contour,CV_RGB(255,255,255),CV_RGB(255,255,255),1,1,8);
        }
    }

    for (int j = 0; j< nBlobNum; j++)
    {
    //get the attributes of each blob here
        if(bgfg_cb) {
            const CvRect& r = rectBlob[j];
            bgfg_cb(r.x, r.y, r.width, r.height);
        }
    }

    cvReleaseMemStorage( &storage); 
    cvReleaseMemStorage( &storage1); 

    return true;
}
示例#7
0
文件: Gesture1.cpp 项目: thorikawa/N3
  void Gesture1::trackMarker (IplImage* destImg, CvPoint _r, CvPoint _b, CvPoint _g, CvPoint _y) {
    
    // find tissue box!
    CvPoint* objPoints = objectDetector->detect(destImg);

    // draw
    world->Step(1.0F/6.0F, 10, 10);
    cvLine(destImg, cvPoint(0,HEIGHT), cvPoint(1000,HEIGHT), CV_RGB(0,255,0), 3);
    for (b2Body* b = world->GetBodyList(); b; b = b->GetNext()) {
      //printf("**draw body\n");
      Box2DData* userData = (Box2DData*)b->GetUserData();
      if (userData != NULL) {
        if (strcmp(userData->type, "Circle") == 0) {
          //b2Vec2 v = b->GetWorldCenter();
          b2Vec2 v = b->GetPosition();
          //printf("** x=%f y=%f r=%f\n", v.x, v.y, userData->radius);
          CvPoint center = cvPoint(v.x*WORLD_SCALE, v.y*WORLD_SCALE);
          cvCircle(destImg, center, userData->radius*WORLD_SCALE, CV_RGB(255,0,0), -1);
        } else if (strcmp(userData->type, "Box") == 0) {
          world->DestroyBody(b);
        }
      }      
    }
    if (objPoints != NULL) {
      printf("construct body\n");
      b2PolygonShape cs;
      b2Vec2 vertices[4] = {
        b2Vec2((float)(objPoints[0].x)/WORLD_SCALE, (float)(objPoints[0].y)/WORLD_SCALE),
        b2Vec2((float)(objPoints[1].x)/WORLD_SCALE, (float)(objPoints[1].y)/WORLD_SCALE),
        b2Vec2((float)(objPoints[2].x)/WORLD_SCALE, (float)(objPoints[2].y)/WORLD_SCALE),
        b2Vec2((float)(objPoints[3].x)/WORLD_SCALE, (float)(objPoints[3].y)/WORLD_SCALE)
      };
      cs.Set(vertices, 4);
      b2BodyDef bd;
      //bd.type = b2_staticBody;
      Box2DData* obj = new Box2DData();
      strcpy(obj->type, "Box");
      bd.userData = obj;
      b2Body* body1 = world->CreateBody(&bd);
      body1->CreateFixture(&cs, 0.0f);
    }

    if (_r.x < 0) return;
    Point2D r = toPoint2D(_r);
    
    // if marker is not moving for a while, reset the path
    int len = path.size();
    if (len > KEEP_MAX) {
      path.erase(path.begin());
    }
    int nearCount = 0;
    int actual = min(KEEP_COUNT, len);
    
    /*
     for(int i=0; i<actual; i++){
     Point2D p = path[len-1-i];
     double d = dist(p, r);
     //printf("dist=%f\n", d);
     if (d < NEAR_THRESHOLD) ++nearCount;
     }
     if (nearCount > (double)actual * DONT_MOVE_THRESHOLD_RATE) {
     // marker is not moving, so clear the path
     printf("cleared\n");
     path.clear();
     }
     */
    
    path.push_back(r);

    // decide if we should recognize
    time_t current;
    time(&current);
    double interval = difftime(current, lastTime);
    printf("interval=%f\n", interval);
    if (interval < INTERVAL_SEC) return;

    len = path.size();
    if (len < 5) return;

    RecognitionResult res = g.recognize(path);
    printf("%s:%f\n", res.name.c_str(), res.score);
    if (res.name == "Circle" && res.score > SCORE_THRESHOLD) {
      printf("##circle detect##\n");
      // convert to vector<Point2D> to CvSeq<CvPoint>
      CvSeqWriter writer;
      CvMemStorage* storage = cvCreateMemStorage(0);
      cvStartWriteSeq( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage, &writer);
      for (int i=0; i<len; i++) {
        CvPoint pt = toCvPoint(path[i]);
        CV_WRITE_SEQ_ELEM(pt, writer);
      }
      CvSeq* seq = cvEndWriteSeq(&writer);
      CvBox2D ellipse = cvFitEllipse2(seq);
      float radius = std::min(ellipse.size.width, ellipse.size.height)/(4.0F*WORLD_SCALE);
      cvEllipseBox(destImg, ellipse, CV_RGB(0,255,255), -1);

      // add Box2D object
      {
        b2CircleShape cs;
        cs.m_radius = radius;
        printf(" x=%f y=%f radius:%f\n", ellipse.center.x/WORLD_SCALE, ellipse.center.y/WORLD_SCALE, radius);
        b2BodyDef bd;
        bd.type = b2_dynamicBody;
        bd.position.Set(ellipse.center.x/WORLD_SCALE, ellipse.center.y/WORLD_SCALE);
        Box2DData* obj = new Box2DData();
        strcpy(obj->type, "Circle");
        obj->radius = radius;
        bd.userData = obj;
        b2Body* body1 = world->CreateBody(&bd);
        b2FixtureDef fixtureDef;
        fixtureDef.shape = &cs;
        fixtureDef.density = 1.0f;
        fixtureDef.friction = 0.3f;
        fixtureDef.restitution = 0.6f;
        body1->CreateFixture(&fixtureDef);
      }

      time(&lastTime);

      //cvEllipseBox(destImg, ellipse, CV_RGB(125,125,255));
    }
  }
示例#8
0
void cvFitEllipse( const CvPoint2D32f* points, int count, CvBox2D* box )
{
    CvMat mat = cvMat( 1, count, CV_32FC2, (void*)points );
    *box = cvFitEllipse2( &mat );
}
int main( int argc, char** argv )
{
	char path[1024];
	IplImage* img;
	help();
	if (argc!=2)
	{
		strcpy(path,"puzzle.png");
		img = cvLoadImage( path, CV_LOAD_IMAGE_GRAYSCALE );
		if (!img)
		{
			printf("\nUsage: mser_sample <path_to_image>\n");
			return 0;
		}
	}
	else
	{
		strcpy(path,argv[1]);
		img = cvLoadImage( path, CV_LOAD_IMAGE_GRAYSCALE );
	}
	
	if (!img)
	{
		printf("Unable to load image %s\n",path);
		return 0;
	}
	IplImage* rsp = cvLoadImage( path, CV_LOAD_IMAGE_COLOR );
	IplImage* ellipses = cvCloneImage(rsp);
	cvCvtColor(img,ellipses,CV_GRAY2BGR);
	CvSeq* contours;
	CvMemStorage* storage= cvCreateMemStorage();
	IplImage* hsv = cvCreateImage( cvGetSize( rsp ), IPL_DEPTH_8U, 3 );
	cvCvtColor( rsp, hsv, CV_BGR2YCrCb );
	CvMSERParams params = cvMSERParams();//cvMSERParams( 5, 60, cvRound(.2*img->width*img->height), .25, .2 );

	double t = (double)cvGetTickCount();
	cvExtractMSER( hsv, NULL, &contours, storage, params );
	t = cvGetTickCount() - t;
	printf( "MSER extracted %d contours in %g ms.\n", contours->total, t/((double)cvGetTickFrequency()*1000.) );
	uchar* rsptr = (uchar*)rsp->imageData;
	// draw mser with different color
	for ( int i = contours->total-1; i >= 0; i-- )
	{
		CvSeq* r = *(CvSeq**)cvGetSeqElem( contours, i );
		for ( int j = 0; j < r->total; j++ )
		{
			CvPoint* pt = CV_GET_SEQ_ELEM( CvPoint, r, j );
			rsptr[pt->x*3+pt->y*rsp->widthStep] = bcolors[i%9][2];
			rsptr[pt->x*3+1+pt->y*rsp->widthStep] = bcolors[i%9][1];
			rsptr[pt->x*3+2+pt->y*rsp->widthStep] = bcolors[i%9][0];
		}
	}
	// find ellipse ( it seems cvfitellipse2 have error or sth?
	for ( int i = 0; i < contours->total; i++ )
	{
		CvContour* r = *(CvContour**)cvGetSeqElem( contours, i );
		CvBox2D box = cvFitEllipse2( r );
		box.angle=(float)CV_PI/2-box.angle;
		
		if ( r->color > 0 )
			cvEllipseBox( ellipses, box, colors[9], 2 );
		else
			cvEllipseBox( ellipses, box, colors[2], 2 );
			
	}

	cvSaveImage( "rsp.png", rsp );

	cvNamedWindow( "original", 0 );
	cvShowImage( "original", img );
	
	cvNamedWindow( "response", 0 );
	cvShowImage( "response", rsp );

	cvNamedWindow( "ellipses", 0 );
	cvShowImage( "ellipses", ellipses );

	cvWaitKey(0);

	cvDestroyWindow( "original" );
	cvDestroyWindow( "response" );
	cvDestroyWindow( "ellipses" );
	cvReleaseImage(&rsp);
	cvReleaseImage(&img);
	cvReleaseImage(&ellipses);
	
}