Linking events in skimage.viewer

198 views
Skip to first unread message

Nadav Horesh

unread,
Dec 18, 2013, 3:13:02 AM12/18/13
to scikit...@googlegroups.com
I
I started to build an interactive image exploration utility based on
matplotlib. Recently, following a link on this list, I encountered
skimage.viewer, and found that the plugins architecture matches my needs.
I could not find how to link keyboard and mouse events (and maybe buttons)
to plugins. Any suggestions?

I am using version 0.93 on linux (I can install the pre 0.10, if needed)

Thanks,

Nadav

Juan Nunez-Iglesias

unread,
Dec 18, 2013, 3:26:42 AM12/18/13
to scikit...@googlegroups.com
Hi Nadav,

I don't have much experience with interactive tools, but I think this is the right place to start for examples:

You'll see that the LineProfile plugin uses the LineTool canvas tool:

Hopefully this helps, otherwise @tonysyu might be able to step in and offer a bit more guidance.

Juan.





--
You received this message because you are subscribed to the Google Groups "scikit-image" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scikit-image...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Nadav Horesh

unread,
Dec 18, 2013, 6:36:53 AM12/18/13
to scikit...@googlegroups.com
Thank you Juan. IIt looks like the event caught by the CanvasToolBase
are not whtn I am looking for (mouse click and keyboard events)

Thank you again,

Nadav

2013/12/18 Juan Nunez-Iglesias <jni....@gmail.com>:

Tony Yu

unread,
Dec 22, 2013, 9:20:44 AM12/22/13
to scikit...@googlegroups.com
On Wed, Dec 18, 2013 at 5:36 AM, Nadav Horesh <nadavh...@gmail.com> wrote:
Thank you Juan. IIt looks like the event caught by the CanvasToolBase
are not whtn I am looking for (mouse click and keyboard events)


Hi Nadav,

I'm not sure I follow. The canvas tools use matplotlib events because the image canvas is drawn with matplotlib. The `CanvasToolBase` class shows an example of using the tool's `connect_event` to connect to "key_press_event" (keyboard events). The `LineTool` class shows an example connecting to keyboard events through "button_press_event".

Note that this event system is only for the image canvas. If another widget (e.g. a slider) has focus, then the events are handled by Qt's infrastructure.

Cheers,
-Tony

Steven Silvester

unread,
Dec 22, 2013, 6:10:32 PM12/22/13
to scikit...@googlegroups.com

Nadav,

The canvas itself is a matplotlib.backends.backend_qt4agg.FigureCanvasQTAgg. If you wanted, you could subclass that class and provide your own mousePressEvent and friends. Something like:

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg
import matplotlib.pyplot as plt
from skimage import data


class MyCanvas(FigureCanvasQtAgg):

    def mousePressEvent(self, event):
        pass

def main(): 
    image = data.camera() 
    f, ax = plt.subplots()
    f.canvas = MyCanvas() 
    ax.imshow(image, interpolation='nearest') 
    h, w = image.shape 
    plt.show()

Nadav Horesh

unread,
Dec 23, 2013, 9:10:59 AM12/23/13
to scikit...@googlegroups.com
Tony,
I found the .connect_event method of the ImageViewer class just before
I got the reply from you, and it roughly works. I say roughly because
in the application there are some sliders that I added (not a part of
the built-in plugins), and what I see that I see an image update only
after I touch the sliders. In the linetool, however, the response is
immediate.

Code snippet:

class Cimage:
.
.
.
def create_window(self):
self.view = viewer.ImageViewer(self.rgb_image)

plugin = OverlayPlugin(image_filter=self.image_update)
plugin += Slider('gamma', 1.0, 3.0, value=self.gamma,
orientation='vertical')
plugin += Slider('mat mix', 0.0, 1.0, value=0.0,
update_on='move', orientation='vertical')
plugin += Slider('wb mix', 0.0, 1.0, value=0.0,
update_on='move', orientation='horizontal')

self.view += plugin
self.view.connect_event('key_press_event', self.key_press)
self.view.setWindowTitle(self.recname)
self.view.show()
.
.
.
in the key_press method execution chain I have
self.view.image = new_image

so the image is updated, but it does not trigger a display update.



Steve,
Here is your code after some typos correction:

#! /usr/bin/python

from __future__ import print_function

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg
import matplotlib.pyplot as plt
from skimage import data


class MyCanvas(FigureCanvasQTAgg):

def mousePressEvent(self, event):
#pass
print('press')
self.image = self.image[::-1]

def main():
image = data.camera()
f, ax = plt.subplots()
f.canvas = MyCanvas(f)
ax.imshow(image, interpolation='nearest')
h, w = image.shape
plt.show()


if __name__ == '__main__':
main()

Running it I see that the method mousePressEvent is not being called

I'll be happy to know if there is something to follow and build an
application based on the viewer module.

Thank you both very much

Nadav


2013/12/23 Steven Silvester <steven.s...@gmail.com>:

Steven Silvester

unread,
Dec 23, 2013, 10:50:29 AM12/23/13
to scikit...@googlegroups.com

Nadav,

You want the slider to update the value as it is moving? If so, pass update_on="move" to Slider(). I tried your example, and my view does update on key presses. I am using skimage 0.9.3 on Windows 7.

import matplotlib.pyplot as plt
from skimage import data
from skimage import viewer
from skimage.viewer.plugins.overlayplugin import OverlayPlugin
from skimage.viewer.widgets import Slider

class Cimage(object):

    def __init__(self):
        self.recname = 'howdy'
        self.rgb_image = data.camera()
        self.gamma = 1

    def key_press(self, event):
        self.view.image = self.view.image[::-1]

    def image_update(self, image, **kwargs):
        return image[::-1] - int(kwargs['gamma']) * 5


    def create_window(self):
        self.view = viewer.ImageViewer(self.rgb_image)

        plugin = OverlayPlugin(image_filter=self.image_update)
        plugin += Slider('gamma', 1.0, 3.0
, value=self.gamma,
orientation='vertical', update_on='move')
        plugin += Slider('mat mix', 0.0, 1.0, value=0.0,
update_on='move', orientation='vertical')
        plugin += Slider('wb mix', 0.0, 1.0, value=0.0,
update_on='move', orientation='horizontal')

        self.view += plugin
        self.view.connect_event('key_press_event', self.key_press)
        self.view.setWindowTitle(self.recname)
        self.view.show()

def main():
    a = Cimage()
    a.create_window()

if __name__ == '__main__':
    main()

About my earlier example, you would need to call f.canvas.show instead of plt.show (I ran the code this time). But, if the MPLCanvas methods work, I’d stick with those.

Cheers,
Steve



You received this message because you are subscribed to a topic in the Google Groups "scikit-image" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/scikit-image/pRZYHjAW78U/unsubscribe.
To unsubscribe from this group and all of its topics, send an email to scikit-image...@googlegroups.com.

Nadav Horesh

unread,
Dec 26, 2013, 9:12:15 AM12/26/13
to scikit...@googlegroups.com
Thanks Steve. It works also on my system (linux). I'll look over why
II had a problem in my original application.

Sorry for the late response,

Nadav

2013/12/23 Steven Silvester <steven.s...@gmail.com>:
> Nadav,
>
Reply all
Reply to author
Forward
0 new messages