Example #1
0
  CvContourPolygon *cvSimplifyPolygon(CvContourPolygon const *p, double const delta)
  {
    CV_FUNCNAME("cvSimplifyPolygon");
    __CV_BEGIN__;
    {
      CV_ASSERT(p!=NULL);
      CV_ASSERT(p->size()>2);

      double furtherDistance=0.;
      unsigned int furtherIndex=0;

      CvContourPolygon::const_iterator it=p->begin();
      ++it;
      for (unsigned int i=1; it!=p->end(); ++it, i++)
      {
	double d = cvDistancePointPoint(*it, p->front());

	if (d>furtherDistance)
	{
	  furtherDistance = d;
	  furtherIndex = i;
	}
      }

      if (furtherDistance<delta)
      {
	CvContourPolygon *result = new CvContourPolygon;
	result->push_back(p->front());
	return result;
      }

      bool *pnUseFlag = new bool[p->size()];
      for (int i=1; i<p->size(); i++) pnUseFlag[i] = false;

      pnUseFlag[0] = pnUseFlag[furtherIndex] = true;

      simplifyPolygonRecursive(p, 0, furtherIndex, pnUseFlag, delta);
      simplifyPolygonRecursive(p, furtherIndex, -1, pnUseFlag, delta);

      CvContourPolygon *result = new CvContourPolygon;

      for (int i=0; i<p->size(); i++)
	if (pnUseFlag[i])
	  result->push_back((*p)[i]);

      delete[] pnUseFlag;

      return result;
    }
    __CV_END__;
  }
Example #2
0
  CvContourPolygon *cvConvertChainCodesToPolygon(CvContourChainCode const *cc)
  {
    CV_FUNCNAME("cvConvertChainCodesToPolygon");
    __CV_BEGIN__;
    {
      CV_ASSERT(cc!=NULL);

      CvContourPolygon *contour = new CvContourPolygon;

      unsigned int x = cc->startingPoint.x;
      unsigned int y = cc->startingPoint.y;
      contour->push_back(cvPoint(x, y));

      if (cc->chainCode.size())
      {
        CvChainCodes::const_iterator it=cc->chainCode.begin();
        CvChainCode lastCode = *it;

        x += cvChainCodeMoves[*it][0];
        y += cvChainCodeMoves[*it][1];

        ++it;

        for (; it!=cc->chainCode.end(); ++it)
        {
          if (lastCode!=*it)
          {
            contour->push_back(cvPoint(x, y));
            lastCode=*it;
          }

          x += cvChainCodeMoves[*it][0];
          y += cvChainCodeMoves[*it][1];
        }
      }

      return contour;
    }
    __CV_END__;
  }
Example #3
0
  void cvWriteContourPolygonSVG(const CvContourPolygon& p, const string& filename, const CvScalar& stroke, const CvScalar& fill)
  {
    int minx=INT_MAX;
    int miny=INT_MAX;
    int maxx=INT_MIN;
    int maxy=INT_MIN;

    stringstream buffer("");

    for (CvContourPolygon::const_iterator it=p.begin(); it!=p.end(); ++it)
    {
      if (it->x>maxx)
	maxx = it->x;
      if (it->x<minx)
	minx = it->x;

      if (it->y>maxy)
	maxy = it->y;
      if (it->y<miny)
	miny = it->y;

      buffer << it->x << "," << it->y << " ";
    }

    ofstream f;
    f.open(filename.c_str());

    f << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" standalone=\"no\"?>" << endl;
    f << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">" << endl;
    f << "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:space=\"preserve\" width=\"" << maxx-minx << "px\" height=\"" << maxy-miny << "px\" viewBox=\"" << minx << " " << miny << " " << maxx << " " << maxy << "\" zoomAndPan=\"disable\" >" << endl;

    f << "<polygon fill=\"rgb(" << fill.val[0] << "," << fill.val[1] << "," << fill.val[2] << ")\" stroke=\"rgb(" << stroke.val[0] << "," << stroke.val[1] << "," << stroke.val[2] << ")\" stroke-width=\"1\" points=\"" << buffer.str() << "\"/>" << endl;

    f << "</svg>" << endl;

    f.close();
  }
