From 3f12aef7ede0044fb03ed0a982128b84f021e9a0 Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 16 Jul 2011 18:44:25 +0200 Subject: [PATCH 1/7] Fix bug with 2D images --- scikits/image/io/_plugins/util.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scikits/image/io/_plugins/util.py b/scikits/image/io/_plugins/util.py index b21dae45..2f37074c 100644 --- a/scikits/image/io/_plugins/util.py +++ b/scikits/image/io/_plugins/util.py @@ -135,14 +135,15 @@ def prepare_for_display(npy_img): if npy_img.ndim == 2 or \ (npy_img.ndim == 3 and npy_img.shape[2] == 1): + npy_plane = npy_img.reshape((height, width)) if np.issubdtype(npy_img.dtype, float): - out[:,:,0] = npy_img*255 + out[:,:,0] = npy_plane*255 out[:,:,1] = out[:,:,0] out[:,:,2] = out[:,:,0] else: - out[:,:,0] = npy_img - out[:,:,1] = npy_img - out[:,:,2] = npy_img + out[:,:,0] = npy_plane + out[:,:,1] = npy_plane + out[:,:,2] = npy_plane elif npy_img.ndim == 3: if npy_img.shape[2] == 3 or npy_img.shape[2] == 4: From 47fba11c98e05f87c63884e74b7c166b39fff9fe Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 16 Jul 2011 18:45:15 +0200 Subject: [PATCH 2/7] Add qt-based imread function --- scikits/image/io/_plugins/qt_plugin.ini | 2 +- scikits/image/io/_plugins/qt_plugin.py | 35 +++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/scikits/image/io/_plugins/qt_plugin.ini b/scikits/image/io/_plugins/qt_plugin.ini index 9e98ba81..822a2867 100644 --- a/scikits/image/io/_plugins/qt_plugin.ini +++ b/scikits/image/io/_plugins/qt_plugin.ini @@ -1,4 +1,4 @@ [qt] description = Fast image display using the Qt library -provides = imshow, _app_show, imsave +provides = imshow, _app_show, imsave, imread diff --git a/scikits/image/io/_plugins/qt_plugin.py b/scikits/image/io/_plugins/qt_plugin.py index b58e2c38..583bf08f 100644 --- a/scikits/image/io/_plugins/qt_plugin.py +++ b/scikits/image/io/_plugins/qt_plugin.py @@ -77,6 +77,41 @@ class ImageWindow(QMainWindow): self.mgr.remove_window(self) +def imread(filename, as_grey=False): + """ + Read an image using QT's QImage.load + """ + qtimg = QImage() + if not qtimg.load(filename): + # QImage.load() returns false on failure, so raise an exception + raise IOError('Unable to load file %s' % filename) + if qtimg.depth() == 1: + raise IOError('1-bit images currently not supported') + # TODO: Warn about other odd formats we don't currently handle properly, + # such as the odd 16-bit packed formats QT supports + arrayptr = qtimg.bits() + # QT may pad the image, so we need to use bytesPerLine, not width for + # the conversion to a numpy array + bytesPerPixel = qtimg.depth() // 8 + pixelsPerLine = qtimg.bytesPerLine() // bytesPerPixel + img_size = pixelsPerLine * qtimg.height() * bytesPerPixel + arrayptr.setsize(img_size) + img = np.array(arrayptr) + # Reshape and trim down to correct dimensions + if bytesPerPixel > 1: + img = img.reshape((qtimg.height(), pixelsPerLine, bytesPerPixel)) + img = img[:, :qtimg.width(), :] + else: + img = img.reshape((qtimg.height(), pixelsPerLine)) + img = img[:, :qtimg.width()] + if as_grey and bytesPerPixel > 1: + # Stolen from fits_plugin + # these are the values that wikipedia says are typical + transform = numpy.array([ 0.30, 0.59, 0.11]) + return numpy.dot(img, transform) + return img + + def imshow(arr, fancy=False): global app if not app: From 9b696cf34e2c7a0289f60865bee5925752dbd54a Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 16 Jul 2011 18:56:16 +0200 Subject: [PATCH 3/7] Only enable imread for new enough sip versions. Warn user if sip is too old --- scikits/image/io/_plugins/qt_plugin.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/scikits/image/io/_plugins/qt_plugin.py b/scikits/image/io/_plugins/qt_plugin.py index 583bf08f..6d931408 100644 --- a/scikits/image/io/_plugins/qt_plugin.py +++ b/scikits/image/io/_plugins/qt_plugin.py @@ -10,6 +10,8 @@ try: from PyQt4.QtGui import (QApplication, QMainWindow, QImage, QPixmap, QLabel, QWidget) from PyQt4 import QtCore, QtGui + import sip + import warnings except ImportError: window_manager._release('qt') @@ -27,6 +29,7 @@ except ImportError: app = None + class ImageLabel(QLabel): def __init__(self, parent, arr): QLabel.__init__(self) @@ -77,7 +80,7 @@ class ImageWindow(QMainWindow): self.mgr.remove_window(self) -def imread(filename, as_grey=False): +def imread_qt(filename, as_grey=False): """ Read an image using QT's QImage.load """ @@ -111,6 +114,14 @@ def imread(filename, as_grey=False): return numpy.dot(img, transform) return img +if sip.SIP_VERSION >= 0x040c00: + # sip.voidptr only acquired a buffer view in 4.12.0, so our imread + # doesn't work with earlier versions + imread = imread_qt +else: + warnings.warn(RuntimeWarning( + "sip version too old. QT imread disabled")) + def imshow(arr, fancy=False): global app From f260a47573a20f6c12dfc001e9c685da8eeeb14b Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 16 Jul 2011 21:02:33 +0200 Subject: [PATCH 4/7] Try initialise multiple plugins, not just PIL --- scikits/image/io/__init__.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scikits/image/io/__init__.py b/scikits/image/io/__init__.py index 4badbbd6..40c777c6 100644 --- a/scikits/image/io/__init__.py +++ b/scikits/image/io/__init__.py @@ -11,10 +11,14 @@ from _plugins import info as plugin_info # Add this plugin so that we can read images by default use_plugin('null') -try: - use_plugin('pil') -except ImportError: - pass +# Try to load a plugin to provide imread +for plugin in ['pil', 'freeimage', 'qt']: + try: + use_plugin(plugin) + # Plugin loaded, so break out + break + except ImportError: + pass from sift import * from collection import * From c266290b5d4408294bacd8d404c7aacd1a8ee968 Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 16 Jul 2011 21:32:31 +0200 Subject: [PATCH 5/7] Don't return an alpha channel if it's not present. Fix return type of as_grey --- scikits/image/io/_plugins/qt_plugin.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/scikits/image/io/_plugins/qt_plugin.py b/scikits/image/io/_plugins/qt_plugin.py index 6d931408..64379982 100644 --- a/scikits/image/io/_plugins/qt_plugin.py +++ b/scikits/image/io/_plugins/qt_plugin.py @@ -107,11 +107,17 @@ def imread_qt(filename, as_grey=False): else: img = img.reshape((qtimg.height(), pixelsPerLine)) img = img[:, :qtimg.width()] + # Strip alpha channel if needed + if bytesPerPixel == 4 and not qtimg.hasAlphaChannel(): + img = img[:, :, 0:3] if as_grey and bytesPerPixel > 1: # Stolen from fits_plugin - # these are the values that wikipedia says are typical - transform = numpy.array([ 0.30, 0.59, 0.11]) - return numpy.dot(img, transform) + if img.shape[2] == 4: + # these are the values that wikipedia says are typical + transform = np.array([ 0.30, 0.59, 0.11, 0]) + else: + transform = np.array([ 0.30, 0.59, 0.11]) + return np.dot(img, transform).astype('uint8') return img if sip.SIP_VERSION >= 0x040c00: From 5d2573af858e685e1a12fe3de0d54fc199c76dff Mon Sep 17 00:00:00 2001 From: Neil Date: Sun, 17 Jul 2011 00:23:22 +0200 Subject: [PATCH 6/7] Remove as_grey from qt imread --- scikits/image/io/_plugins/qt_plugin.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/scikits/image/io/_plugins/qt_plugin.py b/scikits/image/io/_plugins/qt_plugin.py index 64379982..7813e654 100644 --- a/scikits/image/io/_plugins/qt_plugin.py +++ b/scikits/image/io/_plugins/qt_plugin.py @@ -80,7 +80,7 @@ class ImageWindow(QMainWindow): self.mgr.remove_window(self) -def imread_qt(filename, as_grey=False): +def imread_qt(filename): """ Read an image using QT's QImage.load """ @@ -107,17 +107,9 @@ def imread_qt(filename, as_grey=False): else: img = img.reshape((qtimg.height(), pixelsPerLine)) img = img[:, :qtimg.width()] - # Strip alpha channel if needed + # Strip qt's false alpha channel if needed if bytesPerPixel == 4 and not qtimg.hasAlphaChannel(): img = img[:, :, 0:3] - if as_grey and bytesPerPixel > 1: - # Stolen from fits_plugin - if img.shape[2] == 4: - # these are the values that wikipedia says are typical - transform = np.array([ 0.30, 0.59, 0.11, 0]) - else: - transform = np.array([ 0.30, 0.59, 0.11]) - return np.dot(img, transform).astype('uint8') return img if sip.SIP_VERSION >= 0x040c00: From c53c8f3e00c9f7e0eddb920089b8c1c79e34d851 Mon Sep 17 00:00:00 2001 From: Neil Date: Sun, 17 Jul 2011 00:54:12 +0200 Subject: [PATCH 7/7] Fix axes color order --- scikits/image/io/_plugins/qt_plugin.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scikits/image/io/_plugins/qt_plugin.py b/scikits/image/io/_plugins/qt_plugin.py index 7813e654..ff8c7bed 100644 --- a/scikits/image/io/_plugins/qt_plugin.py +++ b/scikits/image/io/_plugins/qt_plugin.py @@ -108,8 +108,11 @@ def imread_qt(filename): img = img.reshape((qtimg.height(), pixelsPerLine)) img = img[:, :qtimg.width()] # Strip qt's false alpha channel if needed + # and reorder color axes as required if bytesPerPixel == 4 and not qtimg.hasAlphaChannel(): - img = img[:, :, 0:3] + img = img[:, :, 2::-1] + elif bytesPerPixel == 4: + img[:, :, 0:3] = img[:, :, 2::-1] return img if sip.SIP_VERSION >= 0x040c00: