1
0
Fork 0
mirror of https://github.com/ruby-opencv/ruby-opencv synced 2023-03-27 23:22:12 -04:00

change CvMat#get_rows, CvMat#get_cols

This commit is contained in:
ser1zw 2013-01-19 21:58:16 +09:00
parent d23728122f
commit c0bff63c92
3 changed files with 113 additions and 90 deletions

View file

@ -225,8 +225,8 @@ void define_ruby_class()
rb_define_method(rb_klass, "to_CvMat", RUBY_METHOD_FUNC(rb_to_CvMat), 0); rb_define_method(rb_klass, "to_CvMat", RUBY_METHOD_FUNC(rb_to_CvMat), 0);
rb_define_method(rb_klass, "sub_rect", RUBY_METHOD_FUNC(rb_sub_rect), -2); rb_define_method(rb_klass, "sub_rect", RUBY_METHOD_FUNC(rb_sub_rect), -2);
rb_define_alias(rb_klass, "subrect", "sub_rect"); rb_define_alias(rb_klass, "subrect", "sub_rect");
rb_define_method(rb_klass, "get_rows", RUBY_METHOD_FUNC(rb_get_rows), -2); rb_define_method(rb_klass, "get_rows", RUBY_METHOD_FUNC(rb_get_rows), -1);
rb_define_method(rb_klass, "get_cols", RUBY_METHOD_FUNC(rb_get_cols), -2); rb_define_method(rb_klass, "get_cols", RUBY_METHOD_FUNC(rb_get_cols), 1);
rb_define_method(rb_klass, "each_row", RUBY_METHOD_FUNC(rb_each_row), 0); rb_define_method(rb_klass, "each_row", RUBY_METHOD_FUNC(rb_each_row), 0);
rb_define_method(rb_klass, "each_col", RUBY_METHOD_FUNC(rb_each_col), 0); rb_define_method(rb_klass, "each_col", RUBY_METHOD_FUNC(rb_each_col), 0);
rb_define_alias(rb_klass, "each_column", "each_col"); rb_define_alias(rb_klass, "each_column", "each_col");
@ -1058,77 +1058,71 @@ rb_sub_rect(VALUE self, VALUE args)
return DEPEND_OBJECT(rb_klass, mat, self); return DEPEND_OBJECT(rb_klass, mat, self);
} }
/* void
* call-seq: rb_get_range_index(VALUE index, int* start, int *end) {
* get_rows(<i>n</i>) -> Return row if (rb_obj_is_kind_of(index, rb_cRange)) {
* get_rows(<i>n1, n2, ...</i>) -> Return Array of row *start = NUM2INT(rb_funcall3(index, rb_intern("begin"), 0, NULL));
* *end = NUM2INT(rb_funcall3(index, rb_intern("end"), 0, NULL));
* Return row(or rows) of matrix. if (rb_funcall3(index, rb_intern("exclude_end?"), 0, NULL) == Qfalse) {
* argument should be Fixnum or CvSlice compatible object. (*end)++;
*/ }
VALUE }
rb_get_rows(VALUE self, VALUE args)
{
int len = RARRAY_LEN(args);
if (len < 1)
rb_raise(rb_eArgError, "wrong number of argument.(more than 1)");
VALUE ary = rb_ary_new2(len);
for (int i = 0; i < len; ++i) {
VALUE value = rb_ary_entry(args, i);
CvMat* row = NULL;
try {
if (FIXNUM_P(value))
row = cvGetRow(CVARR(self), RB_CVALLOC(CvMat), FIX2INT(value));
else { else {
CvSlice slice = VALUE_TO_CVSLICE(value); *start = NUM2INT(index);
row = cvGetRows(CVARR(self), RB_CVALLOC(CvMat), slice.start_index, slice.end_index); *end = *start + 1;
} }
}
catch (cv::Exception& e) {
if (row != NULL)
cvReleaseMat(&row);
raise_cverror(e);
}
rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, row, self));
}
return RARRAY_LEN(ary) > 1 ? ary : rb_ary_entry(ary, 0);
} }
/* /*
* call-seq: * call-seq:
* get_cols(<i>n</i>) -> Return column * get_rows(row, delta_row = 1) -> cvmat
* get_cols(<i>n1, n2, ...</i>) -> Return Array of columns
* *
* Return column(or columns) of matrix. * Return row(or rows) of matrix.
* argument should be Fixnum or CvSlice compatible object. * argument <tt>row</tt> should be Fixnum or Range object.
*/ */
VALUE VALUE
rb_get_cols(VALUE self, VALUE args) rb_get_rows(int argc, VALUE* argv, VALUE self)
{ {
int len = RARRAY_LEN(args); VALUE row_val, delta_val;
if (len < 1) rb_scan_args(argc, argv, "11", &row_val, &delta_val);
rb_raise(rb_eArgError, "wrong number of argument.(more than 1)");
VALUE ary = rb_ary_new2(len); int start, end;
for (int i = 0; i < len; ++i) { rb_get_range_index(row_val, &start, &end);
VALUE value = rb_ary_entry(args, i); int delta = NIL_P(delta_val) ? 1 : NUM2INT(delta_val);
CvMat* col = NULL; CvMat* submat = RB_CVALLOC(CvMat);
try { try {
if (FIXNUM_P(value)) cvGetRows(CVARR(self), submat, start, end, delta);
col = cvGetCol(CVARR(self), RB_CVALLOC(CvMat), FIX2INT(value));
else {
CvSlice slice = VALUE_TO_CVSLICE(value);
col = cvGetCols(CVARR(self), RB_CVALLOC(CvMat), slice.start_index, slice.end_index);
}
} }
catch (cv::Exception& e) { catch (cv::Exception& e) {
if (col != NULL) cvFree(&submat);
cvReleaseMat(&col);
raise_cverror(e); raise_cverror(e);
} }
rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, col, self));
return DEPEND_OBJECT(rb_klass, submat, self);
}
/*
* call-seq:
* get_cols(col) -> cvmat
*
* Return column(or columns) of matrix.
* argument <tt>col</tt> should be Fixnum or Range object.
*/
VALUE
rb_get_cols(VALUE self, VALUE col)
{
int start, end;
rb_get_range_index(col, &start, &end);
CvMat* submat = RB_CVALLOC(CvMat);
try {
cvGetCols(CVARR(self), submat, start, end);
} }
return RARRAY_LEN(ary) > 1 ? ary : rb_ary_entry(ary, 0); catch (cv::Exception& e) {
cvFree(&submat);
raise_cverror(e);
}
return DEPEND_OBJECT(rb_klass, submat, self);
} }
/* /*

View file

@ -58,8 +58,8 @@ VALUE rb_square_q(VALUE self);
VALUE rb_to_CvMat(VALUE self); VALUE rb_to_CvMat(VALUE self);
VALUE rb_to_IplImage(VALUE self); VALUE rb_to_IplImage(VALUE self);
VALUE rb_sub_rect(VALUE self, VALUE args); VALUE rb_sub_rect(VALUE self, VALUE args);
VALUE rb_get_rows(VALUE self, VALUE args); VALUE rb_get_rows(int argc, VALUE* argv, VALUE self);
VALUE rb_get_cols(VALUE self, VALUE args); VALUE rb_get_cols(VALUE self, VALUE col);
VALUE rb_each_row(VALUE self); VALUE rb_each_row(VALUE self);
VALUE rb_each_col(VALUE self); VALUE rb_each_col(VALUE self);
VALUE rb_diag(int argc, VALUE *argv, VALUE self); VALUE rb_diag(int argc, VALUE *argv, VALUE self);

View file

@ -439,48 +439,77 @@ class TestCvMat < OpenCVTestCase
end end
def test_get_rows def test_get_rows
m1 = create_cvmat(10, 20) m1 = create_cvmat(10, 20) { |j, i, c| CvScalar.new(c) }
m2 = m1.get_rows(2) row = 2
assert_equal(1, m2.height) m2 = m1.get_rows(row)
assert_equal(m1.width, m2.width) assert_equal(1, m2.rows)
m1.width.times { |i| assert_equal(m1.cols, m2.cols)
assert_cvscalar_equal(m1[2, i], m2[i]) m1.cols.times { |i|
assert_cvscalar_equal(m1[row, i], m2[i])
} }
m2, m3 = m1.get_rows(1, 2) row1 = 3..7
[m2, m3].each { |m| row2 = 2...8
assert_equal(1, m.height) [row1, row2].each { |row|
assert_equal(m1.width, m.width) m3 = m1.get_rows(row)
w = (row.exclude_end?) ? row.last - row.begin : row.last - row.begin + 1
assert_equal(w, m3.rows)
assert_equal(m1.cols, m3.cols)
m3.rows.times { |j|
m3.cols.times { |i|
assert_cvscalar_equal(m1[row.begin + j, i], m3[j, i])
}
}
}
[row1, row2].each { |row|
delta = 2
m3 = m1.get_rows(row, 2)
w = (((row.exclude_end?) ? row.last - row.begin : row.last - row.begin + 1).to_f / delta).ceil
assert_equal(w, m3.rows)
assert_equal(m1.cols, m3.cols)
m3.rows.times { |j|
m3.cols.times { |i|
assert_cvscalar_equal(m1[row.begin + j * delta, i], m3[j, i])
}
} }
m1.width.times { |i|
assert_cvscalar_equal(m1[1, i], m2[i])
assert_cvscalar_equal(m1[2, i], m3[i])
} }
assert_raise(TypeError) { assert_raise(TypeError) {
m1.get_rows(DUMMY_OBJ) m1.get_rows(DUMMY_OBJ)
} }
assert_raise(TypeError) {
m1.get_rows(1, DUMMY_OBJ)
}
end end
def test_get_cols def test_get_cols
m1 = create_cvmat(10, 20) m1 = create_cvmat(10, 20) { |j, i, c| CvScalar.new(c) }
m2 = m1.get_cols(2) col = 2
assert_equal(1, m2.width) m2 = m1.get_cols(col)
assert_equal(m1.height, m2.height) assert_equal(m1.rows, m2.rows)
assert_equal(1, m2.cols)
m1.height.times { |j| m1.height.times { |j|
assert_cvscalar_equal(m1[j, 2], m2[j]) assert_cvscalar_equal(m1[j, col], m2[j])
} }
m2, m3 = m1.get_cols(1, 2) col1 = 3..7
[m2, m3].each { |m| col2 = 2...8
assert_equal(1, m.width) [col1, col2].each { |col|
assert_equal(m1.height, m.height) m3 = m1.get_cols(col)
w = (col.exclude_end?) ? col.last - col.begin : col.last - col.begin + 1
assert_equal(m1.rows, m3.rows)
assert_equal(w, m3.cols)
m3.rows.times { |j|
m3.cols.times { |i|
assert_cvscalar_equal(m1[j, col.begin + i], m3[j, i])
}
} }
m1.height.times { |j|
assert_cvscalar_equal(m1[j, 1], m2[j])
assert_cvscalar_equal(m1[j, 2], m3[j])
} }
assert_raise(TypeError) { assert_raise(TypeError) {