コード例 #1
0
void MarkerDetector::findCandidates
(
    const ContoursVector& contours, 
    std::vector<Marker>& detectedMarkers
) 
{
    std::vector<cv::Point>  approxCurve;
    std::vector<Marker>     possibleMarkers;

    // For each contour, analyze if it is a parallelepiped likely to be the marker
    for (size_t i=0; i<contours.size(); i++)
    {
        // Approximate to a polygon
        double eps = contours[i].size() * 0.05;
        cv::approxPolyDP(contours[i], approxCurve, eps, true);

        // We interested only in polygons that contains only four points
        if (approxCurve.size() != 4)
            continue;

        // And they have to be convex
        if (!cv::isContourConvex(approxCurve))
            continue;

        // Ensure that the distance between consecutive points is large enough
        float minDist = std::numeric_limits<float>::max();

        for (int i = 0; i < 4; i++)
        {
            cv::Point side = approxCurve[i] - approxCurve[(i+1)%4];            
            float squaredSideLength = side.dot(side);
            minDist = std::min(minDist, squaredSideLength);
        }

        // Check that distance is not very small
        if (minDist < m_minContourLengthAllowed)
            continue;

        // All tests are passed. Save marker candidate:
        Marker m;

        for (int i = 0; i<4; i++)
            m.points.push_back( cv::Point2f(approxCurve[i].x,approxCurve[i].y) );

        // Sort the points in anti-clockwise order
        // Trace a line between the first and second point.
        // If the third point is at the right side, then the points are anti-clockwise
        cv::Point v1 = m.points[1] - m.points[0];
        cv::Point v2 = m.points[2] - m.points[0];

        double o = (v1.x * v2.y) - (v1.y * v2.x);

        if (o < 0.0)		 //if the third point is in the left side, then sort in anti-clockwise order
            std::swap(m.points[1], m.points[3]);

        possibleMarkers.push_back(m);
    }


    // Remove these elements which corners are too close to each other.  
    // First detect candidates for removal:
    std::vector< std::pair<int,int> > tooNearCandidates;
    for (size_t i=0;i<possibleMarkers.size();i++)
    { 
        const Marker& m1 = possibleMarkers[i];

        //calculate the average distance of each corner to the nearest corner of the other marker candidate
        for (size_t j=i+1;j<possibleMarkers.size();j++)
        {
            const Marker& m2 = possibleMarkers[j];

            float distSquared = 0;

            for (int c = 0; c < 4; c++)
            {
                cv::Point v = m1.points[c] - m2.points[c];
                distSquared += v.dot(v);
            }

            distSquared /= 4;

            if (distSquared < 100)
            {
                tooNearCandidates.push_back(std::pair<int,int>(i,j));
            }
        }				
    }

    // Mark for removal the element of the pair with smaller perimeter
    std::vector<bool> removalMask (possibleMarkers.size(), false);

    for (size_t i=0; i<tooNearCandidates.size(); i++)
    {
        float p1 = perimeter(possibleMarkers[tooNearCandidates[i].first ].points);
        float p2 = perimeter(possibleMarkers[tooNearCandidates[i].second].points);

        size_t removalIndex;
        if (p1 > p2)
            removalIndex = tooNearCandidates[i].second;
        else
            removalIndex = tooNearCandidates[i].first;

        removalMask[removalIndex] = true;
    }

    // Return candidates
    detectedMarkers.clear();
    for (size_t i=0;i<possibleMarkers.size();i++)
    {
        if (!removalMask[i])
            detectedMarkers.push_back(possibleMarkers[i]);
    }
}
コード例 #2
0
void dgConvexHull4d::InsertNewVertex(dgInt32 vertexIndex, dgListNode* const frontFace, dgList<dgListNode*>& deletedFaces, dgList<dgListNode*>& newFaces)
{
	dgAssert (Sanity());
	dgList<dgListNode*> stack(GetAllocator());
	
	dgInt32 mark = IncMark();
	stack.Append(frontFace);
	dgHullVector* const hullVertexArray = &m_points[0];
	const dgBigVector& p = hullVertexArray[vertexIndex];
	while (stack.GetCount()) {
		dgList<dgListNode*>::dgListNode* const stackNode = stack.GetLast();
		dgListNode* const node = stackNode->GetInfo();
		stack.Remove(stackNode);
		dgConvexHull4dTetraherum* const face = &node->GetInfo();
		if ((face->GetMark() != mark) && (face->Evalue(hullVertexArray, p) > dgFloat64(0.0f))) { 
#ifdef _DEBUG
			for (dgList<dgListNode*>::dgListNode* deleteNode = deletedFaces.GetFirst(); deleteNode; deleteNode = deleteNode->GetNext()) {
				dgAssert (deleteNode->GetInfo() != node);
			}
#endif
			deletedFaces.Append(node);

			face->SetMark(mark);
			for (dgInt32 i = 0; i < 4; i ++) {
				dgListNode* const twinNode = (dgListNode*)face->m_faces[i].m_twin;
				dgAssert (twinNode);
				dgConvexHull4dTetraherum* const twinFace = &twinNode->GetInfo();

				if (twinFace->GetMark() != mark) {
					stack.Append(twinNode);
				}
			}
		}
	}

    dgTree<dgListNode*, dgInt32> perimeter(GetAllocator());
	for (dgList<dgListNode*>::dgListNode* deleteNode = deletedFaces.GetFirst(); deleteNode; deleteNode = deleteNode->GetNext()) {
		dgListNode* const deleteTetraNode = deleteNode->GetInfo();
		dgConvexHull4dTetraherum* const deletedTetra = &deleteTetraNode->GetInfo();
		dgAssert (deletedTetra->GetMark() == mark);
		for (dgInt32 i = 0; i < 4; i ++) {
			dgListNode* const twinNode = deletedTetra->m_faces[i].m_twin;
			dgConvexHull4dTetraherum* const twinTetra = &twinNode->GetInfo();

			if (twinTetra->GetMark() != mark) {
				if (!perimeter.Find(twinTetra->m_uniqueID)) {
					perimeter.Insert(twinNode, twinTetra->m_uniqueID);
				}
			}
			deletedTetra->m_faces[i].m_twin = NULL;
		}
	}

	dgList<dgListNode*> coneList(GetAllocator());
	dgTree<dgListNode*, dgInt32>::Iterator iter (perimeter);
	for (iter.Begin(); iter; iter ++) {
		dgListNode* const perimeterNode = iter.GetNode()->GetInfo();
		dgConvexHull4dTetraherum* const perimeterTetra = &perimeterNode->GetInfo();
		for (dgInt32 i = 0; i < 4; i ++) {
			dgConvexHull4dTetraherum::dgTetrahedrumFace* const perimeterFace = &perimeterTetra->m_faces[i];

			if (perimeterFace->m_twin->GetInfo().GetMark() == mark) {
				dgListNode* const newNode = AddFace (vertexIndex, perimeterFace->m_index[0], perimeterFace->m_index[1], perimeterFace->m_index[2]);
				newFaces.Addtop(newNode);

				dgConvexHull4dTetraherum* const newTetra = &newNode->GetInfo();
				newTetra->m_faces[2].m_twin = perimeterNode;
				perimeterFace->m_twin = newNode;
				coneList.Append (newNode);
			}
		}
	}

	for (dgList<dgListNode*>::dgListNode* coneNode = coneList.GetFirst(); coneNode->GetNext(); coneNode = coneNode->GetNext()) {
		dgListNode* const coneNodeA = coneNode->GetInfo();
		for (dgList<dgListNode*>::dgListNode* nextConeNode = coneNode->GetNext(); nextConeNode; nextConeNode = nextConeNode->GetNext()) {
			dgListNode* const coneNodeB = nextConeNode->GetInfo();
			LinkSibling (coneNodeA, coneNodeB);
		}
	}
}
コード例 #3
0
 bool DetectPolygons::processFrameContainer(BaseFrameContainer *frm, BaseFrameSource *frameSource)
 {
     Shapes* shapes = frm->getShapes();
     std::vector<Point>  approxCurve;
     unsigned int size = 0;
     ///for each contour, analyze if it is a paralelepiped likely to be the marker
     for (unsigned int i=0;i<shapes->getContours().size();i++)
     {
         
         unsigned int contourSize = shapes->getContours()[i].size();
         //check it is a possible element by first checking is has enough points
         if (contourSize>(unsigned int)(frm->getFrame()->getMat().cols /15))
         {
             //approximate to a polygon - 1. limit slozitosti (pocet bodu krat cislo vs konstanta), 2. uzavreny
             
             double complexity = double(contourSize)*complexityKoef;
             complexity = complexity > maxComplexity ? maxComplexity : (complexity < minComplexity ? minComplexity : complexity);
             cv::approxPolyDP(  cv::Mat (shapes->getContours()[i]),approxCurve , complexity , onlyClosed);
             
             size = approxCurve.size();
             unsigned int one, two;
             
             if (approxCurve.size() >= 3) {
                 // remove inline points
                 for (unsigned int i = 0; i < size; i++) {
                     one = (i + 1)%size;
                     two = (i + 2)%size;
                     // rozdil smernic
                     double x1 = approxCurve[i].x, y1 =  approxCurve[i].y,
                            x2 = approxCurve[one].x, y2 =  approxCurve[one].y,
                            x3 = approxCurve[two].x, y3 =  approxCurve[two].y;
                     
                     float k = std::abs(((y2-y1)/(x2-x1)) - ((y3-y1)/(x3-x1)));
                     
                     float d1 = std::sqrt((float) (approxCurve[i].x-approxCurve[one].x)*(approxCurve[i].x-approxCurve[one].x) +
                                        (approxCurve[i].y-approxCurve[one].y)*(approxCurve[i].y-approxCurve[one].y));
                     
                     float d2 = std::sqrt((float) (approxCurve[i].x-approxCurve[two].x)*(approxCurve[i].x-approxCurve[two].x) +
                                          (approxCurve[i].y-approxCurve[two].y)*(approxCurve[i].y-approxCurve[two].y));
                         
                     // if angle is too small or points are too close
                     if (k < 0.2 || d1 < 0.04*d2) {
                         approxCurve.erase(approxCurve.begin()+one);
                         size--;
                     }
                 }
             }
             
             
             if (size >= minimalPolygonLines && size <= maximalPolygonLines)
             {
                 
                 //and is convex
                 if (!onlyConvex || cv::isContourConvex(Mat  (approxCurve)))
                 {
                     
                     float minDist=1e10;
                     if (minDistance > 0) {
                         for (int i=0;i<size;i++)
                         {
                             float d= std::sqrt((float) (approxCurve[i].x-approxCurve[(i+1)%size].x)*(approxCurve[i].x-approxCurve[(i+1)%size].x) +
                                                (approxCurve[i].y-approxCurve[(i+1)%size].y)*(approxCurve[i].y-approxCurve[(i+1)%size].y));
                             if (d<minDist) minDist=d;
                         }
                     }
                     if (minDist>=minDistance)
                     {
                         shapes->getMarkers().push_back(Marker());
                         for (unsigned int i=0;i<size;i++)
                         {
                             shapes->getMarkers().back().push_back( Point2f(approxCurve[i].x,approxCurve[i].y));
                         }
                     }
                 }
             }
         }
     }
     
     /// remove these elements whise corners are too close to each other
     //first detect candidates
     size = shapes->getMarkers().size();
     
     if (minimalPolygonLines==4 && maximalPolygonLines == 4) {
         for (unsigned int i=0;i<shapes->getMarkers().size();i++)
         {
             
             //trace a line between the first and second point.
             //if the thrid point is at the right side, then the points are anti-clockwise
             double dx1 = shapes->getMarkers()[i][1].x - shapes->getMarkers()[i][0].x;
             double dy1 =  shapes->getMarkers()[i][1].y - shapes->getMarkers()[i][0].y;
             double dx2 = shapes->getMarkers()[i][2].x - shapes->getMarkers()[i][0].x;
             double dy2 = shapes->getMarkers()[i][2].y - shapes->getMarkers()[i][0].y;
             double o = (dx1*dy2)-(dy1*dx2);
             
             if (o  < 0.0)		 //if the third point is in the left side, then sort in anti-clockwise order
             {
                 swap(shapes->getMarkers()[i][1],shapes->getMarkers()[i][3]);
             }
         }
     }
     
     
     vector<pair<int,int>  > TooNearCandidates;
     for (unsigned int i=0;i < size;i++)
     {
         // 	cout<<"Marker i="<<i<<MarkerCanditates[i]<<endl;
         //calculate the average distance of each corner to the nearest corner of the other marker candidate
         for (unsigned int j=i+1;j<size;j++)
         {
             unsigned int vertexCount = shapes->getMarkers()[i].size();
             if (vertexCount == shapes->getMarkers()[j].size()) {
                 float dist=0;
                 for (unsigned int c=0;c<vertexCount;c++)
                     dist+= std::sqrt(  (shapes->getMarkers()[i][c].x-shapes->getMarkers()[j][c].x)*(shapes->getMarkers()[i][c].x-shapes->getMarkers()[j][c].x)+(shapes->getMarkers()[i][c].y-shapes->getMarkers()[j][c].y)*(shapes->getMarkers()[i][c].y-shapes->getMarkers()[j][c].y));
                 dist/=vertexCount;
                 //if distance is too small
                 if (dist< 14) {
                     TooNearCandidates.push_back(pair<int,int>(i,j));
                 }
             }
         }
     }
     //mark for removal the element of  the pair with smaller perimeter
     vector<bool> toRemove (shapes->getMarkers().size(),false);
     for (unsigned int i=0;i<TooNearCandidates.size();i++) {
         if ( perimeter(shapes->getMarkers()[TooNearCandidates[i].first ])>perimeter(shapes->getMarkers()[ TooNearCandidates[i].second] ))
             toRemove[TooNearCandidates[i].second]=true;
         else toRemove[TooNearCandidates[i].first]=true;
     }
     
     //remove the invalid ones
     removeElements(shapes->getMarkers(),toRemove);
     
     return true;
 }
