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

fixed Window to handle MouseEvent with propriety

This commit is contained in:
ser1zw 2011-05-05 04:24:21 +09:00
parent 6be99de63c
commit 81714f0768
8 changed files with 182 additions and 59 deletions

View file

@ -117,7 +117,7 @@ VALUE rb_event(VALUE self)
VALUE VALUE
rb_left_button_q(VALUE self) 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 VALUE
rb_right_button_q(VALUE self) 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 VALUE
rb_middle_button_q(VALUE self) 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 VALUE
rb_ctrl_key_q(VALUE self) 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 VALUE
rb_shift_key_q(VALUE self) 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 VALUE
rb_alt_key_q(VALUE self) 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 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()); VALUE object = rb_allocate(rb_class());
MouseEvent *mouseevent = MOUSEEVENT(object); MouseEvent *mouseevent = MOUSEEVENT(object);
mouseevent->point.x = x; mouseevent->point.x = x;
mouseevent->point.y = y; mouseevent->point.y = y;
mouseevent->event = event; mouseevent->event = event;
mouseevent->flag = flag; mouseevent->flags = flags;
return object; return object;
} }

View file

@ -24,7 +24,7 @@ __NAMESPACE_BEGIN_MOUSEEVENT
typedef struct MouseEvent { typedef struct MouseEvent {
CvPoint point; CvPoint point;
int event; int event;
int flag; int flags;
} MouseEvent; } MouseEvent;
VALUE rb_class(); VALUE rb_class();

View file

@ -410,6 +410,9 @@ define_ruby_module()
rb_define_const(rb_module, "CV_FM_RANSAC", INT2FIX(CV_FM_RANSAC)); rb_define_const(rb_module, "CV_FM_RANSAC", INT2FIX(CV_FM_RANSAC));
rb_define_const(rb_module, "CV_FM_LMEDS", INT2FIX(CV_FM_LMEDS)); 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(); VALUE inversion_method = rb_hash_new();
/* {:lu, :svd, :svd_sym(:svd_symmetric)}: Inversion method */ /* {:lu, :svd, :svd_sym(:svd_symmetric)}: Inversion method */
rb_define_const(rb_module, "INVERSION_METHOD", inversion_method); rb_define_const(rb_module, "INVERSION_METHOD", inversion_method);

View file

