Beispiel #1
0
CvSeq*
create_seq(int seq_flags, size_t header_size, VALUE storage_value)
{
  VALUE klass = Qnil;
  int eltype = seq_flags & CV_SEQ_ELTYPE_MASK;
  storage_value = CHECK_CVMEMSTORAGE(storage_value);

  if (!eltype2class(eltype, &klass)) {
    seq_flags = CV_SEQ_ELTYPE_POINT | CV_SEQ_KIND_GENERIC;
  }

  int mat_type = CV_MAT_TYPE(seq_flags);
  size_t elem_size = (size_t)(CV_ELEM_SIZE(mat_type));
  CvSeq* seq = NULL;
  try {
    seq = cvCreateSeq(seq_flags, header_size, elem_size, CVMEMSTORAGE(storage_value));
  }
  catch (cv::Exception& e) {
    raise_cverror(e);
  }
  register_elem_class(seq, klass);
  register_root_object(seq, storage_value);
  
  return seq;
}
Beispiel #2
0
/*
 * call-seq:
 *   contour(<i>[criteria = 0]</i>) -> cvcontour
 *
 * Restores the contour from its binary tree representation.
 * The parameter criteria determines the accuracy and/or the number of tree levels
 * used for reconstruction, so it is possible to build approximated contour.
 */
VALUE
rb_contour(int argc, VALUE *argv, VALUE self)
{
  VALUE criteria, storage;
  rb_scan_args(argc, argv, "01", &criteria);
  CvSeq *contour = cvContourFromContourTree(CVCONTOURTREE(self), CVMEMSTORAGE(storage), VALUE_TO_CVTERMCRITERIA(criteria));
  return cCvSeq::new_sequence(cCvContour::rb_class(), contour, cCvPoint::rb_class(), storage);
}
Beispiel #3
0
VALUE
new_object()
{
  VALUE storage = cCvMemStorage::new_object();
  CvSeq *seq = NULL;
  try {
    seq = cvCreateSeq(CV_SEQ_CHAIN_CONTOUR, sizeof(CvChain), sizeof(char), CVMEMSTORAGE(storage));
  }
  catch (cv::Exception& e) {
    raise_cverror(e);
  }
  return cCvSeq::new_sequence(cCvChain::rb_class(), seq, T_FIXNUM, storage);
}
Beispiel #4
0
/*
 * call-seq:
 *   CvSeq.new(type[,storage])
 *
 * Return a new CvSeq. <i>type</i> should be following classes.
 *
 * * CvIndex
 * * CvPoint
 */
VALUE
rb_initialize(int argc, VALUE *argv, VALUE self)
{
  VALUE klass, storage_value;

  rb_scan_args(argc, argv, "11", &klass, &storage_value);
  if (!rb_obj_is_kind_of(klass, rb_cClass))
    raise_typeerror(klass, rb_cClass);

  int type = 0, size = 0;
  if (klass == rb_cFixnum) {
    type = CV_SEQ_ELTYPE_INDEX;
    size = sizeof(int);
  }
  else if (klass == cCvPoint::rb_class()) {
    type = CV_SEQ_ELTYPE_POINT;
    size = sizeof(CvPoint);
  }
  else if (klass == cCvPoint2D32f::rb_class()) {
    type = CV_SEQ_ELTYPE_POINT;
    size = sizeof(CvPoint2D32f);
  }
  else if (klass == cCvPoint3D32f::rb_class()) {
    type = CV_SEQ_ELTYPE_POINT3D;
    size = sizeof(CvPoint3D32f);
  }
  else
    rb_raise(rb_eArgError, "unsupport %s class for sequence-block.", rb_class2name(klass));
  
  CvSeq* seq = NULL;
  if (NIL_P(storage_value)) {
    storage_value = cCvMemStorage::new_object(0);
  }
  else {
    storage_value = CHECK_CVMEMSTORAGE(storage_value);
  }
  
  try {
    seq = cvCreateSeq(type, sizeof(CvSeq), size, CVMEMSTORAGE(storage_value));
  }
  catch (cv::Exception& e) {
    raise_cverror(e);
  }
  DATA_PTR(self) = seq;
  register_elem_class(seq, klass);
  register_root_object(seq, storage_value);
  
  return self;
}
Beispiel #5
0
/*
 * Creates hierarchical representation of contour
 * @overload create_tree(threshold = 0.0)
 *   @param threshold [Number] If <= 0, the method creates full binary tree representation.
 *     If > 0, the method creates representation with the precision threshold.
 * @return [CvContourTree] Hierarchical representation of the contour
 * @opencv_func cvCreateContourTree
 */
