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

add array concatenatation functions

This commit is contained in:
ser1zw 2016-05-05 08:15:00 +09:00
parent 7ea42d40d3
commit 88ebe4b591
4 changed files with 119 additions and 1 deletions

View file

@ -1080,6 +1080,31 @@ namespace rubyopencv {
return result;
}
VALUE rb_merge_array_internal(VALUE self, VALUE src,
void (*merge_func)(cv::InputArrayOfArrays, cv::OutputArray)) {
Check_Type(src, T_ARRAY);
const long size = RARRAY_LEN(src);
std::vector<cv::Mat> matrixes;
for (long i = 0; i < size; i++) {
VALUE elt = RARRAY_AREF(src, i);
cv::Mat* tmp = obj2mat(elt);
matrixes.push_back(*tmp);
}
cv::Mat* dstptr = NULL;
try {
dstptr = new cv::Mat();
merge_func(matrixes, *dstptr);
}
catch (cv::Exception& e) {
delete dstptr;
Error::raise(e);
}
return mat2obj(dstptr);
}
/*
* Creates one multi-channel array out of several single-channel ones.
* The function merge merges several arrays to make a single multi-channel array.
@ -1114,6 +1139,34 @@ namespace rubyopencv {
return mat2obj(dstptr);
}
/*
* Applies horizontal concatenation to given matrices.
* The function horizontally concatenates two or more <tt>Cv::Mat</tt> matrices (with the same number of rows).
*
* @overload hconcat(src)
* @param src [Array<Mat>] Input array of matrices. all of the matrices must have the same number of rows and the same depth.
* @return [Mat] Output array
* @!scope class
* @opencv_func cv::hconcat
*/
VALUE rb_hconcat(VALUE self, VALUE src) {
return rb_merge_array_internal(self, src, &cv::hconcat);
}
/*
* Applies vertical concatenation to given matrices.
* The function vertically concatenates two or more <tt>cv::Mat</tt> matrices (with the same number of cols).
*
* @overload vconcat(src)
* @param src [Array<Mat>] Input array of matrices. all of the matrices must have the same number of rows and the same depth.
* @return [Mat] Output array
* @!scope class
* @opencv_func cv::vconcat
*/
VALUE rb_vconcat(VALUE self, VALUE src) {
return rb_merge_array_internal(self, src, &cv::vconcat);
}
void init() {
VALUE opencv = rb_define_module("Cv");

View file

@ -15,6 +15,8 @@ namespace rubyopencv {
VALUE rb_clone(VALUE self);
VALUE rb_add_weighted(int argc, VALUE *argv, VALUE self);
VALUE rb_merge(VALUE self, VALUE mv);
VALUE rb_hconcat(VALUE self, VALUE src);
VALUE rb_vconcat(VALUE self, VALUE src);
cv::Mat* obj2mat(VALUE obj);
VALUE mat2obj(cv::Mat* ptr);

View file

@ -106,6 +106,8 @@ namespace rubyopencv {
rb_define_singleton_method(rb_module, "add_weighted", RUBY_METHOD_FUNC(Mat::rb_add_weighted), -1); // in ext/opencv/mat.cpp
rb_define_singleton_method(rb_module, "merge", RUBY_METHOD_FUNC(Mat::rb_merge), 1); // in ext/opencv/mat.cpp
rb_define_singleton_method(rb_module, "hconcat", RUBY_METHOD_FUNC(Mat::rb_hconcat), 1); // in ext/opencv/mat.cpp
rb_define_singleton_method(rb_module, "vconcat", RUBY_METHOD_FUNC(Mat::rb_vconcat), 1); // in ext/opencv/mat.cpp
rb_define_singleton_method(rb_module, "CV_MAKETYPE", RUBY_METHOD_FUNC(rb_maketype), 2);

View file

@ -64,5 +64,66 @@ class TestOpenCV < OpenCVTestCase
# w.show(m)
# w.wait_key
end
end
def test_hconcat
m1 = Mat::ones(2, 2, CV_8U) + 1
m2 = Mat::ones(2, 2, CV_8U) + 2
m = Cv::hconcat([m1, m2]);
assert_equal(m1.class, m1.class)
assert_equal(m1.rows, m.rows)
assert_equal(m1.cols + m2.cols, m.cols)
assert_equal(m1.depth, m.depth)
assert_equal(m1.channels, m.channels)
m1.rows.times { |r|
(m1.cols + m2.cols).times { |c|
expected = (c < m1.cols) ? m1[r, c][0] : m2[r, c - m1.cols][0]
assert_equal(expected, m[r, c][0])
}
}
assert_raise(TypeError) {
Cv::hconcat(DUMMY_OBJ)
}
assert_raise(TypeError) {
Cv::hconcat([DUMMY_OBJ])
}
# img = Cv::imread(FILENAME_LENA256x256, -1)
# dst = Cv::hconcat([img, img])
# Cv::Window.new('hconcat').show(dst)
# Cv::wait_key
end
def test_vconcat
m1 = Mat::ones(2, 2, CV_8U) + 1
m2 = Mat::ones(2, 2, CV_8U) + 2
m = Cv::vconcat([m1, m2]);
assert_equal(m1.class, m1.class)
assert_equal(m1.rows + m2.rows, m.rows)
assert_equal(m1.cols, m.cols)
assert_equal(m1.depth, m.depth)
assert_equal(m1.channels, m.channels)
(m1.rows + m2.rows).times { |r|
m1.cols.times { |c|
expected = (r < m1.rows) ? m1[r, c][0] : m2[r - m1.rows, c][0]
assert_equal(expected, m[r, c][0])
}
}
assert_raise(TypeError) {
Cv::vconcat(DUMMY_OBJ)
}
assert_raise(TypeError) {
Cv::vconcat([DUMMY_OBJ])
}
# img = Cv::imread(FILENAME_LENA256x256, -1)
# dst = Cv::vconcat([img, img])
# Cv::Window.new('vconcat').show(dst)
# Cv::wait_key
end
end