diff --git a/ext/opencv/mouseevent.cpp b/ext/opencv/mouseevent.cpp index 1519003..ea57f9e 100644 --- a/ext/opencv/mouseevent.cpp +++ b/ext/opencv/mouseevent.cpp @@ -117,7 +117,7 @@ VALUE rb_event(VALUE self) VALUE rb_left_button_q(VALUE self) { - return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_LBUTTON ? Qtrue : Qfalse; + return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_LBUTTON ? Qtrue : Qfalse; } /* @@ -126,7 +126,7 @@ rb_left_button_q(VALUE self) VALUE rb_right_button_q(VALUE self) { - return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_RBUTTON ? Qtrue : Qfalse; + return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_RBUTTON ? Qtrue : Qfalse; } /* @@ -135,7 +135,7 @@ rb_right_button_q(VALUE self) VALUE rb_middle_button_q(VALUE self) { - return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_MBUTTON ? Qtrue : Qfalse; + return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_MBUTTON ? Qtrue : Qfalse; } /* @@ -144,7 +144,7 @@ rb_middle_button_q(VALUE self) VALUE rb_ctrl_key_q(VALUE self) { - return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_CTRLKEY ? Qtrue : Qfalse; + return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_CTRLKEY ? Qtrue : Qfalse; } /* @@ -153,7 +153,7 @@ rb_ctrl_key_q(VALUE self) VALUE rb_shift_key_q(VALUE self) { - return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_SHIFTKEY ? Qtrue : Qfalse; + return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_SHIFTKEY ? Qtrue : Qfalse; } /* @@ -162,18 +162,18 @@ rb_shift_key_q(VALUE self) VALUE rb_alt_key_q(VALUE self) { - return MOUSEEVENT(self)->flag & CV_EVENT_FLAG_ALTKEY ? Qtrue : Qfalse; + return MOUSEEVENT(self)->flags & CV_EVENT_FLAG_ALTKEY ? Qtrue : Qfalse; } VALUE -new_object(int flag, int y, int x, int event) +new_object(int event, int x, int y, int flags) { VALUE object = rb_allocate(rb_class()); MouseEvent *mouseevent = MOUSEEVENT(object); mouseevent->point.x = x; mouseevent->point.y = y; mouseevent->event = event; - mouseevent->flag = flag; + mouseevent->flags = flags; return object; } diff --git a/ext/opencv/mouseevent.h b/ext/opencv/mouseevent.h index fc532c7..260cba5 100644 --- a/ext/opencv/mouseevent.h +++ b/ext/opencv/mouseevent.h @@ -24,7 +24,7 @@ __NAMESPACE_BEGIN_MOUSEEVENT typedef struct MouseEvent { CvPoint point; int event; - int flag; + int flags; } MouseEvent; VALUE rb_class(); diff --git a/ext/opencv/opencv.cpp b/ext/opencv/opencv.cpp index baad070..37d2489 100644 --- a/ext/opencv/opencv.cpp +++ b/ext/opencv/opencv.cpp @@ -409,6 +409,9 @@ define_ruby_module() rb_define_const(rb_module, "CV_FM_8POINT", INT2FIX(CV_FM_8POINT)); rb_define_const(rb_module, "CV_FM_RANSAC", INT2FIX(CV_FM_RANSAC)); rb_define_const(rb_module, "CV_FM_LMEDS", INT2FIX(CV_FM_LMEDS)); + + /* Flags of window */ + rb_define_const(rb_module, "CV_WINDOW_AUTOSIZE", INT2FIX(CV_WINDOW_AUTOSIZE)); VALUE inversion_method = rb_hash_new(); /* {:lu, :svd, :svd_sym(:svd_symmetric)}: Inversion method */ diff --git a/ext/opencv/window.cpp b/ext/opencv/window.cpp index cff0ae8..115b73c 100644 --- a/ext/opencv/window.cpp +++ b/ext/opencv/window.cpp @@ -30,8 +30,7 @@ GET_WINDOW_NAME(VALUE object) void *handle = DATA_PTR(object); if (!handle) rb_raise(rb_eStandardError, "window handle error"); - const char *window_name = cvGetWindowName(handle); - return window_name; + return (const char*)cvGetWindowName(handle); } st_table *windows = st_init_numtable(); @@ -64,10 +63,10 @@ define_ruby_class() rb_define_singleton_method(rb_klass, "destroy_all", RUBY_METHOD_FUNC(rb_destroy_all), 0); rb_define_method(rb_klass, "resize", RUBY_METHOD_FUNC(rb_resize), -1); rb_define_method(rb_klass, "move", RUBY_METHOD_FUNC(rb_move), -1); - rb_define_method(rb_klass, "show_image", RUBY_METHOD_FUNC(rb_show_image), 1); + rb_define_method(rb_klass, "show_image", RUBY_METHOD_FUNC(rb_show_image), -1); rb_define_alias(rb_klass, "show", "show_image"); rb_define_method(rb_klass, "set_trackbar", RUBY_METHOD_FUNC(rb_set_trackbar), -1); - rb_define_method(rb_klass, "set_mouse_callback", RUBY_METHOD_FUNC(rb_set_mouse_callback), 0); + rb_define_method(rb_klass, "set_mouse_callback", RUBY_METHOD_FUNC(rb_set_mouse_callback), -1); rb_define_alias(rb_klass, "on_mouse", "set_mouse_callback"); } @@ -121,34 +120,26 @@ rb_aref(VALUE klass, VALUE name) /* * call-seq: - * new(name[,autosize]) + * new(name[,flags]) * * Create new window named name. - * If autoresize is true(default), window size automatically resize when image given. + * If flags is CV_WINDOW_AUTOSIZE (default), window size automatically resize when image given. */ VALUE rb_initialize(int argc, VALUE *argv, VALUE self) { - VALUE name, autosize; - rb_scan_args(argc, argv, "11", &name, &autosize); + VALUE name, flags; + rb_scan_args(argc, argv, "11", &name, &flags); Check_Type(name, T_STRING); - int mode; - if (argc < 2) - mode = CV_WINDOW_AUTOSIZE; - else{ - switch (TYPE(autosize)) { - case T_TRUE: - mode = CV_WINDOW_AUTOSIZE; - break; - case T_FALSE: - mode = 0; - break; - default: - rb_raise(rb_eTypeError, "argument 2 (auto-size) should be true or false."); - } + int mode = CV_WINDOW_AUTOSIZE; + if (argc == 2) { + Check_Type(flags, T_FIXNUM); + mode = FIX2INT(flags); } - cvNamedWindow(StringValueCStr(name), mode); - void *handle = cvGetWindowHandle(StringValueCStr(name)); + + char* name_str = StringValueCStr(name); + cvNamedWindow(name_str, mode); + void *handle = cvGetWindowHandle(name_str); if (st_lookup(windows, (st_data_t)handle, 0)) { rb_raise(rb_eStandardError, "window name should be unique."); } @@ -217,7 +208,8 @@ rb_resize(int argc, VALUE *argv, VALUE self) size = cvSize(FIX2INT(argv[0]), FIX2INT(argv[1])); break; default: - rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)"); + rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)"); + break; } cvResizeWindow(GET_WINDOW_NAME(self), size.width, size.height); return self; @@ -242,7 +234,8 @@ rb_move(int argc, VALUE *argv, VALUE self) point = cvPoint(FIX2INT(argv[0]), FIX2INT(argv[1])); break; default: - rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)"); + rb_raise(rb_eArgError, "wrong number of arguments (1 or 2)"); + break; } cvMoveWindow(GET_WINDOW_NAME(self), point.x, point.y); return self; @@ -252,22 +245,27 @@ rb_move(int argc, VALUE *argv, VALUE self) * call-seq: * show_image(image) * - * Show the image. If the window was created with autosize = true then the image is shown + * Show the image. If the window was created with flags = CV_WINDOW_AUTOSIZE then the image is shown * with its original size, otherwize the image is scaled to fit the window. */ VALUE -rb_show_image(VALUE self, VALUE image) +rb_show_image(int argc, VALUE *argv, VALUE self) { - if (!rb_obj_is_kind_of(image, cCvMat::rb_class())) { - rb_raise(rb_eTypeError, "argument should be %s.", rb_class2name(cCvMat::rb_class())); + CvArr* image = NULL; + if (argc > 0) { + if (!rb_obj_is_kind_of(argv[0], cCvMat::rb_class())) + rb_raise(rb_eTypeError, "argument should be %s.", rb_class2name(cCvMat::rb_class())); + else + image = CVARR(argv[0]); + + st_table *holder; + if (st_lookup(windows, (st_data_t)DATA_PTR(self), (st_data_t*)&holder)) { + st_insert(holder, cCvMat::rb_class(), argv[0]); + }else + rb_raise(rb_eFatal, "invalid window operation."); } - cvShowImage(GET_WINDOW_NAME(self), CVARR(image)); - st_table *holder; - if (st_lookup(windows, (st_data_t)DATA_PTR(self), (st_data_t*)&holder)) { - st_insert(holder, cCvMat::rb_class(), image); - return self; - }else - rb_raise(rb_eFatal, "invalid window operation."); + cvShowImage(GET_WINDOW_NAME(self), image); + return self; } @@ -291,7 +289,8 @@ rb_set_trackbar(int argc, VALUE *argv, VALUE self) } Trackbar *trackbar = TRACKBAR(instance); void *callback = (void *)alloc_callback(&trackbar_callback, trackbar->block); - cvCreateTrackbar(trackbar->name, GET_WINDOW_NAME(self), &trackbar->val, trackbar->maxval, (CvTrackbarCallback)callback); + cvCreateTrackbar(trackbar->name, GET_WINDOW_NAME(self), &(trackbar->val), trackbar->maxval, + (CvTrackbarCallback)callback); st_table *holder; if (st_lookup(windows, (st_data_t)DATA_PTR(self), (st_data_t*)&holder)) { st_insert(holder, (st_data_t)&trackbar->name, (st_data_t)instance); @@ -326,10 +325,13 @@ rb_set_trackbar(int argc, VALUE *argv, VALUE self) * OpenCV::GUI::wait_key */ VALUE -rb_set_mouse_callback(VALUE self) -{ - VALUE block = rb_block_given_p() ? rb_block_proc() : 0; - if (!block) {rb_raise(rb_eArgError, "block not given.");} +rb_set_mouse_callback(int argc, VALUE* argv, VALUE self) +{ + if (!rb_block_given_p()) + rb_raise(rb_eArgError, "block not given."); + + VALUE block = Qnil; + rb_scan_args(argc, argv, "0&", &block); void *callback = (void *)alloc_callback(&mouse_callback, block); cvSetMouseCallback(GET_WINDOW_NAME(self), (CvMouseCallback)callback); st_table *holder; @@ -353,11 +355,11 @@ void mouse_callback(VALUE block, va_alist ap) { va_start_void(ap); - //VALUE ary = rb_ary_new2(4); - //for (int i = 0; i < 4; i++) - // rb_ary_store(ary, i, INT2FIX(va_arg_int(ap))); - //rb_apply(block, rb_intern("call"), ary); - rb_funcall(block, rb_intern("call"), 1, cMouseEvent::new_object(va_arg_int(ap),va_arg_int(ap),va_arg_int(ap),va_arg_int(ap))); + int event = va_arg_int(ap); + int x = va_arg_int(ap); + int y = va_arg_int(ap); + int flags = va_arg_int(ap); + rb_funcall(block, rb_intern("call"), 1, cMouseEvent::new_object(event, x, y, flags)); va_return_void(ap); } diff --git a/ext/opencv/window.h b/ext/opencv/window.h index 6b72cbe..0883851 100644 --- a/ext/opencv/window.h +++ b/ext/opencv/window.h @@ -40,9 +40,9 @@ VALUE rb_destroy(VALUE self); VALUE rb_destroy_all(VALUE klass); VALUE rb_resize(int argc, VALUE *argv, VALUE self); VALUE rb_move(int argc, VALUE *argv, VALUE self); -VALUE rb_show_image(VALUE self, VALUE image); +VALUE rb_show_image(int argc, VALUE *argv, VALUE self); VALUE rb_set_trackbar(int argc, VALUE *argv, VALUE self); -VALUE rb_set_mouse_callback(VALUE self); +VALUE rb_set_mouse_callback(int argc, VALUE* argv, VALUE self); void trackbar_callback(VALUE block, va_alist ap); void mouse_callback(VALUE block, va_alist ap); diff --git a/extconf.rb b/extconf.rb index 9475459..4e22228 100755 --- a/extconf.rb +++ b/extconf.rb @@ -72,7 +72,7 @@ else end # Quick fix for 1.8.7 -$CFLAGS << "-I#{File.dirname(__FILE__)}/ext/opencv" +$CFLAGS << " -I#{File.dirname(__FILE__)}/ext/opencv" # step-final. create Makefile create_makefile("opencv", "./ext/opencv") diff --git a/test/test_opencv.rb b/test/test_opencv.rb index e936aa8..dedc80b 100755 --- a/test/test_opencv.rb +++ b/test/test_opencv.rb @@ -99,6 +99,9 @@ class TestOpenCV < OpenCVTestCase assert_equal(2, CV_FM_8POINT) assert_equal(8, CV_FM_RANSAC) assert_equal(4, CV_FM_LMEDS) + + # Flags of window + assert_equal(1, CV_WINDOW_AUTOSIZE) end def test_symbols diff --git a/test/test_window.rb b/test/test_window.rb new file mode 100755 index 0000000..38948b9 --- /dev/null +++ b/test/test_window.rb @@ -0,0 +1,115 @@ +#!/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 +include GUI + +# Tests for OpenCV::Window +class TestWindow < OpenCVTestCase + def setup + @window1 = Window.new('window1') + @window2 = Window.new('window2', CV_WINDOW_AUTOSIZE) + @window3 = Window.new('window3', 0) + end + + def teardown + Window::destroy_all + end + + def test_initialize + [Window.new('w1'), Window.new('w2', CV_WINDOW_AUTOSIZE), Window.new('w3', 0)].each { |w| + assert_not_nil(w) + assert_equal(Window, w.class) + } + + assert_raise(TypeError) { + Window.new('w4', 'foobar') + } + + assert_raise(StandardError) { + Window.new('w5') + Window.new('w5') + } + end + + def test_alive + assert(@window1.alive?) + @window1.destroy + assert(!(@window1.alive?)) + end + + def test_destroy + @window1.destroy + assert(!(@window1.alive?)) + end + + def test_destroy_all + Window::destroy_all + assert(!(@window1.alive?)) + assert(!(@window2.alive?)) + assert(!(@window3.alive?)) + end + + def test_resize + @window1.resize(CvSize.new(10, 20)) + @window2.resize(100, 200) + assert_raise(ArgumentError) { + @window3.resize + } + + # Uncomment the following lines to show the results + # @window1.show(CvMat.new(10, 20)) + # @window2.show(CvMat.new(100, 200)) + # GUI::wait_key + end + + def test_move + @window1.move(CvPoint.new(10, 20)) + @window2.move(100, 200) + assert_raise(ArgumentError) { + @window3.move + } + + # Uncomment the following lines to show the results + # @window1.show(CvMat.new(10, 20)) + # @window2.show(CvMat.new(100, 200)) + # GUI::wait_key + end + + def test_show_image + img = IplImage.load(FILENAME_CAT, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR) + @window1.show_image(img) + @window2.show # Alias + + # Uncomment the following lines to show the results + # GUI::wait_key + end + + def test_set_trackbar + tr1 = @window1.set_trackbar('trackbar1', 100) { |value| + puts value + } + assert_equal(Trackbar, tr1.class) + + trackbar2 = Trackbar.new('trackbar2', 10, 1) {} + tr2 = @window2.set_trackbar(trackbar2) + assert_equal(Trackbar, tr2.class) + end + + def test_set_mouseevent + @window1.set_mouse_callback { |mouse| + e = "#{mouse.x}, #{mouse.y} : #{mouse.event} : " + e << "" if mouse.left_button? + e << "" if mouse.right_button? + e << "" if mouse.middle_button? + e << "[CTRL]" if mouse.ctrl_key? + e << "[SHIFT]" if mouse.shift_key? + e << "[ALT]" if mouse.alt_key? + puts e + } + end +end +