diff --git a/ext/iplconvkernel.cpp b/ext/iplconvkernel.cpp index b0a1054..3b20351 100644 --- a/ext/iplconvkernel.cpp +++ b/ext/iplconvkernel.cpp @@ -56,19 +56,14 @@ define_ruby_class() VALUE rb_allocate(VALUE klass) { - return OPENCV_OBJECT(klass, 0); + return IPLCONVKERNEL_OBJECT(klass, 0); } /* * call-seq: - * IplConvKernel.new(shape, rows, cols, anchor_x, anchor_y) + * IplConvKernel.new(cols, rows, anchor_x, anchor_y, shape [,values = nil]) * * Creates structuring element. - * shape - * Shape of the structuring element; may have the following values: - * :rect - * :cross - * :ellipse * cols * Number of columns in the structuring element. * rows @@ -77,25 +72,45 @@ rb_allocate(VALUE klass) * Relative horizontal offset of the anchor point. * anchor_y * Relative vertical offset of the anchor point. + * shape + * Shape of the structuring element; may have the following values: + * :rect + * :cross + * :ellipse + * :custom * */ VALUE rb_initialize(int argc, VALUE *argv, VALUE self) { - VALUE shape, rows, cols, anchor_x, anchor_y; - rb_scan_args(argc, argv, "50", &shape, &rows, &cols, &anchor_x, &anchor_y); + VALUE shape, rows, cols, anchor_x, anchor_y, values; + rb_scan_args(argc, argv, "51", &cols, &rows, &anchor_x, &anchor_y, &shape, &values); Check_Type(shape, T_SYMBOL); const char *shape_name = rb_id2name(SYM2ID(shape)); int shape_type = 0; + int _cols = NUM2INT(cols); + int _rows = NUM2INT(rows); + int num_values; + int *_values; if (!strcmp(shape_name, "rect")) shape_type = CV_SHAPE_RECT; - else if (!strcmp(shape_name, "corss")) + else if (!strcmp(shape_name, "cross")) shape_type = CV_SHAPE_CROSS; else if (!strcmp(shape_name, "ellipse")) shape_type = CV_SHAPE_ELLIPSE; + else if (!strcmp(shape_name, "custom")) { + if (NIL_P(values)) + rb_raise(rb_eArgError, "argument 6 (values) should not be nil when the shape is :custom."); + shape_type = CV_SHAPE_CUSTOM; + num_values = RARRAY_LEN(values); + _values = ALLOCA_N(int, num_values); + VALUE *values_ptr = RARRAY_PTR(values); + for (int i = 0; i < num_values; i++) + _values[i] = NUM2INT(values_ptr[i]); + } else - rb_raise(rb_eTypeError, "argument 1 (shape) should be :rect or :cross or :ellipse."); - DATA_PTR(self) = cvCreateStructuringElementEx(NUM2INT(cols), NUM2INT(rows), NUM2INT(anchor_x), NUM2INT(anchor_y), shape_type); + rb_raise(rb_eTypeError, "argument 1 (shape) should be :rect or :cross or :ellipse or :custom."); + DATA_PTR(self) = cvCreateStructuringElementEx(_cols, _rows, NUM2INT(anchor_x), NUM2INT(anchor_y), shape_type, _values); return self; } diff --git a/ext/opencv.cpp b/ext/opencv.cpp index a0cd607..6ec0eef 100644 --- a/ext/opencv.cpp +++ b/ext/opencv.cpp @@ -117,6 +117,18 @@ release_object(void *ptr) } } +/* + * Release IplConvKernel object from memory and delete from hashtable. + */ +void +release_iplconvkernel_object(void *ptr) +{ + if(ptr){ + unresist_object(ptr); + cvReleaseStructuringElement((IplConvKernel**)(&ptr)); + } +} + VALUE rb_module; VALUE rb_opencv_constants; diff --git a/ext/opencv.h b/ext/opencv.h index 3de053a..0d6f907 100644 --- a/ext/opencv.h +++ b/ext/opencv.h @@ -175,6 +175,7 @@ void resist_root_object(void *ptr, VALUE root); void unresist_object(void *ptr); void free_object(void *ptr); void release_object(void *ptr); +void release_iplconvkernel_object(void *ptr); VALUE rb_module_opencv(); void define_ruby_module(); @@ -194,6 +195,12 @@ OPENCV_OBJECT(VALUE klass, void *ptr) return Data_Wrap_Struct(klass, 0, release_object, ptr); } +inline VALUE +IPLCONVKERNEL_OBJECT(VALUE klass, void *ptr) +{ + return Data_Wrap_Struct(klass, 0, release_iplconvkernel_object, ptr); +} + inline VALUE GENERIC_OBJECT(VALUE klass, void *ptr) { diff --git a/test/test_iplconvkernel.rb b/test/test_iplconvkernel.rb new file mode 100755 index 0000000..3d7c63e --- /dev/null +++ b/test/test_iplconvkernel.rb @@ -0,0 +1,52 @@ +#!/usr/bin/env ruby +# -*- mode: ruby; coding: utf-8-unix -*- +require 'test/unit' +require 'opencv' +require File.expand_path(File.dirname(__FILE__)) + '/helper' + +include OpenCV + +# Tests for OpenCV::IplConvKernel +class TestIplConvKernel < OpenCVTestCase + def test_initialize + [:rect, :cross, :ellipse].each { |sym| + kernel = IplConvKernel.new(5, 5, 2, 2, sym) + assert_not_nil(kernel) + } + + values = [1] * 25 + kernel = IplConvKernel.new(5, 5, 2, 2, :custom, values) + assert_not_nil(kernel) + + assert_raise(ArgumentError) { + IplConvKernel.new(5, 5, 2, 2, :custom) + } + + assert_raise(TypeError) { + IplConvKernel.new(5, 5, 2, 2, :foobar) + } + end + + def test_size + kernel = IplConvKernel.new(5, 4, 2, 2, :rect) + size = kernel.size + assert_equal(5, size.width) + assert_equal(4, size.height) + + assert_equal(5, kernel.cols) + assert_equal(4, kernel.rows) + end + + def test_anchor + kernel = IplConvKernel.new(5, 4, 3, 2, :rect) + a = kernel.anchor + assert_equal(3, a.x) + assert_equal(2, a.y) + + assert_equal(3, kernel.anchor_x) + assert_equal(2, kernel.anchor_y) + end +end + + +