VALUE rb_seq_push(VALUE self, VALUE args, int flag) { CvSeq *seq = CVSEQ(self); VALUE klass = seqblock_class(seq), object; void *buffer = NULL; for (int i = 0; i < RARRAY_LEN(args); i++) { object = RARRAY_PTR(args)[i]; if (CLASS_OF(object) == klass) { if (flag == CV_FRONT) cvSeqPushFront(seq, DATA_PTR(object)); else cvSeqPush(seq, DATA_PTR(object)); } else if (rb_obj_is_kind_of(object, rb_klass) && CLASS_OF(rb_first(object)) == klass) { // object is CvSeq buffer = cvCvtSeqToArray(CVSEQ(object), cvAlloc(CVSEQ(object)->total * CVSEQ(object)->elem_size)); cvSeqPushMulti(seq, buffer, CVSEQ(object)->total, flag); cvFree(&buffer); } else { rb_raise(rb_eTypeError, "arguments should be %s or %s which includes %s.", rb_class2name(klass), rb_class2name(rb_klass), rb_class2name(klass)); } } return self; }
/* * call-seq: * each_index{|index| ... } -> self * * Same as CvSeq#each, but passes the index of the element instead of the element itself. */ VALUE rb_each_index(VALUE self) { CvSeq *seq = CVSEQ(self); for(int i = 0; i < seq->total; i++) rb_yield(INT2FIX(i)); return self; }
/* * call-seq: * last -> obj or nil * * Return last sequence-block. */ VALUE rb_last(VALUE self) { CvSeq *seq = CVSEQ(self); if(!(seq->total > 0)) return Qnil; return REFER_OBJECT(seqblock_class(seq), cvGetSeqElem(seq, -1), self); }
/* * call-seq: * v_next -> seq or nil * * Return the sequence vertically located in next. * Return <tt>nil</tt> if not existing. */ VALUE rb_v_next(VALUE self) { CvSeq *seq = CVSEQ(self); if (seq->v_next) return new_sequence(CLASS_OF(self), seq->v_next, seqblock_class(seq), lookup_root_object(seq)); else return Qnil; }
VALUE auto_extend(VALUE object) { CvSeq *seq = CVSEQ(object); if(CV_IS_SEQ_POINT_SET(seq)){ rb_extend_object(object, mPointSet::rb_module()); } return object; }
/* * call-seq: * insert(<i>index,obj</i>) -> self * * Inserts the given values before element with the given index (which may be negative). */ VALUE rb_insert(VALUE self, VALUE index, VALUE object) { Check_Type(index, T_FIXNUM); CvSeq *seq = CVSEQ(self); VALUE klass = seqblock_class(seq); if(CLASS_OF(object) != klass) rb_raise(rb_eTypeError, "arguments should be %s.", rb_class2name(klass)); cvSeqInsert(seq, FIX2INT(index), DATA_PTR(object)); return self; }
/* * call-seq: * shift -> obj or nil * * Returns the first element of <i>self</i> and removes it (shifting all other elements down by one). Returns <tt>nil</tt> if the array is empty. */ VALUE rb_shift(VALUE self) { CvSeq *seq = CVSEQ(self); if(!(seq->total > 0)){ return Qnil; } VALUE object = GENERIC_OBJECT(seqblock_class(seq), malloc(seq->elem_size)); cvSeqPopFront(seq, DATA_PTR(object)); return object; }
/* * call-seq: * [<i>index</i>] -> obj or nil * * Return sequence-block at <i>index</i>. */ VALUE rb_aref(VALUE self, VALUE index) { CvSeq *seq = CVSEQ(self); int idx = NUM2INT(index); if(!(seq->total > 0)) return Qnil; if (idx >= seq->total) rb_raise(rb_eIndexError, "index %d out of sequence", idx); return REFER_OBJECT(seqblock_class(seq), cvGetSeqElem(seq, idx), self); }
/* * call-seq: * each{|obj| ... } -> self * * Calls block once for each sequence-block in <i>self</i>, * passing that sequence-block as a parameter. * seq = CvSeq.new(CvIndex) * seq.push(5, 6, 7) * seq.each{|x| print x, " -- " } * produces: * 5 -- 6 -- 7 -- */ VALUE rb_each(VALUE self) { CvSeq *seq = CVSEQ(self); if(seq->total > 0){ VALUE klass = seqblock_class(seq); for(int i = 0; i < seq->total; i++){ rb_yield(REFER_OBJECT(klass, cvGetSeqElem(seq, i), self)); } } return self; }
VALUE rb_initialize(int argc, VALUE *argv, VALUE self) { VALUE area, value, rect, contour; rb_scan_args(argc, argv, "04", &area, &value, &rect, &contour); if (!NIL_P(area)) CVCONNECTEDCOMP(self)->area = NUM2DBL(area); if (!NIL_P(value)) CVCONNECTEDCOMP(self)->value = *CVSCALAR(value); if (!NIL_P(rect)) CVCONNECTEDCOMP(self)->rect = *CVRECT(rect); if (!NIL_P(contour)) CVCONNECTEDCOMP(self)->contour = CVSEQ(contour); }
/* * 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); }
/* * call-seq: * [<i>index</i>] -> obj or nil * * Return sequence-block at <i>index</i>. */ VALUE rb_aref(VALUE self, VALUE index) { CvSeq *seq = CVSEQ(self); int idx = NUM2INT(index); if (seq->total == 0) return Qnil; if (idx >= seq->total) rb_raise(rb_eIndexError, "index %d out of sequence", idx); VALUE result = Qnil; try { if (seqblock_class(seq) == rb_cFixnum) result = INT2NUM(*CV_GET_SEQ_ELEM(int, seq, idx)); else result = REFER_OBJECT(seqblock_class(seq), cvGetSeqElem(seq, idx), self); }
/* * 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: * [<i>index</i>] -> obj or nil * * Return sequence-block at <i>index</i>. */ VALUE rb_aref(VALUE self, VALUE index) { CvSeq *seq = CVSEQ(self); int idx = NUM2INT(index); if (seq->total == 0) { return Qnil; } if (idx >= seq->total) { rb_raise(rb_eIndexError, "index %d out of sequence", idx); } VALUE result = Qnil; try { VALUE klass = seqblock_class(seq); if (RTEST(rb_class_inherited_p(klass, rb_cInteger))) { result = INT2NUM(*CV_GET_SEQ_ELEM(int, seq, idx)); } else { result = REFER_OBJECT(klass, cvGetSeqElem(seq, idx), self); } }
/* * 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; }
/* * call-seq: * empty? -> true or false. * * Return <tt>true</tt> if contain no object, otherwize return <tt>false</tt>. */ VALUE rb_empty_q(VALUE self) { return CVSEQ(self)->total == 0 ? Qtrue : Qfalse; }
/* * call-seq: * total -> int * * Return total number of sequence-block. */ VALUE rb_total(VALUE self) { return INT2NUM(CVSEQ(self)->total); }
/* * no idia. */ VALUE rb_simple_q(VALUE self) { return CV_IS_SEQ_SIMPLE(CVSEQ(self)) ? Qtrue : Qfalse; }
/* * If curve is hole(inner contour), return true. Otherwise return false. */ VALUE rb_hole_q(VALUE self) { return CV_IS_SEQ_HOLE(CVSEQ(self)) ? Qtrue : Qfalse; }
/* * If curve is convex, return true. Otherwise return false. */ VALUE rb_convex_q(VALUE self) { return CV_IS_SEQ_CONVEX(CVSEQ(self)) ? Qtrue : Qfalse; }
/* * If curve is closed, return true. Otherwise return false. */ VALUE rb_closed_q(VALUE self) { return CV_IS_SEQ_CLOSED(CVSEQ(self)) ? Qtrue : Qfalse; }
/* * call-seq: * clear -> self * * Clears sequence. Removes all elements from the sequence. */ VALUE rb_clear(VALUE self) { cvClearSeq(CVSEQ(self)); return self; }
/* * call-seq: * remove(<i>index</i>) -> obj or nil * * Deletes the elements at the specified index. */ VALUE rb_remove(VALUE self, VALUE index) { cvSeqRemove(CVSEQ(self), FIX2INT(index)); return self; }