Exemplo n.º 1
0
CvSeq* findSquares4(IplImage *img, CvMemStorage* storage)
{
	CvSeq* contours;
	int i, c, l, N = 11;
	int thresh = 50;
	CvSize sz = cvSize(img->width & -2, img->height & -2);

	IplImage* timg = cvCloneImage(img);
	IplImage* gray = cvCreateImage(sz, 8, 1);
	IplImage* pyr = cvCreateImage(cvSize(sz.width / 2, sz.height / 2), 8, 3);
	IplImage* tgray;

	CvSeq* result;

	// 创建一个空序列用处储存轮廓角点
	CvSeq* squares = cvCreateSeq(0, sizeof(CvSeq), sizeof(CvPoint), storage);

	cvSetImageROI(timg, cvRect(0, 0, sz.width, sz.height));

	// 过滤噪音
	//cvPyrDown(timg, pyr, 7);
	tgray = cvCreateImage(sz, 8, 1);
	//cvPyrUp(pyr, timg, 7);

        // 红绿蓝3色分别提取
	for (int c = 0; c < 3; c++) {
		cvSetImageCOI(timg, c + 1);
		cvCopy(timg, tgray, 0);

                // 尝试各种阈值提取
		for (int l = 0; l < N; l++) {
			if (l == 0) {
				cvCanny(tgray, gray, 0, thresh, 5);
				cvDilate(gray, gray, 0, 1);
			} else {
				cvThreshold(tgray, gray, (l + 1) * 255 / N, 255,
				                CV_THRESH_BINARY);
			}

                        // 找到轮廓并存储在队列中
			cvFindContours(gray, storage, &contours,
			                sizeof(CvContour), CV_RETR_LIST,
			                CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0));


                        // 遍历每一个轮廓
			while (contours) {
                                // 使用指定的精度逼近多边形曲线
				result = cvApproxPoly(contours,
				                sizeof(CvContour), storage,
				                CV_POLY_APPROX_DP,
				                cvContourPerimeter(contours) * 0.02, 0);
				if (result->total == 4
				                && fabs(
				                                cvContourArea(
				                                                result,
				                                                CV_WHOLE_SEQ))
				                                > 500
				                && fabs(
				                                cvContourArea(
				                                                result,
				                                                CV_WHOLE_SEQ))
				                                < 100000
				                && cvCheckContourConvexity(
				                                result))
				{

					double s = 0, t;
					for (int i = 0; i < 5; i++) {
						if (i >= 2) {
							t =
							                fabs(
							                                angle(
							                                                (CvPoint*) cvGetSeqElem(
							                                                                result,
							                                                                i),
							                                                (CvPoint *) cvGetSeqElem(
							                                                                result,
							                                                                i
							                                                                                - 2),
							                                                (CvPoint *) cvGetSeqElem(
							                                                                result,
							                                                                i
							                                                                                - 1)));
							s = s > t ? s : t;
						}
					}

                                        // 如果余弦值足够小, 可以认定角度为90度, 是直角
					if (s < 0.08) {
						for (int i = 0; i < 4; i++) {
							cvSeqPush(squares,
							                (CvPoint *) cvGetSeqElem(
							                                result,
							                                i));
						}
					}
				}
				contours = contours->h_next;
			}

		}
	}

	cvReleaseImage(&gray);
	cvReleaseImage (&pyr);
	cvReleaseImage(&tgray);
	cvReleaseImage(&timg);

	return squares;
}
Exemplo n.º 2
0
// returns sequence of squares detected on the image.
// the sequence is stored in the specified memory storage
CvSeq* findSquares4( IplImage* img, CvMemStorage* storage )
{
    CvSeq* contours;
    int i, c, l, N = 11;
    CvSize sz = cvSize( img->width & -2, img->height & -2 );
    IplImage* timg = cvCloneImage( img ); // make a copy of input image
    IplImage* gray = cvCreateImage( sz, 8, 1 );
    IplImage* pyr = cvCreateImage( cvSize(sz.width/2, sz.height/2), 8, 3 );
    IplImage* tgray;
    CvSeq* result;
    double s, t;
    // create empty sequence that will contain points -
    // 4 points per square (the square's vertices)
    CvSeq* squares = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvPoint), storage );

    // select the maximum ROI in the image
    // with the width and height divisible by 2
    cvSetImageROI( timg, cvRect( 0, 0, sz.width, sz.height ));

    // down-scale and upscale the image to filter out the noise
    cvPyrDown( timg, pyr, 7 );
    cvPyrUp( pyr, timg, 7 );
    tgray = cvCreateImage( sz, 8, 1 );

    // find squares in every color plane of the image
    for( c = 0; c < 3; c++ )
    {
        // extract the c-th color plane
        cvSetImageCOI( timg, c+1 );
        cvCopy( timg, tgray, 0 );

        // try several threshold levels
        for( l = 0; l < N; l++ )
        {
            // hack: use Canny instead of zero threshold level.
            // Canny helps to catch squares with gradient shading
            if( l == 0 )
            {
                // apply Canny. Take the upper threshold from slider
                // and set the lower to 0 (which forces edges merging)
                cvCanny( tgray, gray, 0, thresh, 5 );
                // dilate canny output to remove potential
                // holes between edge segments
                cvDilate( gray, gray, 0, 1 );
            }
            else
            {
                // apply threshold if l!=0:
                //     tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0
                cvThreshold( tgray, gray, (l+1)*255/N, 255, CV_THRESH_BINARY );
            }

            // find contours and store them all as a list
            cvFindContours( gray, storage, &contours, sizeof(CvContour),
                CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );

            // test each contour
            while( contours )
            {
                // approximate contour with accuracy proportional
                // to the contour perimeter
                result = cvApproxPoly( contours, sizeof(CvContour), storage,
                    CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0 );
                // square contours should have 4 vertices after approximation
                // relatively large area (to filter out noisy contours)
                // and be convex.
                // Note: absolute value of an area is used because
                // area may be positive or negative - in accordance with the
                // contour orientation
                if( result->total == 4 &&
                    cvContourArea(result,CV_WHOLE_SEQ,0) > 500 &&
                    cvCheckContourConvexity(result) )
                {
                    s = 0;

                    for( i = 0; i < 5; i++ )
                    {
                        // find minimum angle between joint
                        // edges (maximum of cosine)
                        if( i >= 2 )
                        {
                            t = fabs(angle(
                            (CvPoint*)cvGetSeqElem( result, i ),
                            (CvPoint*)cvGetSeqElem( result, i-2 ),
                            (CvPoint*)cvGetSeqElem( result, i-1 )));
                            s = s > t ? s : t;
                        }
                    }

                    // if cosines of all angles are small
                    // (all angles are ~90 degree) then write quandrange
                    // vertices to resultant sequence
                    if( s < 0.3 )
                        for( i = 0; i < 4; i++ )
                            cvSeqPush( squares,
                                (CvPoint*)cvGetSeqElem( result, i ));
                }

                // take the next contour
                contours = contours->h_next;
            }
        }
    }

    // release all the temporary images
    cvReleaseImage( &gray );
    cvReleaseImage( &pyr );
    cvReleaseImage( &tgray );
    cvReleaseImage( &timg );

    return squares;
}
CvSeq* CSquareDetection::FindSquares( IplImage* tgray )
{
	CvSeq* contours;
	int i, l, N = 11;
	double imgArea = tgray->width*tgray->height;
	CvSize sz = cvSize( tgray->width & -2, tgray->height & -2 );
	IplImage* gray = cvCreateImage( sz, 8, 1 ); 
	IplImage* pyr = cvCreateImage( cvSize(sz.width/2, sz.height/2), 8, 1 );
	CvSeq* result;
	// create empty sequence that will contain points -
	// 4 points per square (the square's vertices)
	CvSeq* squares = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvPoint), storage );

	// select the maximum ROI in the image
	// with the width and height divisible by 2
	cvSetImageROI( tgray, cvRect( 0, 0, sz.width, sz.height ));

	// down-scale and upscale the image to filter out the noise
	//cvPyrDown( tgray, pyr, 7 );
	//cvPyrUp( pyr, tgray, 7 );

	// try several threshold levels
	cvCanny( tgray, gray, 0, _CannyThresh, 5 );
	cvDilate( gray, gray, 0, 1 );

	for( l = 1; l < N-4; l++ )
	{
		cvThreshold( tgray, gray, (l+1)*255/N, 255, CV_THRESH_BINARY );
		// find contours and store them all as a list
		cvFindContours( gray, storage, &contours, sizeof(CvContour),
			CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );

		// test each contour
		while( contours )
		{
			// approximate contour with accuracy proportional
			// to the contour perimeter
			result = cvApproxPoly( contours, sizeof(CvContour), storage,
				CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0 );
			// square contours should have 4 vertices after approximation
			// relatively large area (to filter out noisy contours)
			// and be convex.
			// Note: absolute value of an area is used because
			// area may be positive or negative - in accordance with the
			// contour orientation
			double area = fabs(cvContourArea(result,CV_WHOLE_SEQ));
			if( result->total == 4 &&
				area < _maxPropotionArea*imgArea &&
				area > _minPropotionArea*imgArea &&
				cvCheckContourConvexity(result) )
			{
				// Kiem tra va sap xep lai vi tri dinh
				if (Check4Vertexes(result, _CosineThresh, _EdgeThresh))
				{
					// Dau vao mang ket qua
					for( i = 0; i < 4; i++ )
						cvSeqPush( squares,(CvPoint*)cvGetSeqElem( result, i ));
				}
			}

			// take the next contour
			contours = contours->h_next;
		}
	}
	// Loc lai
	int delta_thres = 30;
	int* flags = new int[squares->total/4];
	for (int i = 0; i < squares->total/4; i++)
		flags[i] = 0;

	CvSeq* sqrSeq = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvPoint), storage );
	CvPoint* V[4], *Vp[4];

	for (int i = 0; i < squares->total; i+=4)
	{
		if (!flags[i/4])
		{
			V[0] = (CvPoint*)cvGetSeqElem( squares, i );
			V[1] = (CvPoint*)cvGetSeqElem( squares, i+1 );
			V[2] = (CvPoint*)cvGetSeqElem( squares, i+2 );
			V[3] = (CvPoint*)cvGetSeqElem( squares, i+3 );

			for (int j = i+4; j < squares->total; j+= 4)
			{
				if (!flags[j/4])
				{
					Vp[0] = (CvPoint*)cvGetSeqElem( squares, j );
					Vp[1] = (CvPoint*)cvGetSeqElem( squares, j+1 );
					Vp[2] = (CvPoint*)cvGetSeqElem( squares, j+2 );
					Vp[3] = (CvPoint*)cvGetSeqElem( squares, j+3 );
					// xac dinh trung diem
					CvPoint M;
					M.x = (Vp[0]->x+Vp[2]->x)/2;
					M.y = (Vp[0]->y+Vp[2]->y)/2;

					if (MathHelper.ktNamTrong(V, 4, &M))
					{
						int d1 = max(MathHelper.sqrDistance(V[0], V[1]), MathHelper.sqrDistance(V[1], V[2]));
						int d2 = max(MathHelper.sqrDistance(Vp[0], Vp[1]), MathHelper.sqrDistance(Vp[1], Vp[2]));
						
						if ( d1 > d2)
						{
							V[0]->x = Vp[0]->x; V[0]->y = Vp[0]->y;
							V[1]->x = Vp[1]->x; V[1]->y = Vp[1]->y;
							V[2]->x = Vp[2]->x; V[2]->y = Vp[2]->y;
							V[3]->x = Vp[3]->x; V[3]->y = Vp[3]->y;
						}
						flags[j/4] = 1;
					}
					
				}
			}
		}
	}

	for (int i = 0; i < squares->total; i+=4)
	{
		if (!flags[i/4])
		{
			V[0] = (CvPoint*)cvGetSeqElem( squares, i );
			V[1] = (CvPoint*)cvGetSeqElem( squares, i+1 );
			V[2] = (CvPoint*)cvGetSeqElem( squares, i+2 );
			V[3] = (CvPoint*)cvGetSeqElem( squares, i+3 );

			// Kiem tra co nguoc chieu kim dong ho ko
			// Neu khong nguoc chieu kim dong ho thi hoan doi
			// Chinh lai huong cua la bai
			Line* l = MathHelper.ptDuongThang(V[0], V[1]);
			if (MathHelper.thePointLenLine(l, V[3]) > 0)
			{
				int temp = V[1]->x; V[1]->x = V[3]->x; V[3]->x  = temp;
					temp = V[1]->y; V[1]->y = V[3]->y; V[3]->y  = temp;
			}
			//MathHelper.SapDongHo(V);
			cvSeqPush(sqrSeq, V[0]);
			cvSeqPush(sqrSeq, V[1]);
			cvSeqPush(sqrSeq, V[2]);
			cvSeqPush(sqrSeq, V[3]);
		}
	}

	//cvClearSeq(squares);
	// release all the temporary images
	cvReleaseImage( &gray );
	cvReleaseImage( &pyr );
	//cvReleaseImage( &tgray );

	cvClearMemStorage(storage);
	return sqrSeq;
}
Exemplo n.º 4
0
CvSeq* EyeTracker::findSquares()
{
	CvSeq* contours;
	int i, N = 5;
	CvSize sz = cvSize( sceneImagePts->width, sceneImagePts->height);
	IplImage* gray = cvCreateImage( sz, 8, 1 );
	IplImage* tgray = cvCreateImage( sz, 8, 1 );
	CvSeq* result;
	double s, t;

	CvSeq* squares = cvCreateSeq(0, sizeof(CvSeq), sizeof(CvPoint), squareStorage);

	cvCvtColor(sceneImagePts, tgray, CV_RGB2GRAY);

	// apply threshold if l!=0:
	//     tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0
	cvThreshold(tgray, gray, squareThreshold, 255, CV_THRESH_BINARY );

	// find contours and store them all as a list
	cvFindContours(gray, squareStorage, &contours, sizeof(CvContour),
				   CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

	// test each contour
	while(contours)
	{
		// approximate contour with accuracy proportional
		// to the contour perimeter
		result = cvApproxPoly(contours, 
							  sizeof(CvContour), 
							  squareStorage,
							  CV_POLY_APPROX_DP, 
							  cvContourPerimeter(contours) * 0.02, 
							  0);

		// square contours should have 4 vertices after approximation
		// relatively large area (to filter out noisy contours)
		// and be convex.
		// Note: absolute value of an area is used because
		// area may be positive or negative - in accordance with the
		// contour orientation
		if(result->total == 4 &&
		   fabs(cvContourArea(result, CV_WHOLE_SEQ)) > 1000 &&
		   cvCheckContourConvexity(result))
		{
			s = 0;

			for(i = 0; i < 5; ++i)
			{
				// find minimum angle between joint
				// edges (maximum of cosine)
				if(i >= 2)
				{
					t = fabs(angle((CvPoint*)cvGetSeqElem(result, i),
								   (CvPoint*)cvGetSeqElem(result, i-2),
								   (CvPoint*)cvGetSeqElem(result, i-1)));
					s = s > t ? s : t;
				}
			}

			// if cosines of all angles are small
			// (all angles are ~90 degree) then write quandrange
			// vertices to resultant sequence
			if(s < 0.2)
			{
				CvSeqReader reader;

				// initialize reader of the sequence
				cvStartReadSeq(result, &reader, 0);
				CvPoint pt[4];

				CV_READ_SEQ_ELEM( pt[0], reader );
				CV_READ_SEQ_ELEM( pt[1], reader );
				CV_READ_SEQ_ELEM( pt[2], reader );
				CV_READ_SEQ_ELEM( pt[3], reader );

				for(int i = 1; i < 4; ++i)
				{
					for(int j = 0; j < 4 - i; ++j)
					{
						if(pt[j].x > pt[j+1].x)
						{
							CvPoint temp = pt[j+1];
							pt[j+1] = pt[j];
							pt[j] = temp;
						}
					}
				}

				if(pt[0].y > pt[1].y)
				{
					CvPoint temp = pt[1];
					pt[1] = pt[0];
					pt[0] = temp;
				}

				if(pt[2].y > pt[3].y)
				{
					CvPoint temp = pt[3];
					pt[3] = pt[2];
					pt[2] = temp;
				}

				if(abs(pt[0].y - pt[1].y) > 240)
				{
					sceneCorner[0] = pt[0];
					sceneCorner[1] = pt[1];
					sceneCorner[2] = pt[2];
					sceneCorner[3] = pt[3];

					for(int i = 0; i < 4; ++i)
						cvSeqPush(squares, (CvPoint*) cvGetSeqElem(result, i));

					break;
				}
			}
		}

		// take the next contour
		contours = contours->h_next;
	}

	// release all the temporary images
	cvReleaseImage(&gray);
	cvReleaseImage(&tgray);
	
	return squares;
}
Exemplo n.º 5
0
CvSeq * find_quad( CvSeq * src_contour, CvMemStorage *storage, int min_size)
{
    // stolen from icvGenerateQuads
    CvMemStorage * temp_storage = cvCreateChildMemStorage( storage );
    
    int flags = CV_CALIB_CB_FILTER_QUADS;
    CvSeq *dst_contour = 0;
    
    const int min_approx_level = 2, max_approx_level = MAX_CONTOUR_APPROX;
    int approx_level;
    for( approx_level = min_approx_level; approx_level <= max_approx_level; approx_level++ )
    {
        dst_contour = cvApproxPoly( src_contour, sizeof(CvContour), temp_storage,
                                    CV_POLY_APPROX_DP, (float)approx_level );
        // we call this again on its own output, because sometimes
        // cvApproxPoly() does not simplify as much as it should.
        dst_contour = cvApproxPoly( dst_contour, sizeof(CvContour), temp_storage,
                                    CV_POLY_APPROX_DP, (float)approx_level );

        if( dst_contour->total == 4 )
            break;
    }

    // reject non-quadrangles
    if( dst_contour->total == 4 && cvCheckContourConvexity(dst_contour) )
    {
        CvPoint pt[4];
        double d1, d2, p = cvContourPerimeter(dst_contour);
        double area = fabs(cvContourArea(dst_contour, CV_WHOLE_SEQ));
        double dx, dy;

        for( int i = 0; i < 4; i++ )
            pt[i] = *(CvPoint*)cvGetSeqElem(dst_contour, i);

        dx = pt[0].x - pt[2].x;
        dy = pt[0].y - pt[2].y;
        d1 = sqrt(dx*dx + dy*dy);

        dx = pt[1].x - pt[3].x;
        dy = pt[1].y - pt[3].y;
        d2 = sqrt(dx*dx + dy*dy);

        // philipg.  Only accept those quadrangles which are more square
        // than rectangular and which are big enough
        double d3, d4;
        dx = pt[0].x - pt[1].x;
        dy = pt[0].y - pt[1].y;
        d3 = sqrt(dx*dx + dy*dy);
        dx = pt[1].x - pt[2].x;
        dy = pt[1].y - pt[2].y;
        d4 = sqrt(dx*dx + dy*dy);
        if( !(flags & CV_CALIB_CB_FILTER_QUADS) ||
            (d3*1.1 > d4 && d4*1.1 > d3 && d3*d4 < area*1.5 && area > min_size &&
            d1 >= 0.15 * p && d2 >= 0.15 * p) )
        {
            // CvContourEx* parent = (CvContourEx*)(src_contour->v_prev);
            // parent->counter++;
            // if( !board || board->counter < parent->counter )
            //     board = parent;
            // dst_contour->v_prev = (CvSeq*)parent;
            //for( i = 0; i < 4; i++ ) cvLine( debug_img, pt[i], pt[(i+1)&3], cvScalar(200,255,255), 1, CV_AA, 0 );
            // cvSeqPush( root, &dst_contour );
            return dst_contour;
        }
    }
    
    return NULL;
}
Exemplo n.º 6
0
int RectDetector::FindShape(const IplImage* img,std::vector<RectShape>& shapes)
{
	if( !img )
	{
        return -1;
	}

	int thresh = 50;
	CvMemStorage* storage = cvCreateMemStorage(0);
	CvSeq* contours;
	int i, c, l, N = 11;
	CvSize sz = cvSize( img->width & -2, img->height & -2 ); 
 
	IplImage* timg = cvCloneImage( img );
	IplImage* gray = cvCreateImage( sz, 8, 1 );
	IplImage* pyr = cvCreateImage( cvSize(sz.width/2, sz.height/2), 8, 3 );
	IplImage* tgray;
	CvSeq* result;
	double s, t;
	// 创建一个空序列用于存储轮廓角点
	//CvSeq* squares = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvPoint), storage );

	cvSetImageROI( timg, cvRect( 0, 0, sz.width, sz.height ));
	// 过滤噪音
	//cvPyrDown( timg, pyr, 5 );
	//cvPyrUp( pyr, timg, 5 );
	tgray = cvCreateImage( sz, 8, 1 );
	//cvShowImage("test",timg);
 

	// 提取 the c-th color plane
	cvSetImageCOI( timg, 0 );
	cvCopy( timg, tgray, 0 );

	// 尝试各种阈值提取得到的(N=11)
	for( l = 0; l < N; l++ )
	{
		// apply Canny. Take the upper threshold from slider
		// Canny helps to catch squares with gradient shading  
		if( l == 0 )
		{
			cvCanny( tgray, gray, 0, thresh, 5 );
			//使用任意结构元素膨胀图像
			cvDilate( gray, gray, 0, 2 );
			//cvShowImage("test",gray);
		}
		else
		{
			// apply threshold if l!=0:
			cvThreshold( tgray, gray, (l+1)*255/N, 255, CV_THRESH_BINARY );
 
		}

		// 找到所有轮廓并且存储在序列中
		cvFindContours( gray, storage, &contours, sizeof(CvContour),
		CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );

		// 遍历找到的每个轮廓contours
		while( contours )
		{
			//用指定精度逼近多边形曲线
			result = cvApproxPoly( contours, sizeof(CvContour), storage,
			CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0 );
                  

			if( result->total == 4 &&
				fabs(cvContourArea(result,CV_WHOLE_SEQ)) > 500 &&
				fabs(cvContourArea(result,CV_WHOLE_SEQ)) < 100000 &&
				cvCheckContourConvexity(result) )
			{
				s = 0;

				for( i = 0; i < 5; i++ )
				{
					// find minimum angle between joint edges (maximum of cosine)
					if( i >= 2 )
					{
						t = fabs(this->CalcAngle((CvPoint*)cvGetSeqElem( result, i ),
										(CvPoint*)cvGetSeqElem( result, i-2 ),
										(CvPoint*)cvGetSeqElem( result, i-1 )));
						s = s > t ? s : t;
					}
				}

				 // if 余弦值 足够小,可以认定角度为90度直角
				 //cos0.1=83度,能较好的趋近直角
				if( s < 0.1 ) 
				{
					RectShape RectShape(*(CvPoint*)cvGetSeqElem( result, 0 ),*(CvPoint*)cvGetSeqElem( result, 1 ),*(CvPoint*)cvGetSeqElem( result, 2 ),*(CvPoint*)cvGetSeqElem( result, 3 ));
					
					bool isExist = false;
					//去重
					for(int j = 0 ; j < shapes.size(); ++j)
					{
						if(RectShape == shapes[j] )
						{
							isExist = true;
							continue;
						}
						//remove the rectangle which contains others
						if(RectShape.isNear(shapes[j]))
						{
							if(RectShape.ctPoint.x > shapes[j].ctPoint.x || RectShape.ctPoint.y > shapes[j].ctPoint.y)
							{
								isExist = true;
								continue;
							}
							else
							{
								shapes[j] = RectShape;
							}
						}
	 

					}

					if(!isExist)
					{
						shapes.push_back(RectShape);
					}
					
				}
			}

			// 继续查找下一个轮廓
			contours = contours->h_next;
		

		}
	}

	cvReleaseImage( &gray );
	cvReleaseImage( &pyr );
	cvReleaseImage( &tgray );
	cvReleaseImage( &timg );
	cvClearMemStorage( storage );
	


	return shapes.size();
}
Exemplo n.º 7
0
int main(int argc, char* argv[]) {
    IplImage* img_8uc1 = NULL;


#ifdef IMAGE
    if( argc != 2 || !(img_8uc1 = cvLoadImage( argv[1], CV_LOAD_IMAGE_GRAYSCALE )) ){
        printf("%s image\n",argv[0]);
        return -1;
    }
#else
    CvCapture* capture = cvCreateFileCapture( argv[1] );
    IplImage* frame;
    if( argc != 2 || !(frame = cvQueryFrame( capture )) ){
        printf("%s image\n",argv[0]);
        return -1;
    }
#endif
  
    const char* name = "Edge Detection Window";
    cvNamedWindow( name, 0 );
    cvCreateTrackbar( "Contour perimeter", name, &high_switch_value, 100, switch_callback_h );
    cvCreateTrackbar( "Min area", name, &minimum_area, 100000, NULL);
    cvCreateTrackbar( "Max area", name, &maximum_area, 100000, NULL);

    while(1) {
#ifndef IMAGE
        frame = cvQueryFrame( capture );
        img_8uc1=cvCreateImage( cvGetSize(frame), 8, 1 );
        cvCvtColor(frame,img_8uc1,CV_BGR2GRAY);
#endif
        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* first_contour = NULL;
        cvFindContours(
           img_edge,
           storage,
           &first_contour,
           sizeof(CvContour),
           CV_RETR_CCOMP
       );

       int n=0;
       cvCvtColor( img_8uc1, img_8uc3, CV_GRAY2BGR );
       CvSeq* contours=first_contour;
       while (contours) {
           double area=fabs(cvContourArea(contours, CV_WHOLE_SEQ));
           if(area < minimum_area || area > maximum_area) {
               contours = contours->h_next;
               continue;
           }
           CvSeq *result;
           double s,t;

           result = cvApproxPoly(contours, sizeof(CvContour), storage,
               CV_POLY_APPROX_DP, cvContourPerimeter(contours) * perimeter_constant, 0);

           if (result->total == 4 && cvCheckContourConvexity(result)) {
               s = 0;
               int i;
               for (i = 0; i < 5; i++) {
                   // find minimum angle between joint
                   // edges (maximum of cosine)
                   if (i >= 2) {
                       t = fabs(angle(
                           (CvPoint *) cvGetSeqElem(result, i),
                           (CvPoint *) cvGetSeqElem(result, i - 2),
                           (CvPoint *) cvGetSeqElem(result, i - 1)));
                       s = s > t ? s : t;
                   }
                }
                cvDrawContours(img_8uc3, contours, RED, BLUE, 0, 2, 8);
                // if cosines of all angles are small
                // (all angles are ~90 degree) then write quandrange
                // vertices to resultant sequence 
                // printf("s=%f\n",s);
	        if (s > 0.3) {
	  	/*for (i = 0; i < 4; i++) {
		    cvSeqPush(squares,(CvPoint *) cvGetSeqElem(result, i));
	        }*/
                }
            }
            contours = contours->h_next;
            n++;
        }
        cvShowImage( name, img_8uc3 );
        cvWaitKey(200);
        cvReleaseImage( &img_8uc3 );
        cvReleaseImage( &img_edge );
#ifndef IMAGE
        cvReleaseImage( &img_8uc1 );
#endif
    }
    cvDestroyWindow( argv[0] );
    return 0;
}
Exemplo n.º 8
0
void FrameProcessor::DetectAndDrawQuads(IplImage* img, vector <Square>& cubes, CvCapture* capture)
{
	float angle = 0.0f;
	CvSeq* contours;
	CvSeq* result;
	CvMemStorage *storage = cvCreateMemStorage(0);

	//IplImage* ret = cvCreateImage(cvGetSize(img), 8, 3);
	IplImage* temp = cvCreateImage(cvGetSize(img), 8, 1);

	cvCvtColor(img, temp, CV_BGR2GRAY);

	IplImage* Img = cvCreateImage (cvGetSize (img), 8, 1);
	cvThreshold(temp, Img, 0, 255, CV_THRESH_BINARY_INV | CV_THRESH_OTSU);

	cvFindContours(Img, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
	CvSeq* contours1 = contours;
	while(contours)
    {
		result = cvApproxPoly (contours, sizeof (CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter (contours) * 0.02, 0);

		if((result->total==4)  && (fabs(cvContourArea(result, CV_WHOLE_SEQ)) > 30) && cvCheckContourConvexity (result))
        {
	  int countTriang = 0;   
	  CvSeq* contours2 = contours1;
	  
	  while(contours2){
	    
	    CvSeq* result2 = cvApproxPoly(contours2, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contours2)*0.02, 0);
	    if((result2->total==3) && (fabs(cvContourArea(result2, CV_WHOLE_SEQ)) > 50) && cvCheckContourConvexity(result2)) 
	      {
		CvPoint *pt[3];
		for(int i=0;i<3;i++)
		  pt[i] = (CvPoint*)cvGetSeqElem(result2, i);
		
		CvPoint ptCent[1];
		ptCent[0].x = (pt[0]->x + pt[1]->x + pt[2]->x)/3;
		ptCent[0].y = (pt[0]->y + pt[1]->y + pt[2]->y)/3;
		//printf("(%d, %d) (%d,%d) (%d,%d)\n", pt[0]->x, pt[0]->y, pt[1]->x, pt[1]->y, pt[2]->x, pt[2]->y); 
		//cvCircle(ret, ptCent[0], 5, cvScalar(255));
		
		CvPoint2D32f triang;
		triang.x = ptCent[0].x;
		triang.y = ptCent[0].y;
		
		if(cvPointPolygonTest(result, triang, 0)  > 0){
		  countTriang++;
		  //cvLine(ret, *pt[0], *pt[1], cvScalar(30, 50, 50));
		  //cvLine(ret, *pt[1], *pt[2], cvScalar(30, 50, 50));
		  //cvLine(ret, *pt[2], *pt[0], cvScalar(30, 50, 50));
		  angle = GetAngle(pt);
		}
	      }
	    
	    contours2 = contours2->h_next;
	  }
	  
	  if(countTriang == 1){
	    CvPoint *pt[4];
	    for(int i=0;i<4;i++)
	      pt[i] = (CvPoint*)cvGetSeqElem(result, i);
	    
	    //cvLine(ret, *pt[0], *pt[1], cvScalar(255));
	    //cvLine(ret, *pt[1], *pt[2], cvScalar(255));
	    //cvLine(ret, *pt[2], *pt[3], cvScalar(255));
	    //cvLine(ret, *pt[3], *pt[0], cvScalar(255));
	    
	    CvSeq* contours3 = contours1;
	    int countSquare = 0;
	    while(contours3){
	      CvSeq* result3 = cvApproxPoly(contours3, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contours3)*0.02, 0);
	      if((result3->total==4) && (fabs(cvContourArea(result3, CV_WHOLE_SEQ)) > 50) && cvCheckContourConvexity(result3)) 
		{
		  CvPoint *pt[4];
		  for(int i=0;i<4;i++)
		    pt[i] = (CvPoint*)cvGetSeqElem(result3, i);
		  
		  CvPoint ptCent[1];
		  ptCent[0].x = (pt[0]->x + pt[1]->x + pt[2]->x + pt[3]->x)/4;
		  ptCent[0].y = (pt[0]->y + pt[1]->y + pt[2]->y + pt[3]->y)/4;
		  
		  //cvCircle(ret, ptCent[0], 5, cvScalar(255));
		  
		  CvPoint2D32f square;
		  square.x = ptCent[0].x;
		  square.y = ptCent[0].y;
		  
		  //cout << cvPointPolygonTest(result, triang, 0);
		  if(cvPointPolygonTest(result, square, 0)  > 0){
		    countSquare++;
		    //cvLine(ret, *pt[0], *pt[1], cvScalar(90, 50, 50));
		    //cvLine(ret, *pt[1], *pt[2], cvScalar(90, 50, 50));
		    //cvLine(ret, *pt[2], *pt[3], cvScalar(90, 50, 50));
		    //cvLine(ret, *pt[3], *pt[0], cvScalar(90, 50, 50));
		    
		  }
		}
	      contours3 = contours3->h_next;
	    }
	    countSquare--;
	    
	    CvPoint *pt1[4];
	    for(int i=0;i<4;i++)
	      pt1[i] = (CvPoint*)cvGetSeqElem(result, i);
	    
	    CvPoint ptCent[1];
	    ptCent[0].x = (pt1[0]->x + pt1[1]->x + pt1[2]->x + pt1[3]->x)/4;
	    ptCent[0].y = (pt1[0]->y + pt1[1]->y + pt1[2]->y + pt1[3]->y)/4;
	    //printf("%d %d\n", ptCent[0].x, ptCent[0].y);
	    //cvCircle(ret, ptCent[0], 5, cvScalar(255));
	    
	    CvPoint pC[1];
	    pC[0].x = ptCent[0].x;
	    pC[0].y = ptCent[0].y;
	    
	    int width = (int) cvGetCaptureProperty (capture, CV_CAP_PROP_FRAME_WIDTH);
	    int height = (int) cvGetCaptureProperty (capture, CV_CAP_PROP_FRAME_HEIGHT);

	    pC[0].x = width - ptCent[0].x;

	    pC[0].x = (pC[0].x * 100) / width;
	    pC[0].y = (ptCent[0].y * 100) / height;

	    Square test3 (countSquare, pC [0], abs(pt1[0]->x - pC[0].x) * 1.5, abs(pt1[0]->x - pC[0].x) * 1.5, angle);
	    cubes.push_back(test3);
	  }
        }
      
      contours = contours->h_next;
    }

	cvReleaseImage(&temp);
	//cvReleaseImage(&ret);
	cvReleaseImage(&Img);
	cvReleaseMemStorage(&storage);
}