VALUE
rb_create_tree(int argc, VALUE *argv, VALUE self)
{
  VALUE threshold, storage;
  rb_scan_args(argc, argv, "01", &threshold);
  storage = cCvMemStorage::new_object();
  CvContourTree *tree = NULL;
  try {
    tree = cvCreateContourTree(CVSEQ(self), CVMEMSTORAGE(storage), IF_DBL(threshold, 0.0));
  }
  catch (cv::Exception& e) {
    raise_cverror(e);
  }
  return cCvSeq::new_sequence(cCvContourTree::rb_class(), (CvSeq*)tree, cCvPoint::rb_class(), storage);
}
Beispiel #6
0
/*
 * Approximates polygonal curves with desired precision
 * @overload approx_poly(options)
 *   @param options [Hash] Parameters
 *   @option options [Symbol] :method Approximation method (default :dp)
 *     * :dp - Douglas-Peucker algorithm.
 *   @option options [Number] :accuracy Parameter specifying the approximation accuracy.
 *     This is the maximum distance between the original curve and its approximation.
 *   @option options [Boolean] :recursive Recursion flag. If true, the function approximates
 *     all the contours accessible from curve by h_next and v_next links.
 * @return [CvContour] Result of the approximation
 * @return [nil] Approximation faied
 * @opencv_func cvApproxPoly
 */
VALUE
rb_approx_poly(int argc, VALUE *argv, VALUE self)
{
  VALUE approx_poly_option;
  rb_scan_args(argc, argv, "01", &approx_poly_option);  
  approx_poly_option = APPROX_POLY_OPTION(approx_poly_option);
  VALUE storage = cCvMemStorage::new_object();
  CvSeq *contour = cvApproxPoly(CVCONTOUR(self), sizeof(CvContour), CVMEMSTORAGE(storage),
				APPROX_POLY_METHOD(approx_poly_option),
				APPROX_POLY_ACCURACY(approx_poly_option),
				APPROX_POLY_RECURSIVE(approx_poly_option));

  if (contour && contour->total > 0) {
    return cCvSeq::new_sequence(cCvContour::rb_class(), contour, cCvPoint::rb_class(), storage);
  }
  return Qnil;
}
Beispiel #7
0
CvSeq*
create_seq(int seq_flags, size_t header_size, VALUE storage_value)
{
  VALUE klass = Qnil;
  int eltype = seq_flags & CV_SEQ_ELTYPE_MASK;
  storage_value = CHECK_CVMEMSTORAGE(storage_value);

  switch (eltype) {
  case CV_SEQ_ELTYPE_POINT:
    klass = cCvPoint::rb_class();
    break;
  case CV_32FC2:
    klass = cCvPoint2D32f::rb_class();
    break;
  case CV_SEQ_ELTYPE_POINT3D:
    klass = cCvPoint3D32f::rb_class();
    break;
  case CV_SEQ_ELTYPE_CODE:
  case CV_SEQ_ELTYPE_INDEX:
    klass = rb_cFixnum;
    break;
  case CV_SEQ_ELTYPE_PPOINT: // or CV_SEQ_ELTYPE_PTR:
    // Not supported
    rb_raise(rb_eArgError, "seq_flags %d is not supported.", eltype);
    break;
  default:
    seq_flags = CV_SEQ_ELTYPE_POINT | CV_SEQ_KIND_GENERIC;
    klass = cCvPoint::rb_class();
    break;
  }

  int mat_type = CV_MAT_TYPE(seq_flags);
  size_t elem_size = (size_t)(CV_ELEM_SIZE(mat_type));
  CvSeq* seq = NULL;
  try {
    seq = cvCreateSeq(seq_flags, header_size, elem_size, CVMEMSTORAGE(storage_value));
  }
  catch (cv::Exception& e) {
    raise_cverror(e);
  }
  register_elem_class(seq, klass);
  register_root_object(seq, storage_value);
  
  return seq;
}
/*
 * call-seq:
 *   detect_objects(image[, options]) -> cvseq(include CvAvgComp object)
 *   detect_objects(image[, options]){|cmp| ... } -> cvseq(include CvAvgComp object)
 *
 * Detects objects in the image. This method finds rectangular regions in the
 * given image that are likely to contain objects the cascade has been trained
 * for and return those regions as a sequence of rectangles.
 *
 * * <i>option</i> should be Hash include these keys.
 *   :scale_factor (should be > 1.0)
 *      The factor by which the search window is scaled between the subsequent scans,
 *      1.1 mean increasing window by 10%.
 *   :storage
 *      Memory storage to store the resultant sequence of the object candidate rectangles
 *   :flags
 *      Mode of operation. Currently the only flag that may be specified is CV_HAAR_DO_CANNY_PRUNING .
 *      If it is set, the function uses Canny edge detector to reject some image regions that contain
 *      too few or too much edges and thus can not contain the searched object. The particular threshold
 *      values are tuned for face detection and in this case the pruning speeds up the processing
 *   :min_neighbors
 *      Minimum number (minus 1) of neighbor rectangles that makes up an object.
 *      All the groups of a smaller number of rectangles than min_neighbors - 1 are rejected.
 *      If min_neighbors is 0, the function does not any grouping at all and returns all the detected
 *      candidate rectangles, whitch many be useful if the user wants to apply a customized grouping procedure.
 *   :min_size
 *      Minimum window size. By default, it is set to size of samples the classifier has been
 *      trained on (~20x20 for face detection).
 *   :max_size
 *      aximum window size to use. By default, it is set to the size of the image.
 */