Example #4
0
int main(int argc, char** argv)
{
  CvTracks tracks;
  
  /*drawing*/
  CvPoint pt3;
  /*colors*/
  CvScalar green = CV_RGB(0,255,0);

  cvNamedWindow("red_object_tracking", CV_WINDOW_AUTOSIZE);

  CvCapture* capture;
  capture = cvCreateFileCapture (argv[1]);
  assert( capture != NULL );
  IplImage *img = cvQueryFrame( capture );

  CvSize imgSize = cvGetSize(img);

  IplImage *frame = cvCreateImage(cvGetSize(img), img->depth, img->nChannels);

  IplConvKernel* morphKernel = cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_RECT, NULL);

  //unsigned int frameNumber = 0;
  unsigned int blobNumber = 0;

  bool quit = false;
  while (!quit)
  {
    IplImage *img = cvQueryFrame( capture );

    cvConvertScale(img, frame, 1, 0);

    IplImage *segmentated = cvCreateImage(imgSize, 8, 1);
    
    // Detecting red pixels:
    // (This is very slow, use direct access better...)
    for (unsigned int j=0; j<imgSize.height; j++)
      for (unsigned int i=0; i<imgSize.width; i++)
      {
		CvScalar c = cvGet2D(frame, j, i);

		double b = ((double)c.val[0])/255.;
		double g = ((double)c.val[1])/255.;
		double r = ((double)c.val[2])/255.;
		unsigned char f = 255*((r<0.15)&&(b<0.15)&&(g<0.15));
		//unsigned char f = 255*((r>0.5+g)&&(r>0.5+b));

		cvSet2D(segmentated, j, i, CV_RGB(f, f, f));
      }

    cvMorphologyEx(segmentated, segmentated, NULL, morphKernel, CV_MOP_OPEN, 1);

    cvShowImage("segmentated", segmentated);

    IplImage *labelImg = cvCreateImage(cvGetSize(frame), IPL_DEPTH_LABEL, 1);

    CvBlobs blobs;
    unsigned int result = cvLabel(segmentated, labelImg, blobs);
    cvFilterByArea(blobs, 50, (frame->width*frame->height)/30);
    //cvRenderBlobs(labelImg, blobs, frame, frame, CV_BLOB_RENDER_BOUNDING_BOX);
    //cvUpdateTracks(blobs, tracks, 200., 5);
    //cvRenderTracks(tracks, frame, frame, CV_TRACK_RENDER_ID|CV_TRACK_RENDER_BOUNDING_BOX);

    int l = 0;
    for (CvBlobs::const_iterator it=blobs.begin(); it!=blobs.end(); ++it, l++)
	{
	//define marker corners
	pt3 = cvPoint(it->second->centroid.x,it->second->centroid.y);
	// draw small corner circle
	cvCircle(frame, pt3, 3, green, 1, 8, 0);
	
	CvContourPolygon *polygon = cvConvertChainCodesToPolygon(&(*it).second->contour);

	double perimeter = 	cvContourPolygonPerimeter(polygon);

    CvContourPolygon *sPolygon = cvSimplifyPolygon(polygon, 5. );
    CvContourPolygon *cPolygon = cvPolygonContourConvexHull(sPolygon);
  
	if (1)  
//    if (sPolygon->size()==4)
	{
		for (CvContourPolygon::const_iterator itp=sPolygon->begin(); itp!=sPolygon->end(); ++itp)
		{

			int x = itp->x;
			int y = itp->y;
			CvPoint pt1 = cvPoint(x,y);
			cvCircle(frame, pt1, 3, CV_RGB(255, 128, 50), 1, 8, 0);
			cvRenderContourPolygon(sPolygon, frame, CV_RGB(0, 0, 255));
		}
	}

    //cvRenderContourChainCode(&(*it).second->contour, frame);
    //cvRenderContourPolygon(sPolygon, frame, CV_RGB(0, 0, 255));
    //cvRenderContourPolygon(cPolygon, frame, CV_RGB(0, 255, 0));
	}

	cvNamedWindow("red_object_tracking", CV_WINDOW_NORMAL) ;
    cvShowImage("red_object_tracking", frame);

    /*std::stringstream filename;
    filename << "redobject_" << std::setw(5) << std::setfill('0') << frameNumber << ".png";
    cvSaveImage(filename.str().c_str(), frame);*/

    cvReleaseImage(&labelImg);
    cvReleaseImage(&segmentated);

    char k = cvWaitKey(0)&0xff;
    switch (k)
    {
      case 27:
      case 'q':
      case 'Q':
        quit = true;
        break;
      case 's':
      case 'S':
        for (CvBlobs::const_iterator it=blobs.begin(); it!=blobs.end(); ++it)
        {
          std::stringstream filename;
          filename << "redobject_blob_" << std::setw(5) << std::setfill('0') << blobNumber << ".png";
          cvSaveImageBlob(filename.str().c_str(), img, it->second);
          blobNumber++;

          std::cout << filename.str() << " saved!" << std::endl;
        }
        break;
    }
    
    for (CvBlobs::const_iterator it=blobs.begin(); it!=blobs.end(); ++it)
	{
  		std::cout << "Blob #" << it->second->label << ": Area=" << it->second->area << ", Centroid=(" << it->second->centroid.x << ", " << it->second->centroid.y << ")" << std::endl;
	}

    cvReleaseBlobs(blobs);

    //frameNumber++;
  }

  cvReleaseStructuringElement(&morphKernel);
  cvReleaseImage(&frame);

  cvDestroyWindow("red_object_tracking");

  return 0;
}