Merge pull request #289 from tonysyu/qtmpl-collection-viewer

ENH: Add CollectionViewer.
This commit is contained in:
Stefan van der Walt
2012-09-02 04:39:23 -07:00
4 changed files with 118 additions and 2 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
try:
from viewers import ImageViewer
from viewers import ImageViewer, CollectionViewer
except ImportError:
print("Could not import PyQt4 -- ImageViewer not available.")
+1 -1
View File
@@ -1 +1 @@
from .core import *
from .core import ImageViewer, CollectionViewer
+87
View File
@@ -12,6 +12,10 @@ except ImportError:
from skimage.util.dtype import dtype_range
from ..utils import figimage, MatplotlibCanvas
from ..widgets import Slider
__all__ = ['ImageViewer', 'CollectionViewer']
qApp = None
@@ -194,3 +198,86 @@ class ImageViewer(QMainWindow):
return "%4s @ [%4s, %4s]" % (self.image[y, x], x, y)
except IndexError:
return ""
class CollectionViewer(ImageViewer):
"""Viewer for displaying image collections.
Select the displayed frame of the image collection using the slider or
with the following keyboard shortcuts:
left/right arrows
Previous/next image in collection.
number keys, 0--9
0% to 90% of collection. For example, "5" goes to the image in the
middle (i.e. 50%) of the collection.
home/end keys
First/last image in collection.
Subclasses and plugins will likely extend the `update_image` method to add
custom overlays or filter the displayed image.
Parameters
----------
image_collection : list of images
List of images to be displayed.
update_on : {'on_slide' | 'on_release'}
Control whether image is updated on slide or release of the image
slider. Using 'on_release' will give smoother behavior when displaying
large images or when writing a plugin/subclass that requires heavy
computation.
"""
def __init__(self, image_collection, update_on='move', **kwargs):
self.image_collection = image_collection
self.index = 0
self.num_images = len(self.image_collection)
first_image = image_collection[0]
super(CollectionViewer, self).__init__(first_image)
slider_kws = dict(value=0, low=0, high=self.num_images-1)
slider_kws['update_on'] = update_on
slider_kws['callback'] = self.update_index
slider_kws['value_type'] = 'int'
self.slider = Slider('frame', **slider_kws)
self.layout.addWidget(self.slider)
#TODO: Adjust height to accomodate slider; the following doesn't work
# s_size = self.slider.sizeHint()
# cs_size = self.canvas.sizeHint()
# self.resize(cs_size.width(), cs_size.height() + s_size.height())
def update_index(self, name, index):
"""Select image on display using index into image collection."""
index = int(round(index))
if index == self.index:
return
# clip index value to collection limits
index = max(index, 0)
index = min(index, self.num_images-1)
self.index = index
self.slider.val = index
self.update_image(self.image_collection[index])
def update_image(self, image):
"""Update displayed image.
This method can be overridden or extended in subclasses and plugins to
react to image changes.
"""
self.image = image
def keyPressEvent(self, event):
if type(event) == QtGui.QKeyEvent:
key = event.key()
# Number keys (code: 0 = key 48, 9 = key 57) move to deciles
if 48 <= key < 58:
index = 0.1 * int(key - 48) * self.num_images
self.update_index('', index)
event.accept()
else:
event.ignore()
@@ -0,0 +1,29 @@
"""
=====================
CollectionViewer demo
=====================
Demo of CollectionViewer for viewing collections of images. This demo uses
successively darker versions of the same image to fake an image collection.
You can scroll through images with the slider, or you can interact with the
viewer using your keyboard:
left/right arrows
Previous/next image in collection.
number keys, 0--9
0% to 90% of collection. For example, "5" goes to the image in the
middle (i.e. 50%) of the collection.
home/end keys
First/last image in collection.
"""
import numpy as np
from skimage import data
from skimage.viewer import CollectionViewer
img = data.lena()
img_collection = [np.uint8(img * 0.9**i) for i in range(20)]
view = CollectionViewer(img_collection)
view.show()