Exemplo n.º 1
0
//! Calculate contour points from crack codes
t_PointList CBlobContour::GetContourPoints()
{
	// it is calculated?
	if( m_contourPoints != NULL )
		return m_contourPoints;

	if ( m_contour == NULL || m_contour->total <= 0 )
	{
		return NULL;
	}

	CvSeq *tmpPoints;
	CvSeqReader reader;
	CvSeqWriter writer;
	CvPoint actualPoint;
	CvRect boundingBox;

	// if aproximation is different than simple extern perimeter will not work
	tmpPoints = cvApproxChains( m_contour, m_parentStorage, CV_CHAIN_APPROX_NONE);


	// apply an offset to contour points to recover real coordinates
	
	cvStartReadSeq( tmpPoints, &reader);

	m_contourPoints = cvCreateSeq( tmpPoints->flags, tmpPoints->header_size, tmpPoints->elem_size, m_parentStorage );
	cvStartAppendToSeq(m_contourPoints, &writer );

	// also calculate bounding box of the contour to allow cvPointPolygonTest
	// work correctly on the generated polygon
	boundingBox.x = boundingBox.y = 10000;
	boundingBox.width = boundingBox.height = 0;
	
	for( int i=0; i< tmpPoints->total; i++)
	{
		CV_READ_SEQ_ELEM( actualPoint, reader);

		actualPoint.x += m_startPoint.x;
		actualPoint.y += m_startPoint.y;

		boundingBox.x = MIN( boundingBox.x, actualPoint.x );
		boundingBox.y = MIN( boundingBox.y, actualPoint.y );
		boundingBox.width = MAX( boundingBox.width, actualPoint.x );
		boundingBox.height = MAX( boundingBox.height, actualPoint.y );
		
		CV_WRITE_SEQ_ELEM( actualPoint, writer );
	}
	cvEndWriteSeq( &writer );
	cvClearSeq( tmpPoints );

	// assign calculated bounding box
	((CvContour*)m_contourPoints)->rect = boundingBox;


	return m_contourPoints;
}
Exemplo n.º 2
0
/*
 * call-seq:
 *   approx_chains(<i>[approx_chain_option]</i>) -> cvcontour
 *
 * Approximates Freeman chain(s) with polygonal curve.
 * <i>approx_chain_option</i> should be Hash include these keys.
 *   :method - Approximation method.
 *      :approx_none - translate all the points from the chain code into points;
 *      :approx_simple(default) - compress horizontal, vertical, and diagonal segments, that is,
 *                                the function leaves only their ending points.
 *      :approx_tc89_l1
 *      :approx_tc89_kcos - apply one of the flavors of Teh-Chin chain approximation algorithm.
 *      If set the difference between the current pixel and seed pixel is considered,
 *      otherwise difference between neighbor pixels is considered (the range is floating).
 *   :parameter - Method parameter (not used now).
 *   :minimal_perimeter (default 0)
 *      Approximates only those contours whose perimeters are not less than minimal_perimeter. Other chains are removed from the resulting structure.
 *   :recursive (default false)
 *      If not nil or false, the function approximates all chains that access can be obtained to
 *      from self by h_next or v_next links. If 0, the single chain is approximated.
 *
 */
VALUE
rb_approx_chains(int argc, VALUE *argv, VALUE self)
{
  VALUE approx_chain_option;
  rb_scan_args(argc, argv, "01", &approx_chain_option);

  approx_chain_option = APPROX_CHAIN_OPTION(approx_chain_option);
  VALUE storage = cCvMemStorage::new_object();
  CvSeq *seq = cvApproxChains(CVSEQ(self), CVMEMSTORAGE(storage),			      
			      APPROX_CHAIN_METHOD(approx_chain_option),
			      APPROX_CHAIN_PARAMETER(approx_chain_option),
			      APPROX_CHAIN_MINIMAL_PERIMETER(approx_chain_option),
			      APPROX_CHAIN_RECURSIVE(approx_chain_option));

  if (seq && seq->total > 0) {
    return cCvSeq::new_sequence(cCvChain::rb_class(), seq, cCvPoint::rb_class(), storage);
  }
  return Qnil;
}