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

added CvMat#set_data

This commit is contained in:
ser1zw 2011-04-30 13:29:47 +09:00
parent 76ba4506ca
commit 579ba0299d
3 changed files with 89 additions and 0 deletions

View file

@ -205,6 +205,7 @@ void define_ruby_class()
rb_define_method(rb_klass, "[]", RUBY_METHOD_FUNC(rb_aref), -2);
rb_define_alias(rb_klass, "at", "[]");
rb_define_method(rb_klass, "[]=", RUBY_METHOD_FUNC(rb_aset), -2);
rb_define_method(rb_klass, "set_data", RUBY_METHOD_FUNC(rb_set_data), 1);
rb_define_method(rb_klass, "fill", RUBY_METHOD_FUNC(rb_fill), -1);
rb_define_alias(rb_klass, "set", "fill");
rb_define_method(rb_klass, "fill!", RUBY_METHOD_FUNC(rb_fill_bang), -1);
@ -1240,6 +1241,66 @@ rb_aset(VALUE self, VALUE args)
return self;
}
/*
* call-seq:
* set_data(<i>data</i>)
*
* Assigns user data to the array header.
* <i>data</i> should be Array which contains numbers.
*/
VALUE
rb_set_data(VALUE self, VALUE data)
{
data = rb_funcall(data, rb_intern("flatten"), 0);
const int DATA_LEN = RARRAY_LEN(data);
CvMat *self_ptr = CVMAT(self);
int depth = CV_MAT_DEPTH(self_ptr->type);
void* array = NULL;
switch (depth) {
case CV_8U:
array = rb_cvAlloc(sizeof(uchar) * DATA_LEN);
for (int i = 0; i < DATA_LEN; ++i)
((uchar*)array)[i] = (uchar)(NUM2INT(rb_ary_entry(data, i)));
break;
case CV_8S:
array = rb_cvAlloc(sizeof(char) * DATA_LEN);
for (int i = 0; i < DATA_LEN; ++i)
((char*)array)[i] = (char)(NUM2INT(rb_ary_entry(data, i)));
break;
case CV_16U:
array = rb_cvAlloc(sizeof(ushort) * DATA_LEN);
for (int i = 0; i < DATA_LEN; ++i)
((ushort*)array)[i] = (ushort)(NUM2INT(rb_ary_entry(data, i)));
break;
case CV_16S:
array = rb_cvAlloc(sizeof(short) * DATA_LEN);
for (int i = 0; i < DATA_LEN; ++i)
((short*)array)[i] = (short)(NUM2INT(rb_ary_entry(data, i)));
break;
case CV_32S:
array = rb_cvAlloc(sizeof(int) * DATA_LEN);
for (int i = 0; i < DATA_LEN; ++i)
((int*)array)[i] = NUM2INT(rb_ary_entry(data, i));
break;
case CV_32F:
array = rb_cvAlloc(sizeof(float) * DATA_LEN);
for (int i = 0; i < DATA_LEN; ++i)
((float*)array)[i] = (float)NUM2DBL(rb_ary_entry(data, i));
break;
case CV_64F:
array = rb_cvAlloc(sizeof(double) * DATA_LEN);
for (int i = 0; i < DATA_LEN; ++i)
((double*)array)[i] = NUM2DBL(rb_ary_entry(data, i));
break;
default:
rb_raise(rb_eTypeError, "Invalid CvMat depth");
}
cvSetData(self_ptr, array, self_ptr->step);
return self;
}
/*
* call-seq:
* fill(<i>value[, mask]</i>) -> cvmat

View file

@ -70,6 +70,7 @@ VALUE rb_dims(VALUE self);
VALUE rb_dim_size(VALUE self, VALUE index);
VALUE rb_aref(VALUE self, VALUE args);
VALUE rb_aset(VALUE self, VALUE args);
VALUE rb_set_data(VALUE self, VALUE data);
VALUE rb_fill(int argc, VALUE *argv, VALUE self);
VALUE rb_fill_bang(int argc, VALUE *argv, VALUE self);
VALUE rb_clear(VALUE self);

View file

@ -500,6 +500,33 @@ class TestCvMat < OpenCVTestCase
assert_cvscalar_equal(CvScalar.new(5, 5, 5, 5), m[1, 0])
end
def test_set_data
[CV_8U, CV_8S, CV_16U, CV_16S, CV_32S].each { |depth|
a = [10, 20, 30, 40, 50, 60]
m = CvMat.new(2, 3, depth, 1)
m.set_data(a)
(m.rows * m.cols).times { |i|
assert_equal(a[i], m[i][0])
}
}
[CV_32F, CV_64F].each { |depth|
a = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]
m = CvMat.new(2, 3, depth, 1)
m.set_data(a)
(m.rows * m.cols).times { |i|
assert_in_delta(a[i], m[i][0], 1.0e-5)
}
}
a = [[10, 20, 30], [40, 50, 60]]
m = CvMat.new(2, 3, CV_8U, 1)
m.set_data(a)
(m.rows * m.cols).times { |i|
assert_equal(a.flatten[i], m[i][0])
}
end
def test_fill
m1 = create_cvmat(2, 3)
m2 = m1.fill(CvScalar.new(1, 2, 3, 4))