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; }
/* * 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); }
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); }
/* * 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; }
/* * 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); }
/* * 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; }
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; }
/* * 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; }
/* * 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; }
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; }