Ejemplo n.º 1
0
//! Copy operator
CBlobContour& CBlobContour::operator=( const CBlobContour &source )
{
	if( this != &source )
	{		
		m_startPoint = source.m_startPoint;

		m_parentStorage = source.m_parentStorage;
		
		if (m_contour)
		{
			cvClearSeq( m_contour );
		}

		if (source.m_contour)
		{
			m_contour =	cvCloneSeq( source.m_contour, m_parentStorage);
		}
		
		if( source.m_contourPoints )
		{
			if( m_contourPoints )
				cvClearSeq( m_contourPoints );
			m_contourPoints = cvCloneSeq( source.m_contourPoints, m_parentStorage);
		}

		m_area = source.m_area;
		m_perimeter = source.m_area;
		m_moments = source.m_moments;
	}
	return *this;
}
Ejemplo n.º 2
0
void ShapeClassifier::StartTraining(TrainingSet *sampleSet) {
	// Make a copy of the set used for training (we'll want to save it later)
	sampleSet->CopyTo(&trainSet);

	cvClearMemStorage(templateStorage);
    templateContours = NULL;

    // TODO: call into trainingset class to do this instead of accessing samplemap
    for (map<UINT, TrainingSample*>::iterator i = sampleSet->sampleMap.begin(); i != sampleSet->sampleMap.end(); i++) {
        TrainingSample *sample = (*i).second;
        if (sample->iGroupId == GROUPID_POSSAMPLES) { // positive sample

            IplImage *grayscale = cvCreateImage( cvSize(sample->fullImageCopy->width, sample->fullImageCopy->height), IPL_DEPTH_8U, 1);
            cvCvtColor(sample->fullImageCopy, grayscale, CV_BGR2GRAY);
            cvCanny(grayscale, grayscale, SHAPE_CANNY_EDGE_LINK, SHAPE_CANNY_EDGE_FIND, SHAPE_CANNY_APERTURE);
			cvDilate(grayscale, grayscale, 0, 2);

            CvMemStorage *storage = cvCreateMemStorage(0);
            CvSeq *sampleContours = NULL;

            cvFindContours(grayscale, storage, &sampleContours, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_TC89_KCOS);
			if (sampleContours != NULL) {
			    sampleContours = cvApproxPoly(sampleContours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, 0.2, 1 );
				for (CvSeq *contour = sampleContours; contour != NULL; contour = contour->h_next)
				{
					if ((contour->total > SHAPE_MIN_CONTOUR_POINTS) && (contour->flags & CV_SEQ_FLAG_CLOSED)){
						if (!templateContours) {
							templateContours = cvCloneSeq(contour, templateStorage);
						} else {
							CvSeq *newContour = cvCloneSeq(contour, templateStorage);
							newContour->h_next = templateContours->h_next;
							templateContours->h_next = newContour;
						}
					}
				}
			}
            cvReleaseMemStorage(&storage);
            cvReleaseImage(&grayscale);

		} else if (sample->iGroupId == GROUPID_NEGSAMPLES) { // negative sample
            // do nothing for now
            // TODO: we could compare guesses against these as well and remove them if they match
        }
    }

    UpdateContourImage();

    if (isOnDisk) { // this classifier has been saved so we'll update the files
        Save();        
    }

    // update member variables
	isTrained = true;
}
Ejemplo n.º 3
0
CBlob& CBlob::operator=(const CBlob &src )
{
	if( this != &src )
	{
		m_id = src.m_id;
		m_area = src.m_area;
		m_perimeter = src.m_perimeter;
		m_externPerimeter = src.m_externPerimeter;
		m_meanGray = src.m_meanGray;
		m_stdDevGray = src.m_stdDevGray;
		m_boundingBox = src.m_boundingBox;
		m_ellipse = src.m_ellipse;
		m_originalImageSize = src.m_originalImageSize;
		
		// clear all current blob contours
		ClearContours();
		
		if( m_storage )
			cvReleaseMemStorage( &m_storage );

		m_storage = cvCreateMemStorage();

		m_externalContour = CBlobContour(src.m_externalContour.GetStartPoint(), m_storage );
		if( src.m_externalContour.m_contour )
			m_externalContour.m_contour = cvCloneSeq( src.m_externalContour.m_contour, m_storage);
		m_internalContours.clear();

		// copy all internal contours
		if( src.m_internalContours.size() )
		{
			m_internalContours = t_contourList( src.m_internalContours.size() );
			t_contourList::const_iterator itSrc;
			t_contourList::iterator it;

			itSrc = src.m_internalContours.begin();
			it = m_internalContours.begin();

			while (itSrc != src.m_internalContours.end())
			{
				*it = CBlobContour((*itSrc).GetStartPoint(), m_storage);
				if( (*itSrc).m_contour )
					(*it).m_contour = cvCloneSeq( (*itSrc).m_contour, m_storage);

				it++;
				itSrc++;
			}
		}
	}

	return *this;
}
Ejemplo n.º 4
0
CvSeq *reghand::filthull(CvSeq *hullseq)
{
    int thresh=handcenter.y;
    CvSeq *filtedhullseq=cvCloneSeq(hullseq);
    cvClearSeq(filtedhullseq);
    for (int i=0;i<hullseq->total;i++)
    {
        CvPoint** data=CV_GET_SEQ_ELEM(CvPoint*,hullseq,i);
        CvPoint currpt=**data;
        if(currpt.y<thresh)
            cvSeqPush(filtedhullseq,data);

        ;
    }
    return filtedhullseq;
}
Ejemplo n.º 5
0
CvSeq *reghand::elimNeighborHulls(CvSeq *hullseq)
{
    int disthreshold=handradis/3;
    CvSeq *filtedhullseq=cvCloneSeq(hullseq);
    if(hullseq->total<=1) return filtedhullseq;
    cvClearSeq(filtedhullseq);
    CvPoint **curdata;CvPoint currpt,nextpt;
    for(int i=0;i<hullseq->total-1;i++)
    {
        curdata=CV_GET_SEQ_ELEM(CvPoint*,hullseq,i);
        currpt=**curdata;
        nextpt=**CV_GET_SEQ_ELEM(CvPoint*,hullseq,i+1);
        double distance=sqrt(pow(double(currpt.x-nextpt.x),2)+pow(double(currpt.y-nextpt.y),2));
        if(distance>disthreshold) cvSeqPush(filtedhullseq,curdata);

    }
    //	if(hullseq->total==2)return filtedhullseq;
    curdata=CV_GET_SEQ_ELEM(CvPoint*,hullseq,hullseq->total-1);
    currpt=**curdata;
    nextpt=**CV_GET_SEQ_ELEM(CvPoint*,hullseq,0);
    double distance=sqrt(pow(double(currpt.x-nextpt.x),2)+pow(double(currpt.y-nextpt.y),2));
    if(distance>disthreshold) cvSeqPush(filtedhullseq,curdata);
    return filtedhullseq;
}
Ejemplo n.º 6
0
/*
 *
 * Creates a worm polygon object from a CvSeq of Points.
 * This will clone the CvSeq and copy it into the memory storage
 * specified
 */
