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, "sub_rect", RUBY_METHOD_FUNC(rb_sub_rect), -2);
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_cols", RUBY_METHOD_FUNC(rb_get_cols), -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), 1);
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_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);
}
/*
* call-seq:
* get_rows(<i>n</i>) -> Return row
* get_rows(<i>n1, n2, ...</i>) -> Return Array of row
*
* Return row(or rows) of matrix.
* argument should be Fixnum or CvSlice compatible object.
*/
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 {
CvSlice slice = VALUE_TO_CVSLICE(value);
row = cvGetRows(CVARR(self), RB_CVALLOC(CvMat), slice.start_index, slice.end_index);
}
void
rb_get_range_index(VALUE index, int* start, int *end) {
if (rb_obj_is_kind_of(index, rb_cRange)) {
*start = NUM2INT(rb_funcall3(index, rb_intern("begin"), 0, NULL));
*end = NUM2INT(rb_funcall3(index, rb_intern("end"), 0, NULL));
if (rb_funcall3(index, rb_intern("exclude_end?"), 0, NULL) == Qfalse) {
(*end)++;
}
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);
else {
*start = NUM2INT(index);
*end = *start + 1;
}
}
/*
* call-seq:
* get_cols(<i>n</i>) -> Return column
* get_cols(<i>n1, n2, ...</i>) -> Return Array of columns
* get_rows(row, delta_row = 1) -> cvmat
*
* Return column(or columns) of matrix.
* argument should be Fixnum or CvSlice compatible object.
* Return row(or rows) of matrix.
* argument <tt>row</tt> should be Fixnum or Range object.
*/
VALUE
rb_get_cols(VALUE self, VALUE args)
rb_get_rows(int argc, VALUE* argv, VALUE self)
{
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* col = NULL;
try {
if (FIXNUM_P(value))
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) {
if (col != NULL)
cvReleaseMat(&col);
raise_cverror(e);
}
rb_ary_store(ary, i, DEPEND_OBJECT(rb_klass, col, self));
VALUE row_val, delta_val;
rb_scan_args(argc, argv, "11", &row_val, &delta_val);
int start, end;
rb_get_range_index(row_val, &start, &end);
int delta = NIL_P(delta_val) ? 1 : NUM2INT(delta_val);
CvMat* submat = RB_CVALLOC(CvMat);
try {
cvGetRows(CVARR(self), submat, start, end, delta);
}
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);
}
/*
* 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);
}
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_IplImage(VALUE self);
VALUE rb_sub_rect(VALUE self, VALUE args);
VALUE rb_get_rows(VALUE self, VALUE args);
VALUE rb_get_cols(VALUE self, VALUE args);
VALUE rb_get_rows(int argc, VALUE* argv, VALUE self);
VALUE rb_get_cols(VALUE self, VALUE col);
VALUE rb_each_row(VALUE self);
VALUE rb_each_col(VALUE self);
VALUE rb_diag(int argc, VALUE *argv, VALUE self);

View file

@ -439,48 +439,77 @@ class TestCvMat < OpenCVTestCase
end
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)
assert_equal(1, m2.height)
assert_equal(m1.width, m2.width)
m1.width.times { |i|
assert_cvscalar_equal(m1[2, i], m2[i])
row = 2
m2 = m1.get_rows(row)
assert_equal(1, m2.rows)
assert_equal(m1.cols, m2.cols)
m1.cols.times { |i|
assert_cvscalar_equal(m1[row, i], m2[i])
}
m2, m3 = m1.get_rows(1, 2)
[m2, m3].each { |m|
assert_equal(1, m.height)
assert_equal(m1.width, m.width)
row1 = 3..7
row2 = 2...8
[row1, row2].each { |row|
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])
}
}
}
m1.width.times { |i|
assert_cvscalar_equal(m1[1, i], m2[i])
assert_cvscalar_equal(m1[2, i], m3[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])
}
}
}
assert_raise(TypeError) {
m1.get_rows(DUMMY_OBJ)
}
assert_raise(TypeError) {
m1.get_rows(1, DUMMY_OBJ)
}
end
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)
assert_equal(1, m2.width)
assert_equal(m1.height, m2.height)
col = 2
m2 = m1.get_cols(col)
assert_equal(m1.rows, m2.rows)
assert_equal(1, m2.cols)
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)
[m2, m3].each { |m|
assert_equal(1, m.width)
assert_equal(m1.height, m.height)
}
m1.height.times { |j|
assert_cvscalar_equal(m1[j, 1], m2[j])
assert_cvscalar_equal(m1[j, 2], m3[j])
col1 = 3..7
col2 = 2...8
[col1, col2].each { |col|
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])
}
}
}
assert_raise(TypeError) {