VALUE
rb_detect_objects(int argc, VALUE *argv, VALUE self)
{ 
  VALUE image, options;
  rb_scan_args(argc, argv, "11", &image, &options);

  double scale_factor;
  int flags, min_neighbors;
  CvSize min_size, max_size;
  VALUE storage_val;
  if (NIL_P(options)) {
    scale_factor = 1.1;
    flags = 0;
    min_neighbors = 3;
    min_size = max_size = cvSize(0, 0);
    storage_val = cCvMemStorage::new_object();
  }
  else {
    scale_factor = IF_DBL(LOOKUP_CVMETHOD(options, "scale_factor"), 1.1);
    flags = IF_INT(LOOKUP_CVMETHOD(options, "flags"), 0);
    min_neighbors = IF_INT(LOOKUP_CVMETHOD(options, "min_neighbors"), 3);
    VALUE min_size_val = LOOKUP_CVMETHOD(options, "min_size");
    min_size = NIL_P(min_size_val) ? cvSize(0, 0) : VALUE_TO_CVSIZE(min_size_val);
    VALUE max_size_val = LOOKUP_CVMETHOD(options, "max_size");
    max_size = NIL_P(max_size_val) ? cvSize(0, 0) : VALUE_TO_CVSIZE(max_size_val);
    storage_val = CHECK_CVMEMSTORAGE(LOOKUP_CVMETHOD(options, "storage"));
  }

  VALUE result = Qnil;
  try {
    IplImage *ipl = IPLIMAGE_WITH_CHECK(image);
    CvSeq *seq = cvHaarDetectObjects(ipl, CVHAARCLASSIFIERCASCADE(self), CVMEMSTORAGE(storage_val),
			      scale_factor, min_neighbors, flags, min_size, max_size);
    result = cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvAvgComp::rb_class(), storage_val);
    if (rb_block_given_p()) {
      for(int i = 0; i < seq->total; ++i)
	rb_yield(REFER_OBJECT(cCvAvgComp::rb_class(), cvGetSeqElem(seq, i), storage_val));
    }
  }
  catch (cv::Exception& e) {
    raise_cverror(e);
  }
  return result;
}
Beispiel #9
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;
}
Beispiel #10
0
/*
 * call-seq:
 *   CvSeq.new(<i>type[,storage]</i>)
 *
 * Return a new CvSeq. <i>type</i> should be following classes.
 *
 * * CvIndex
 * * CvPoint
 */