@ -30,8 +30,7 @@ GET_WINDOW_NAME(VALUE object)
void *handle = DATA_PTR(object); void *handle = DATA_PTR(object);
if (!handle) if (!handle)
rb_raise(rb_eStandardError, "window handle error"); rb_raise(rb_eStandardError, "window handle error");
const char *window_name = cvGetWindowName(handle); return (const char*)cvGetWindowName(handle);
return window_name;
} }
st_table *windows = st_init_numtable(); 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_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, "resize", RUBY_METHOD_FUNC(rb_resize), -1);
rb_define_method(rb_klass, "move", RUBY_METHOD_FUNC(rb_move), -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_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_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"); rb_define_alias(rb_klass, "on_mouse", "set_mouse_callback");
} }
@ -121,34 +120,26 @@ rb_aref(VALUE klass, VALUE name)
/* /*
* call-seq: * call-seq:
* new(<i>name[,autosize]</i>) * new(<i>name[,flags]</i>)
* *
* Create new window named <i>name</i>. * Create new window named <i>name</i>.
* If <i>autoresize</i> is true(default), window size automatically resize when image given. * If <i>flags</i> is CV_WINDOW_AUTOSIZE (default), window size automatically resize when image given.
*/ */
VALUE VALUE
rb_initialize(int argc, VALUE *argv, VALUE self) rb_initialize(int argc, VALUE *argv, VALUE self)
{ {
VALUE name, autosize; VALUE name, flags;
rb_scan_args(argc, argv, "11", &name, &autosize); rb_scan_args(argc, argv, "11", &name, &flags);
Check_Type(name, T_STRING); Check_Type(name, T_STRING);
int mode; int mode = CV_WINDOW_AUTOSIZE;
if (argc < 2) if (argc == 2) {
mode = CV_WINDOW_AUTOSIZE; Check_Type(flags, T_FIXNUM);
else{ mode = FIX2INT(flags);
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.");
} }
}
cvNamedWindow(StringValueCStr(name), mode); char* name_str = StringValueCStr(name);
void *handle = cvGetWindowHandle(StringValueCStr(name)); cvNamedWindow(name_str, mode);
void *handle = cvGetWindowHandle(name_str);
if (st_lookup(windows, (st_data_t)handle, 0)) { if (st_lookup(windows, (st_data_t)handle, 0)) {
rb_raise(rb_eStandardError, "window name should be unique."); rb_raise(rb_eStandardError, "window name should be unique.");
} }
@ -218,6 +209,7 @@ rb_resize(int argc, VALUE *argv, VALUE self)
break; break;
default: 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); cvResizeWindow(GET_WINDOW_NAME(self), size.width, size.height);
return self; return self;
@ -243,6 +235,7 @@ rb_move(int argc, VALUE *argv, VALUE self)
break; break;
default: 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); cvMoveWindow(GET_WINDOW_NAME(self), point.x, point.y);
return self; return self;
@ -252,22 +245,27 @@ rb_move(int argc, VALUE *argv, VALUE self)
* call-seq: * call-seq:
* show_image(<i>image</i>) * show_image(<i>image</i>)
* *
* Show the image. If the window was created with <i>autosize</i> = true then the image is shown * Show the image. If the window was created with <i>flags</i> = CV_WINDOW_AUTOSIZE then the image is shown
* with its original size, otherwize the image is scaled to fit the window. * with its original size, otherwize the image is scaled to fit the window.
*/ */
VALUE 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())) { 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())); rb_raise(rb_eTypeError, "argument should be %s.", rb_class2name(cCvMat::rb_class()));
} else
cvShowImage(GET_WINDOW_NAME(self), CVARR(image)); image = CVARR(argv[0]);
st_table *holder; st_table *holder;
if (st_lookup(windows, (st_data_t)DATA_PTR(self), (st_data_t*)&holder)) { if (st_lookup(windows, (st_data_t)DATA_PTR(self), (st_data_t*)&holder)) {
st_insert(holder, cCvMat::rb_class(), image); st_insert(holder, cCvMat::rb_class(), argv[0]);
return self;
}else }else
rb_raise(rb_eFatal, "invalid window operation."); rb_raise(rb_eFatal, "invalid window operation.");
}
cvShowImage(GET_WINDOW_NAME(self), image);
return self; return self;
} }
@ -291,7 +289,8 @@ rb_set_trackbar(int argc, VALUE *argv, VALUE self)
} }
Trackbar *trackbar = TRACKBAR(instance); Trackbar *trackbar = TRACKBAR(instance);
void *callback = (void *)alloc_callback(&trackbar_callback, trackbar->block); 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; st_table *holder;
if (st_lookup(windows, (st_data_t)DATA_PTR(self), (st_data_t*)&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); 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 * OpenCV::GUI::wait_key
*/ */
VALUE VALUE
rb_set_mouse_callback(VALUE self) rb_set_mouse_callback(int argc, VALUE* argv, VALUE self)
{ {
VALUE block = rb_block_given_p() ? rb_block_proc() : 0; if (!rb_block_given_p())
if (!block) {rb_raise(rb_eArgError, "block not given.");} 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); void *callback = (void *)alloc_callback(&mouse_callback, block);
cvSetMouseCallback(GET_WINDOW_NAME(self), (CvMouseCallback)callback); cvSetMouseCallback(GET_WINDOW_NAME(self), (CvMouseCallback)callback);
st_table *holder; st_table *holder;
@ -353,11 +355,11 @@ void
mouse_callback(VALUE block, va_alist ap) mouse_callback(VALUE block, va_alist ap)
{ {
va_start_void(ap); va_start_void(ap);
//VALUE ary = rb_ary_new2(4); int event = va_arg_int(ap);
//for (int i = 0; i < 4; i++) int x = va_arg_int(ap);
// rb_ary_store(ary, i, INT2FIX(va_arg_int(ap))); int y = va_arg_int(ap);
//rb_apply(block, rb_intern("call"), ary); int flags = va_arg_int(ap);
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))); rb_funcall(block, rb_intern("call"), 1, cMouseEvent::new_object(event, x, y, flags));
va_return_void(ap); va_return_void(ap);
} }

View file

@ -40,9 +40,9 @@ VALUE rb_destroy(VALUE self);
VALUE rb_destroy_all(VALUE klass); VALUE rb_destroy_all(VALUE klass);
VALUE rb_resize(int argc, VALUE *argv, VALUE self); VALUE rb_resize(int argc, VALUE *argv, VALUE self);
VALUE rb_move(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_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 trackbar_callback(VALUE block, va_alist ap);
void mouse_callback(VALUE block, va_alist ap); void mouse_callback(VALUE block, va_alist ap);

View file

@ -72,7 +72,7 @@ else
end end
# Quick fix for 1.8.7 # Quick fix for 1.8.7
$CFLAGS << "-I#{File.dirname(__FILE__)}/ext/opencv" $CFLAGS << " -I#{File.dirname(__FILE__)}/ext/opencv"
# step-final. create Makefile # step-final. create Makefile
create_makefile("opencv", "./ext/opencv") create_makefile("opencv", "./ext/opencv")

View file

@ -99,6 +99,9 @@ class TestOpenCV < OpenCVTestCase
assert_equal(2, CV_FM_8POINT) assert_equal(2, CV_FM_8POINT)
assert_equal(8, CV_FM_RANSAC) assert_equal(8, CV_FM_RANSAC)
assert_equal(4, CV_FM_LMEDS) assert_equal(4, CV_FM_LMEDS)
# Flags of window
assert_equal(1, CV_WINDOW_AUTOSIZE)
end end
def test_symbols def test_symbols

115
test/test_window.rb Executable file
View file

@ -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 << "<L>" if mouse.left_button?
e << "<R>" if mouse.right_button?
e << "<M>" 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