WormPolygon* CreateWormPolygonFromSeq(CvMemStorage* memory,CvSize GridSize,CvSeq* points){
	WormPolygon* myPoly=(WormPolygon*) malloc(sizeof(WormPolygon));
	myPoly->Points=cvCloneSeq(points,memory);
	myPoly->GridSize=GridSize;
	return myPoly;
}
Ejemplo n.º 7
0
 CvSeq * cvCloneSeq_wrap(const CvSeq * seq , CvMemStorage * storage ){
	return cvCloneSeq(/*const*//*CvSeq*//***/seq , /*CvMemStorage*//***/storage);
}
Ejemplo n.º 8
0
void Distinguish::FunctionSwitch(CvSeq* circles){
	/*
	ThreeButtonsCombination SwitchCase=1;
	MouseMove               SwitchCase=2;
	Combination             SwitchCase=3;
	TwoFingersMouse         SwitchCase=4;
	ThreeFingerMouse        SwitchCase=5;
	*/
	for(int i=0;i<circles->total;i++){//if fingers are not in keyboard area,that must be mouse action
		float* p=(float*)cvGetSeqElem(circles,0);
		if(cvRound(p[0])<65 || cvRound(p[0])>590 ||cvRound(p[1])<35||cvRound(p[1])>410){
			mouse.MouseGesture(circles);
			SwitchCounter=0;
			SwitchCase=0;
			return;
		}
	}
	SwitchCounter++;
	if(SwitchCounter==1){//initialize 
		circlesTemp=cvCloneSeq(circles,NULL);
	}
	switch (circles->total){//To switch amont different numbers of circles
		case 0://if zero finger circle,pass this to both and they will have corresponding actions
			pattern.estimation(circles);
			MouseMoveToLeftClick++;
			keyboard.OutputKey(circles);
			mouse.MouseGesture(circles);
			SwitchCounter=0;
			SwitchCase=0;
			if(MouseMoveToLeftClick>=10){//count for left click
				MouseMoveToLeftClick=0;
				SingleClick=false;
			}
			break;
		case 1:
			pattern.estimation(circles);
			int PointTemp[2];
			int Point[2];
			if(SwitchCase==2){
				mouse.MouseGesture(circles);
				break;
			}
			if(SingleClick==true && MouseMoveToLeftClick!=0){
				mouse.MouseGesture(circles);
				MouseMoveToLeftClick=0;
				break;
			}
			if(circlesTemp->total==1 && circles->total==1){
				float* p=(float*)cvGetSeqElem(circlesTemp,0);
				PointTemp[0]=cvRound(p[0]);
				PointTemp[1]=cvRound(p[1]);
			    float* q=(float*)cvGetSeqElem(circles,0);
				Point[0]=cvRound(q[0]);
				Point[1]=cvRound(q[1]);
			}
			if(abs(Point[0]-PointTemp[0])<10 && abs(Point[1]-PointTemp[1])<10){
				SwitchCase=1;
				keyboard.OutputKey(circles);
				break;
			}else if((abs(Point[0]-PointTemp[0])>10 || abs(Point[1]-PointTemp[1])>10)){
				SwitchCase=2;
				SingleClick=true;
				mouse.MouseGesture(circles);
				break;
			}
		case 2:
			if(SwitchCase==3){
				keyboard.OutputKey(circles);
				break;
			}else if (SwitchCase==4){
				mouse.MouseGesture(circles);
				break;
			}
			if(circlesTemp->total==1&& circles->total==2){
				keyboard.OutputKey(circles);
				SwitchCase=3;
				break;
			}else{
				mouse.MouseGesture(circles);
				SwitchCase=4;
				break;
			}
		case 3:
			if(SwitchCase==1){
				keyboard.OutputKey(circles);
				break;
			}else if (SwitchCase==5){
				mouse.MouseGesture(circles);
				break;
			}
			if(circlesTemp->total==2&& circles->total==3){
				keyboard.OutputKey(circles);
				SwitchCase=1;
				break;
			}else{
				mouse.MouseGesture(circles);
				SwitchCase=5;
				break;
			}
		default://more then three fingers are all mouse actions
			mouse.MouseGesture(circles);
		    SwitchCounter=0;
			SwitchCase=0;
			break;
	}
	circlesTemp=cvCloneSeq(circles,NULL);
}
Ejemplo n.º 9
0
//////////////////////
//
//   원 검출
//
//////////////////////
void ColorTracking::draw_circle(IplImage* image)
{
	
	CvSeq* m_circle = NULL;					// 원 정보
	CvMemStorage* storage1 = NULL;			// 메모리 할당

	//검출된 원을 위한 메모리 공간 할당
	storage1 = cvCreateMemStorage(0);

	//원 갯수 저장 변수
	circle_cnt = 0;

	//원의 중심점을 검출하기 위한 누산기의 해상도
	// 1이면 입력영상과 같은 크기, 2이면 입력 영상의 가로/세로의 반크기의 누산기
	double dp = 1.5; 
	double min_dist = 300;				//검출된 원의 중심 사이의 최소거리.작을 수록 많은 원이 검출 됨-? 
	double cannyThreshold = 100;		//cvCanny 함수 임계값
	double accThreshold = 50;			//cvCanny 함수 축적평면의 임계값
	int min_radius = 50;				//최소 반지름
	int max_radius = 150;				//최대 반지름
	int cx, cy = 0;
		
	//소스영상, 메모리스토리지 포인터, 메소드인자, 영상의 해상도, 인접한 두 원사이의 최소거리
	m_circle = cvHoughCircles(image, storage1, CV_HOUGH_GRADIENT,
		dp,min_dist, cannyThreshold, accThreshold, min_radius, max_radius);

		//원이 1개 라도 있으면
	if(m_circle->total >0 )
	{
		// 데이터를 내보내기 위한 전역 선언한 시퀸스로 복사
		circles = cvCloneSeq(m_circle, storage0);

		//원 그리기
		for(int k = 0; k < m_circle->total; k++)
		{
			float* circle;
			int radius;

			//검출된 원을 저장한 circles에서 원의 파라미터를 circle에 저장
			//원의 중심 좌표 및 반지름이 배열에 순서대로 저장됨
			circle = (float*)cvGetSeqElem(m_circle, k);
			cx     = cvRound(circle[0]);     //중심점 x 좌표
			cy     = cvRound(circle[1]);     //중심점 y 좌표
			radius = cvRound(circle[2]);     //반지름

			//원그리기
			
			if(radius > min_radius && radius < max_radius)
			{
				//중심점
				cvCircle(m_orig_img, cvPoint(cx, cy), 3, CV_RGB(240,0,255), -1, 8, 0);

				//검출라인
				cvCircle(m_orig_img, cvPoint(cx, cy), radius, CV_RGB(255,255,255), 3, 8, 0);

			}	
		}
	}
	else // 원이 없으면
	{
		circles = NULL;
		circle_cnt = 0;
	}

	cvReleaseMemStorage(&storage1);
}
Ejemplo n.º 10
0
/*
 * Smooths, thresholds and finds the worms contour.
 * The original image must already be loaded into Worm.ImgOrig
 * The Smoothed image is deposited into Worm.ImgSmooth
 * The thresholded image is deposited into Worm.ImgThresh
 * The Boundary is placed in Worm.Boundary
 *
 */