コード例 #4
0
ファイル: Square_pointer.c プロジェクト: elnazd/IPC144-F14
int main()
{
	struct Square mainSquare = {4,0,0};
	area(&mainSquare);
	perimeter(&mainSquare);
}
コード例 #5
0
ファイル: s0075.c プロジェクト: recursion-ninja/ProjectEuler
int triplePerimeterCmp(const void * lhs, const void * rhs) {
  return perimeter(*(triple **)lhs)
       - perimeter(*(triple **)rhs);
}
コード例 #6
0
ファイル: analysis.c プロジェクト: rfabbri/animal
/*
   TODO
   - label_contour is called two times; only once suffices
*/
AnimalExport ImgPUInt32 *
msskl_difference(ann_img *aimg)
{
   ImgPUInt32 *imcont, *immsskel, *imseed, *imperim;
   puint32 *seed, *cont, *perim, *pred, *label, *msskel,
            maxd1, maxd2, MaxD;
   int r,c,i,j,k,qx,qy,p,q, d1,d2,
       *idxlut,n;

   r = aimg->label->rows; 
   c = aimg->label->cols;
   n = r*c;
   idxlut   = aimg->label->lut;
   imcont   = label_contour(aimg->img);  
   imperim  = perimeter(aimg->img);
   immsskel = new_img_puint32(r,c);
   imseed   = root_map(aimg->pred);

   seed     = imseed->data;
   cont     = imcont->data;
   perim    = imperim->data;
   msskel   = immsskel->data;
   pred     = aimg->pred->data;
   label    = aimg->label->data;

   MaxD = 0;
   for (i=0; i<r; i++) 
         for (j=0; j<c; j++) {
            p = index1(i,j,idxlut);
            // @@@ why eliminate the contours??
            if (pred[p] != (unsigned)p) {/* Eliminates the contours and
                                            considers the side option */
               maxd1 = maxd2 = 0;
               for (k=0; k < 4; k++) {
                  qy = n4[k][0] + i;
                  qx = n4[k][1] + j;
                  if (valid_pixel(r,c,qx,qy)) {
                     q = index1(qy,qx,idxlut);
                     if (cont[seed[p]] == cont[seed[q]]) { // not a SKIZ
                        d2 = label[q] - label[p];
                        if (d2 > (int)perim[seed[p]]-d2)
                           d2 = (int)perim[seed[p]]-d2;
                        if (d2 > (int)maxd2)
                           maxd2 = (unsigned)d2;
                     } else { // a SKIZ
                        d1 = cont[seed[q]] - cont[seed[p]];
                        if (d1 > (int)maxd1)
                           maxd1 = (unsigned)d1;
                     }
                  }
               }
               if (maxd1 > 0)
                  msskel[p] = UINT_MAX;
               else {
                  msskel[p] = maxd2;
                  if (msskel[p] > MaxD)
                     MaxD = msskel[p];
               }
            }
         }

   for (p=0; p < n; p++)
      if (msskel[p] == UINT_MAX)
         msskel[p] = MaxD + 1;

   imfree_puint32(&imcont);
   imfree_puint32(&imperim);
   imfree_puint32(&imseed);
   return immsskel;
}
コード例 #7
0
ファイル: MGSBRep4.cpp プロジェクト: zephyrer/mgcl
//Compute continuity with brep2.
int MGSBRep::continuity(	// Reuturn value is the continuity.
	const MGSBRep& brep2,	// Input second SBRep
	int is_u1,		// Input if u-direction of this.
	int is_u2,		// Input if u-direction of brep2.
	int opposite,	// Input if parameter direction of which2 is equal or not.
	int& which1,	// Outputs which perimeter(which1) of this is
	int& which2,	// connected to which(which2) of brep2.
					// These are valid only when continuity>=0.
	double& ratio	// Ratio of 1st derivatives of the two surfaces will
					// be returned.
			// ratio= d2/d1, where d1=1st deriv of this and d2=of brep2
	) const
	// Function's return value is:
	// -1: G(-1) continuity, i.e. two surfaces are discontinuous.
	//  0: G0 continuity, i.e. two surfaces are connected,
	//     but tangents are discontinuous
	//  1: G1 continuity, i.e. two surfaces are connected,
	//     and tangents are also continuous.
	//  2: G2 continuity, i.e. two surfaces are connected,
	//     and tangents and curvatures are also continuous.
{
	size_t i,j,k,i2; int incrmnt;
	double ratio2; int which;
	int cont, contold;
	size_t dim1=sdim(), dim2=brep2.sdim();
	size_t ns1,nt1, ns2,nt2;
	MGLBRep p1a, p1b, p2a, p2b;

	// Test if perimeter of this is continuous to perimeter brep2.
	const MGKnotVector *s1,*s2,*t1,*t2;
	if(is_u1){
		which1=0; 
		s1=&knot_vector_u(); t1=&knot_vector_v();
		p1a=perimeter(0); p1b=perimeter(2);
	}
	else{
		which1=1;
		s1=&knot_vector_v(); t1=&knot_vector_u();
		p1a=perimeter(1); p1b=perimeter(3);
	}
	if(is_u2){
		which2=0;
		s2=&(brep2.knot_vector_u()); t2=&(brep2.knot_vector_v());
		p2a=brep2.perimeter(0); p2b=brep2.perimeter(2);
	}
	else{
		which2=1;
		s2=&(brep2.knot_vector_v()); t2=&(brep2.knot_vector_u());
		p2a=brep2.perimeter(1); p2b=brep2.perimeter(3);
	}
	ns1=(*s1).bdim(); ns2=(*s2).bdim();
	nt1=(*t1).bdim(); nt2=(*t2).bdim();

	cont=0;
	// 1. Test if positional data of two perimeters are equal.
	if(opposite){ p2a.negate(); p2b.negate();}
	if     (p1a.line_bcoef()==p2a.line_bcoef()){
		cont=1;}
	else if(p1a.line_bcoef()==p2b.line_bcoef()){
		which2+=2; cont=1;}
	else if(p1b.line_bcoef()==p2a.line_bcoef()){
		which1+=2; cont=1;}
	else if(p1b.line_bcoef()==p2b.line_bcoef()){
		which1+=2; which2+=2; cont=1;}
	if(cont==0) return -1;

	// There exists a possibility of continuity 1.
	// 2. Test if derivatives along v direction are equal.
	i2=0; incrmnt=1; if(opposite) {i2=ns2-1; incrmnt=-1;}
	MGBPointSeq b1(nt1,dim1), b2(nt2,dim2);
	contold=0;
	for(i=0; i<ns1; i++){
		if(is_u1){
			for(j=0; j<nt1; j++)
				for(k=0; k<dim1; k++) b1(j,k)=coef(i,j,k);
		}
		else{
			for(j=0; j<nt1; j++)
				for(k=0; k<dim1; k++) b1(j,k)=coef(j,i,k);
		}
		if(is_u2){
			for(j=0; j<nt2; j++)
				for(k=0; k<dim2; k++) b2(j,k)=brep2.coef(i2,j,k);
		}
		else{
			for(j=0; j<nt2; j++)
				for(k=0; k<dim2; k++) b2(j,k)=brep2.coef(j,i2,k);
		}
		i2=i2+incrmnt;

		MGLBRep lb1(*t1,b1), lb2(*t2, b2);
		cont=lb1.continuity(lb2,which,ratio2);
		if(cont<=0) return 0;			          //Continuity is C0.
		if(contold==0) {contold=cont; ratio=ratio2;}
		else{
			if(!MGREqual2(ratio2,ratio)) return 0; //Continuity is C0.
			else if(contold>cont) contold=cont;
		}
	}
	return contold;
}
コード例 #8
0
ファイル: qgstriangle.cpp プロジェクト: GeoCat/QGIS
double QgsTriangle::inscribedRadius() const
{
  return ( 2.0 * area() / perimeter() );
}
コード例 #9
0
 /// As used by OpenCV, return value in [0, 1] - requires contour
 double circularity() const {
     auto perim = perimeter();
     return 4 * CV_PI * area() / (perim * perim);
 }
コード例 #10
0
ファイル: rectangle.cpp プロジェクト: Sergane/ff_tasks
bool Rectangle::operator>(Rectangle & rect2){
	if(area()>rect2.area() && perimeter()>rect2.perimeter())
		return true;
	return false;
}
コード例 #11
0
double Shape :: areaToPerimeter()const
{
    return area()/perimeter();
}