VALUE
rb_initialize(int argc, VALUE *argv, VALUE self)
{
  VALUE klass, storage_value;
  CvMemStorage *storage;

  if (rb_scan_args(argc, argv, "11", &klass, &storage_value) > 1) {
    storage_value = CHECK_CVMEMSTORAGE(storage_value);
    storage = CVMEMSTORAGE(storage_value);
  }
  else
    storage = cvCreateMemStorage(0);
  
  if(!rb_obj_is_kind_of(klass, rb_cClass))
    rb_raise(rb_eTypeError, "argument 1 (sequence-block class) should be %s.", rb_class2name(rb_cClass));

  int type = 0, size = 0;
  if (klass == cCvIndex::rb_class()) {
    type = CV_SEQ_ELTYPE_INDEX;
    size = sizeof(CvIndex);
  }
  else if (klass == cCvPoint::rb_class()) {
    type = CV_SEQ_ELTYPE_POINT;
    size = sizeof(CvPoint);
  }
  else if (klass == cCvPoint2D32f::rb_class()) {
    type = CV_SEQ_ELTYPE_POINT;
    size = sizeof(CvPoint2D32f);
  }
  else if (klass == cCvPoint3D32f::rb_class()) {
    type = CV_SEQ_ELTYPE_POINT3D;
    size = sizeof(CvPoint3D32f);
  }
  // todo: more various class will be support.
  if (!size)
    rb_raise(rb_eTypeError, "unsupport %s class for sequence-block.", rb_class2name(klass));
  
  CvSeq* seq = cvCreateSeq(type, sizeof(CvSeq), size, storage);
  DATA_PTR(self) = seq;
  resist_class_information_of_sequence(seq, klass);
  
  return self;
}
Beispiel #11
0
VALUE
rb_initialize(int argc, VALUE *argv, VALUE self)
{
  CvMemStorage *storage;
  VALUE storage_value;
  if (rb_scan_args(argc, argv, "01", &storage_value) > 0) {
    storage_value = CHECK_CVMEMSTORAGE(storage_value);
    storage = CVMEMSTORAGE(storage_value);
  }
  else
    storage = rb_cvCreateMemStorage(0);
  try {
    DATA_PTR(self) = (CvChain*)cvCreateSeq(CV_SEQ_ELTYPE_CODE, sizeof(CvChain),
					   sizeof(char), storage);
  }
  catch (cv::Exception& e) {
    raise_cverror(e);
  }
  return self;
}
/*
 * call-seq:
 *   detect_objects_with_pruning(image[,scale_factor = 1.1, min_neighbor = 3, min_size = CvSize.new(0,0)]) -> cvseq(include CvAvgComp object)
 *   detect_objects_with_pruning(image[,scale_factor = 1.1, min_neighbor = 3, min_size = CvSize.new(0,0)]){|cmp| ... } -> cvseq(include CvAvgComp object)
 *
 * Almost same to #detect_objects (Return detected objects).
 * 
 * Before scanning to image, Canny edge detector to reject some image regions
 * that contain too few or too much edges, and thus can not contain the searched object.
 *
 *   note: The particular threshold values are tuned for face detection.
 *         And in this case the pruning speeds up the processing.
 */ 
VALUE
rb_detect_objects_with_pruning(int argc, VALUE *argv, VALUE self)
{
  VALUE image, storage, scale_factor, min_neighbors, min_size, result;
  rb_scan_args(argc, argv, "14", &image, &storage, &scale_factor, &min_neighbors, &min_size);
  if (!rb_obj_is_kind_of(image, cCvMat::rb_class()))
    rb_raise(rb_eTypeError, "argument 1(target-image) should be %s.", rb_class2name(cCvMat::rb_class()));
  double scale = IF_DBL(scale_factor, 1.1);
  if (!(scale > 1.0))
    rb_raise(rb_eArgError, "argument 2 (scale factor) must > 1.0.");
  storage = CHECK_CVMEMSTORAGE(storage);
  CvSeq *seq = cvHaarDetectObjects(CVMAT(image), CVHAARCLASSIFIERCASCADE(self), CVMEMSTORAGE(storage),
                                   scale, IF_INT(min_neighbors, 3), CV_HAAR_DO_CANNY_PRUNING, NIL_P(min_size) ? cvSize(0,0) : VALUE_TO_CVSIZE(min_size));
  result = cCvSeq::new_sequence(cCvSeq::rb_class(), seq, cCvAvgComp::rb_class(), storage);
  if (rb_block_given_p()) {
    for(int i = 0; i < seq->total; i++)
      rb_yield(REFER_OBJECT(cCvAvgComp::rb_class(), cvGetSeqElem(seq, i), storage));      
  }
  return result;
}
/*
 * Constructor
 * @overload new(storage = nil)
 *   @param [CvMemStorage] storage Sequence location
 * @return [CvContour] self
 * @opencv_func cvCreateSeq
 */
VALUE
rb_initialize(int argc, VALUE *argv, VALUE self)
{
  VALUE storage;
  rb_scan_args(argc, argv, "01", &storage);

  if (NIL_P(storage))
    storage = cCvMemStorage::new_object(0);
  else
    storage = CHECK_CVMEMSTORAGE(storage);

  try {
    DATA_PTR(self) = (CvContour*)cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvContour),
					     sizeof(CvPoint), CVMEMSTORAGE(storage));
  }
  catch (cv::Exception& e) {
    raise_cverror(e);
  }
  cCvSeq::register_elem_class(self, cCvPoint::rb_class());
  register_root_object(CVSEQ(self), storage);

  return self;
}