void FindWormBoundary(WormAnalysisData* Worm, WormAnalysisParam* Params){
	/** This function currently takes around 5-7 ms **/
	/**
	 * Before I forget.. plan to make this faster by:
	 *  a) using region of interest
	 *  b) decimating to make it smaller (maybe?)
	 *  c) resize
	 *  d) not using CV_GAUSSIAN for smoothing
	 */

	/** Smooth the Image **/
	TICTOC::timer().tic("cvSmooth");
	cvSmooth(Worm->ImgOrig,Worm->ImgSmooth,CV_GAUSSIAN,Params->GaussSize*2+1);
	TICTOC::timer().toc("cvSmooth");

	/** Dilate and Erode **/
//	cvDilate(Worm->ImgSmooth, Worm->ImgSmooth,NULL,3);
//	cvErode(Worm->ImgSmooth, Worm->ImgSmooth,NULL,2);


	/** Threshold the Image **/
	TICTOC::timer().tic("cvThreshold");
	cvThreshold(Worm->ImgSmooth,Worm->ImgThresh,Params->BinThresh,255,CV_THRESH_BINARY );
	TICTOC::timer().toc("cvThreshold");


	/** Dilate and Erode **/
	if (Params->DilateErode==1){
		TICTOC::timer().tic("DilateAndErode");
		cvDilate(Worm->ImgThresh, Worm->ImgThresh,NULL,3);
		cvErode(Worm->ImgThresh, Worm->ImgThresh,NULL,2);
		TICTOC::timer().toc("DilateAndErode");
	}


	/** Find Contours **/
	CvSeq* contours;
	IplImage* TempImage=cvCreateImage(cvGetSize(Worm->ImgThresh),IPL_DEPTH_8U,1);
	cvCopy(Worm->ImgThresh,TempImage);
	TICTOC::timer().tic("cvFindContours");
	cvFindContours(TempImage,Worm->MemStorage, &contours,sizeof(CvContour),CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE,cvPoint(0,0));
	TICTOC::timer().toc("cvFindContours");

	CvSeq* rough;
	/** Find Longest Contour **/
	TICTOC::timer().tic("cvLongestContour");
	if (contours) LongestContour(contours,&rough);
	TICTOC::timer().toc("cvLongestContour");
	cvReleaseImage(&TempImage);

	/** Smooth the Boundary **/
	if (Params->BoundSmoothSize>0){
		TICTOC::timer().tic("SmoothBoundary");
		CvSeq* smooth=smoothPtSequence(rough,Params->BoundSmoothSize,Worm->MemStorage);
		Worm->Boundary=cvCloneSeq(smooth);
		TICTOC::timer().toc("SmoothBoundary");

	} else {
		Worm->Boundary=cvCloneSeq(rough);
	}



}
Ejemplo n.º 11
0
void Determine::FunctionSwitch(CvSeq* circles){
	/*
	KeyboardClick SwitchCase=1;
	MouseMove     SwitchCase=2;
	Combination   SwitchCase=3;
	RightClick    SwitchCase=4;
	LeftClick     SwitchCase=5;
	*/
	for(int i=0;i<circles->total;i++){
		float* p=(float*)cvGetSeqElem(circles,0);
		if(cvRound(p[0])<70 || cvRound(p[0])>590 ||cvRound(p[1])<60||cvRound(p[1])>430){
			JudgementMouse(circles);
			SwitchTemp=0;
			SwitchCase=0;
			return;
		}
	}
	SwitchTemp++;
	if(SwitchTemp==1){
		circlesTemp=cvCloneSeq(circles,NULL);
	}
	switch (circles->total){
		case 0:
			MouseMoveToLeftClick++;
			keyboard.OutputKey(circles);
			JudgementMouse(circles);
			SwitchTemp=0;
			SwitchCase=0;
			if(MouseMoveToLeftClick>=10){
				MouseMoveToLeftClick=0;
				SingleClick=false;
			}
			break;
		case 1:
			int PointTemp[2];
			int Point[2];
			if(SwitchCase==2){
					std::cout<<"come SwitchCase2"<<std::endl;
				JudgementMouse(circles);
				break;
			}
			if(SingleClick==true && MouseMoveToLeftClick!=0){
				std::cout<<"come LeftClick"<<std::endl;
				JudgementMouse(circles);
				MouseMoveToLeftClick=0;
				break;
			}
			if(circlesTemp->total==1 && circles->total==1){
				float* p=(float*)cvGetSeqElem(circlesTemp,0);
				PointTemp[0]=cvRound(p[0]);
				PointTemp[1]=cvRound(p[1]);
			    float* q=(float*)cvGetSeqElem(circles,0);
				Point[0]=cvRound(q[0]);
				Point[1]=cvRound(q[1]);
			}
			if(abs(Point[0]-PointTemp[0])<10 && abs(Point[1]-PointTemp[1])<10){
				std::cout<<"come keyboard"<<std::endl;
				SwitchCase=1;
				keyboard.OutputKey(circles);
				break;
			}else if((abs(Point[0]-PointTemp[0])>10 || abs(Point[1]-PointTemp[1])>10)){
				std::cout<<"come mouse"<<std::endl;
				SwitchCase=2;
				SingleClick=true;
				JudgementMouse(circles);
				break;
			}
		case 2:
			if(circlesTemp->total==1&& circles->total==2){
				keyboard.OutputKey(circles);
				SwitchCase=3;
				break;
			}else{
				JudgementMouse(circles);
				SwitchCase=4;
				break;
			}
			if(SwitchCase==3){
				keyboard.OutputKey(circles);
				break;
			}else if (SwitchCase==4){
				JudgementMouse(circles);
				break;
			}
		default:
			JudgementMouse(circles);
		    SwitchTemp=0;
			SwitchCase=0;
			break;
	}
	circlesTemp=cvCloneSeq(circles,NULL);
}
Ejemplo n.º 12
0
//functiown switch among mouse gesture and keyboard automatically
void Recognition::FunctionSwitch(CvSeq* TouchBlobList){
	/*
	Single key                 SwitchCase=1;
	MouseMove                  SwitchCase=2;
	Combination                SwitchCase=3;
	TwoFingersMouse            SwitchCase=4;
	ThreeFingerMouse           SwitchCase=5;
	ThreeKeysCombination       SwitchCase=6;
	*/
	//less fingers number's action can jump to more fingers numbers' action, but it can not jump back
	for(int i=0;i<TouchBlobList->total;i++){
		float* p=(float*)cvGetSeqElem(TouchBlobList,i);
		if(cvRound(p[0])<65 || cvRound(p[0])>590 ||cvRound(p[1])<35||cvRound(p[1])>410){
			MouseGestureSwitch(TouchBlobList);
			SwitchCounter=0;
			SwitchCase=0;
			return;
		}
	}
	SwitchCounter++;//the total number of how many frames come
	if(SwitchCounter==1){//initialize when first frame comes
		PreviousTouchBlobList=cvCloneSeq(TouchBlobList,NULL);
	}
	switch (TouchBlobList->total){//To switch among different numbers of circles
		case 0://if zero finger ,pass this to all functions and they will have corresponding actions
			gesture.estimation(TouchBlobList);
			MouseMoveToLeftClick++;
			keyboard.OutputKey(TouchBlobList);
			MouseGestureSwitch(TouchBlobList);
			SwitchCounter=0;//clear
			SwitchCase=0;//clear
			if(MouseMoveToLeftClick>5){//count for left click,the time between two left click should be limited 
				MouseMoveToLeftClick=0;
				SingleClick=false;//forget last click,begin a new one
			}
			keyboard.UpKeys();
			break;
		case 1:
			gesture.estimation(TouchBlobList);//for cross close window
			POINT PreviousPoint;//initilize a point for previousPoint object
			POINT Point;// initilize a point for current point object
			if(SwitchCase==2){//if previous action is mouse movement action
				MouseGestureSwitch(TouchBlobList);
				break;
			}else if(SingleClick==true && MouseMoveToLeftClick!=0){
				MouseGestureSwitch(TouchBlobList);
				MouseMoveToLeftClick=0;
				keyboard.ClearVirtualKey();
				break;
				//if none of these matches, evaluate for next use
			}else if(PreviousTouchBlobList->total==1 && TouchBlobList->total==1){
				float* p=(float*)cvGetSeqElem(PreviousTouchBlobList,0);
				PreviousPoint.x=cvRound(p[0]);
				PreviousPoint.y=cvRound(p[1]);
			    float* q=(float*)cvGetSeqElem(TouchBlobList,0);
				Point.x=cvRound(q[0]);
				Point.y=cvRound(q[1]);
			}
			//
			if(SwitchCase==0 || SwitchCase==1){
				if(abs(Point.x-PreviousPoint.x)<10 && abs(Point.y-PreviousPoint.y)<10){
					SwitchCase=1;
					keyboard.OutputKey(TouchBlobList);
					break;
				}else if((abs(Point.x-PreviousPoint.x)>10 || abs(Point.y-PreviousPoint.y)>10)){
					SwitchCase=2;
					SingleClick=true;
					keyboard.ClearVirtualKey();
					MouseGestureSwitch(TouchBlobList);
					break;
				}
			}
			break;
		case 2:
			if(SwitchCase==3){
	    		keyboard.OutputKey(TouchBlobList);
				break;
			}else if (SwitchCase==4){
				MouseGestureSwitch(TouchBlobList);
				break;
			}
			//in case previous action is not zero finger or one finger
			if(SwitchCase==0 || SwitchCase==1){
				if(PreviousTouchBlobList->total==1 && TouchBlobList->total==2){
					keyboard.OutputKey(TouchBlobList);
					SwitchCase=3;
					break;
				}else{
					MouseGestureSwitch(TouchBlobList);
					SwitchCase=4;
					break;
				}
			}
			break;
			//three fingers action
		case 3:
			if(SwitchCase==6){
				keyboard.OutputKey(TouchBlobList);
				break;
			}else if (SwitchCase==5){
				MouseGestureSwitch(TouchBlobList);
				break;
			}
			//
			if(SwitchCase==0 || SwitchCase==3 || SwitchCase==4){
				if(PreviousTouchBlobList->total==2&& TouchBlobList->total==3){
					keyboard.OutputKey(TouchBlobList);
					SwitchCase=6;
				}else{
					MouseGestureSwitch(TouchBlobList);
					SwitchCase=5;
				}
			}
			break;
		default://more then three fingers are all mouse actions
			MouseGestureSwitch(TouchBlobList);// only mouse & gestue has four fingers action
		    SwitchCounter=0;//clean for next use
			SwitchCase=0;//clean for next use
			break;
	}
	PreviousTouchBlobList=cvCloneSeq(TouchBlobList,NULL);//copy current TouchBlobList to previous one
}