Added automatic image downsampling (disabled by default)

- Reduces aliasing when zoomed out
  - Improves performance and memory usage for large images
Merge branch 'image_downsampling' into develop

Conflicts:
	pyqtgraph/graphicsItems/ImageItem.py
This commit is contained in:
Luke Campagnola 2014-02-17 20:48:22 -05:00
commit 7d32ef85be
7 changed files with 374 additions and 150 deletions

View File

@ -20,6 +20,7 @@ pyqtgraph-0.9.9 [unreleased]
New Features: New Features:
- Added ViewBox.setLimits() method - Added ViewBox.setLimits() method
- Adde ImageItem downsampling
- New HDF5 example for working with very large datasets - New HDF5 example for working with very large datasets
- Added Qt.loadUiType function for PySide - Added Qt.loadUiType function for PySide
- Simplified Profilers; can be activated with environmental variables - Simplified Profilers; can be activated with environmental variables

View File

@ -71,40 +71,67 @@ ui.rgbLevelsCheck.toggled.connect(updateScale)
cache = {} cache = {}
def mkData(): def mkData():
global data, cache, ui with pg.BusyCursor():
dtype = (ui.dtypeCombo.currentText(), ui.rgbCheck.isChecked()) global data, cache, ui
if dtype not in cache: frames = ui.framesSpin.value()
if dtype[0] == 'uint8': width = ui.widthSpin.value()
dt = np.uint8 height = ui.heightSpin.value()
loc = 128 dtype = (ui.dtypeCombo.currentText(), ui.rgbCheck.isChecked(), frames, width, height)
scale = 64 if dtype not in cache:
mx = 255 if dtype[0] == 'uint8':
elif dtype[0] == 'uint16': dt = np.uint8
dt = np.uint16 loc = 128
loc = 4096 scale = 64
scale = 1024 mx = 255
mx = 2**16 elif dtype[0] == 'uint16':
elif dtype[0] == 'float': dt = np.uint16
dt = np.float loc = 4096
loc = 1.0 scale = 1024
scale = 0.1 mx = 2**16
elif dtype[0] == 'float':
dt = np.float
loc = 1.0
scale = 0.1
if ui.rgbCheck.isChecked():
data = np.random.normal(size=(frames,width,height,3), loc=loc, scale=scale)
data = ndi.gaussian_filter(data, (0, 6, 6, 0))
else:
data = np.random.normal(size=(frames,width,height), loc=loc, scale=scale)
data = ndi.gaussian_filter(data, (0, 6, 6))
if dtype[0] != 'float':
data = np.clip(data, 0, mx)
data = data.astype(dt)
cache = {dtype: data} # clear to save memory (but keep one to prevent unnecessary regeneration)
data = cache[dtype]
updateLUT()
updateSize()
def updateSize():
global ui
frames = ui.framesSpin.value()
width = ui.widthSpin.value()
height = ui.heightSpin.value()
dtype = np.dtype(str(ui.dtypeCombo.currentText()))
rgb = 3 if ui.rgbCheck.isChecked() else 1
ui.sizeLabel.setText('%d MB' % (frames * width * height * rgb * dtype.itemsize / 1e6))
if ui.rgbCheck.isChecked():
data = np.random.normal(size=(20,512,512,3), loc=loc, scale=scale)
data = ndi.gaussian_filter(data, (0, 6, 6, 0))
else:
data = np.random.normal(size=(20,512,512), loc=loc, scale=scale)
data = ndi.gaussian_filter(data, (0, 6, 6))
if dtype[0] != 'float':
data = np.clip(data, 0, mx)
data = data.astype(dt)
cache[dtype] = data
data = cache[dtype]
updateLUT()
mkData() mkData()
ui.dtypeCombo.currentIndexChanged.connect(mkData) ui.dtypeCombo.currentIndexChanged.connect(mkData)
ui.rgbCheck.toggled.connect(mkData) ui.rgbCheck.toggled.connect(mkData)
ui.widthSpin.editingFinished.connect(mkData)
ui.heightSpin.editingFinished.connect(mkData)
ui.framesSpin.editingFinished.connect(mkData)
ui.widthSpin.valueChanged.connect(updateSize)
ui.heightSpin.valueChanged.connect(updateSize)
ui.framesSpin.valueChanged.connect(updateSize)
ptr = 0 ptr = 0
lastTime = ptime.time() lastTime = ptime.time()
@ -116,6 +143,8 @@ def update():
else: else:
useLut = None useLut = None
downsample = ui.downsampleCheck.isChecked()
if ui.scaleCheck.isChecked(): if ui.scaleCheck.isChecked():
if ui.rgbLevelsCheck.isChecked(): if ui.rgbLevelsCheck.isChecked():
useScale = [ useScale = [
@ -134,7 +163,7 @@ def update():
ui.rawGLImg.setImage(data[ptr%data.shape[0]], lut=useLut, levels=useScale) ui.rawGLImg.setImage(data[ptr%data.shape[0]], lut=useLut, levels=useScale)
ui.stack.setCurrentIndex(2) ui.stack.setCurrentIndex(2)
else: else:
img.setImage(data[ptr%data.shape[0]], autoLevels=False, levels=useScale, lut=useLut) img.setImage(data[ptr%data.shape[0]], autoLevels=False, levels=useScale, lut=useLut, autoDownsample=downsample)
ui.stack.setCurrentIndex(0) ui.stack.setCurrentIndex(0)
#img.setImage(data[ptr%data.shape[0]], autoRange=False) #img.setImage(data[ptr%data.shape[0]], autoRange=False)

View File

@ -15,6 +15,20 @@
</property> </property>
<widget class="QWidget" name="centralwidget"> <widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout_2"> <layout class="QGridLayout" name="gridLayout_2">
<item row="8" column="0" colspan="2">
<widget class="QCheckBox" name="downsampleCheck">
<property name="text">
<string>Auto downsample</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="scaleCheck">
<property name="text">
<string>Scale Data</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="4"> <item row="1" column="0" colspan="4">
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="3" column="0"> <item row="3" column="0">
@ -78,14 +92,7 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="2" column="0"> <item row="3" column="2">
<widget class="QLabel" name="label">
<property name="text">
<string>Data type</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QComboBox" name="dtypeCombo"> <widget class="QComboBox" name="dtypeCombo">
<item> <item>
<property name="text"> <property name="text">
@ -105,40 +112,20 @@
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QCheckBox" name="scaleCheck"> <widget class="QLabel" name="label">
<property name="text"> <property name="text">
<string>Scale Data</string> <string>Data type</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="1"> <item row="4" column="1">
<widget class="QCheckBox" name="rgbLevelsCheck"> <widget class="QCheckBox" name="rgbLevelsCheck">
<property name="text"> <property name="text">
<string>RGB</string> <string>RGB</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="2"> <item row="5" column="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="SpinBox" name="minSpin1"/>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>&lt;---&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="SpinBox" name="maxSpin1"/>
</item>
</layout>
</item>
<item row="4" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_2"> <layout class="QHBoxLayout" name="horizontalLayout_2">
<item> <item>
<widget class="SpinBox" name="minSpin2"> <widget class="SpinBox" name="minSpin2">
@ -166,7 +153,27 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="5" column="2"> <item row="4" column="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="SpinBox" name="minSpin1"/>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>&lt;---&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<widget class="SpinBox" name="maxSpin1"/>
</item>
</layout>
</item>
<item row="6" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_3"> <layout class="QHBoxLayout" name="horizontalLayout_3">
<item> <item>
<widget class="SpinBox" name="minSpin3"> <widget class="SpinBox" name="minSpin3">
@ -194,21 +201,21 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="6" column="0"> <item row="7" column="0">
<widget class="QCheckBox" name="lutCheck"> <widget class="QCheckBox" name="lutCheck">
<property name="text"> <property name="text">
<string>Use Lookup Table</string> <string>Use Lookup Table</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="1"> <item row="7" column="1">
<widget class="QCheckBox" name="alphaCheck"> <widget class="QCheckBox" name="alphaCheck">
<property name="text"> <property name="text">
<string>alpha</string> <string>alpha</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="6" column="2" colspan="2"> <item row="7" column="2" colspan="2">
<widget class="GradientWidget" name="gradient" native="true"> <widget class="GradientWidget" name="gradient" native="true">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
@ -218,7 +225,7 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="3"> <item row="3" column="3">
<spacer name="horizontalSpacer"> <spacer name="horizontalSpacer">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@ -246,13 +253,67 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="1"> <item row="3" column="1">
<widget class="QCheckBox" name="rgbCheck"> <widget class="QCheckBox" name="rgbCheck">
<property name="text"> <property name="text">
<string>RGB</string> <string>RGB</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Image size</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QSpinBox" name="framesSpin">
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="value">
<number>10</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="widthSpin">
<property name="buttonSymbols">
<enum>QAbstractSpinBox::PlusMinus</enum>
</property>
<property name="maximum">
<number>10000</number>
</property>
<property name="value">
<number>512</number>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="heightSpin">
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="maximum">
<number>10000</number>
</property>
<property name="value">
<number>512</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="3">
<widget class="QLabel" name="sizeLabel">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
</widget> </widget>

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Form implementation generated from reading ui file './VideoTemplate.ui' # Form implementation generated from reading ui file './examples/VideoTemplate.ui'
# #
# Created: Sat Nov 16 20:07:09 2013 # Created: Mon Feb 17 20:39:30 2014
# by: PyQt4 UI code generator 4.10 # by: PyQt4 UI code generator 4.10.3
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -31,6 +31,12 @@ class Ui_MainWindow(object):
self.centralwidget.setObjectName(_fromUtf8("centralwidget")) self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget) self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget)
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2")) self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
self.downsampleCheck = QtGui.QCheckBox(self.centralwidget)
self.downsampleCheck.setObjectName(_fromUtf8("downsampleCheck"))
self.gridLayout_2.addWidget(self.downsampleCheck, 8, 0, 1, 2)
self.scaleCheck = QtGui.QCheckBox(self.centralwidget)
self.scaleCheck.setObjectName(_fromUtf8("scaleCheck"))
self.gridLayout_2.addWidget(self.scaleCheck, 4, 0, 1, 1)
self.gridLayout = QtGui.QGridLayout() self.gridLayout = QtGui.QGridLayout()
self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.rawRadio = QtGui.QRadioButton(self.centralwidget) self.rawRadio = QtGui.QRadioButton(self.centralwidget)
@ -76,34 +82,18 @@ class Ui_MainWindow(object):
self.rawGLRadio.setObjectName(_fromUtf8("rawGLRadio")) self.rawGLRadio.setObjectName(_fromUtf8("rawGLRadio"))
self.gridLayout.addWidget(self.rawGLRadio, 4, 0, 1, 1) self.gridLayout.addWidget(self.rawGLRadio, 4, 0, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 1, 0, 1, 4) self.gridLayout_2.addLayout(self.gridLayout, 1, 0, 1, 4)
self.label = QtGui.QLabel(self.centralwidget)
self.label.setObjectName(_fromUtf8("label"))
self.gridLayout_2.addWidget(self.label, 2, 0, 1, 1)
self.dtypeCombo = QtGui.QComboBox(self.centralwidget) self.dtypeCombo = QtGui.QComboBox(self.centralwidget)
self.dtypeCombo.setObjectName(_fromUtf8("dtypeCombo")) self.dtypeCombo.setObjectName(_fromUtf8("dtypeCombo"))
self.dtypeCombo.addItem(_fromUtf8("")) self.dtypeCombo.addItem(_fromUtf8(""))
self.dtypeCombo.addItem(_fromUtf8("")) self.dtypeCombo.addItem(_fromUtf8(""))
self.dtypeCombo.addItem(_fromUtf8("")) self.dtypeCombo.addItem(_fromUtf8(""))
self.gridLayout_2.addWidget(self.dtypeCombo, 2, 2, 1, 1) self.gridLayout_2.addWidget(self.dtypeCombo, 3, 2, 1, 1)
self.scaleCheck = QtGui.QCheckBox(self.centralwidget) self.label = QtGui.QLabel(self.centralwidget)
self.scaleCheck.setObjectName(_fromUtf8("scaleCheck")) self.label.setObjectName(_fromUtf8("label"))
self.gridLayout_2.addWidget(self.scaleCheck, 3, 0, 1, 1) self.gridLayout_2.addWidget(self.label, 3, 0, 1, 1)
self.rgbLevelsCheck = QtGui.QCheckBox(self.centralwidget) self.rgbLevelsCheck = QtGui.QCheckBox(self.centralwidget)
self.rgbLevelsCheck.setObjectName(_fromUtf8("rgbLevelsCheck")) self.rgbLevelsCheck.setObjectName(_fromUtf8("rgbLevelsCheck"))
self.gridLayout_2.addWidget(self.rgbLevelsCheck, 3, 1, 1, 1) self.gridLayout_2.addWidget(self.rgbLevelsCheck, 4, 1, 1, 1)
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.minSpin1 = SpinBox(self.centralwidget)
self.minSpin1.setObjectName(_fromUtf8("minSpin1"))
self.horizontalLayout.addWidget(self.minSpin1)
self.label_2 = QtGui.QLabel(self.centralwidget)
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName(_fromUtf8("label_2"))
self.horizontalLayout.addWidget(self.label_2)
self.maxSpin1 = SpinBox(self.centralwidget)
self.maxSpin1.setObjectName(_fromUtf8("maxSpin1"))
self.horizontalLayout.addWidget(self.maxSpin1)
self.gridLayout_2.addLayout(self.horizontalLayout, 3, 2, 1, 1)
self.horizontalLayout_2 = QtGui.QHBoxLayout() self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
self.minSpin2 = SpinBox(self.centralwidget) self.minSpin2 = SpinBox(self.centralwidget)
@ -118,7 +108,20 @@ class Ui_MainWindow(object):
self.maxSpin2.setEnabled(False) self.maxSpin2.setEnabled(False)
self.maxSpin2.setObjectName(_fromUtf8("maxSpin2")) self.maxSpin2.setObjectName(_fromUtf8("maxSpin2"))
self.horizontalLayout_2.addWidget(self.maxSpin2) self.horizontalLayout_2.addWidget(self.maxSpin2)
self.gridLayout_2.addLayout(self.horizontalLayout_2, 4, 2, 1, 1) self.gridLayout_2.addLayout(self.horizontalLayout_2, 5, 2, 1, 1)
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.minSpin1 = SpinBox(self.centralwidget)
self.minSpin1.setObjectName(_fromUtf8("minSpin1"))
self.horizontalLayout.addWidget(self.minSpin1)
self.label_2 = QtGui.QLabel(self.centralwidget)
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName(_fromUtf8("label_2"))
self.horizontalLayout.addWidget(self.label_2)
self.maxSpin1 = SpinBox(self.centralwidget)
self.maxSpin1.setObjectName(_fromUtf8("maxSpin1"))
self.horizontalLayout.addWidget(self.maxSpin1)
self.gridLayout_2.addLayout(self.horizontalLayout, 4, 2, 1, 1)
self.horizontalLayout_3 = QtGui.QHBoxLayout() self.horizontalLayout_3 = QtGui.QHBoxLayout()
self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3")) self.horizontalLayout_3.setObjectName(_fromUtf8("horizontalLayout_3"))
self.minSpin3 = SpinBox(self.centralwidget) self.minSpin3 = SpinBox(self.centralwidget)
@ -133,13 +136,13 @@ class Ui_MainWindow(object):
self.maxSpin3.setEnabled(False) self.maxSpin3.setEnabled(False)
self.maxSpin3.setObjectName(_fromUtf8("maxSpin3")) self.maxSpin3.setObjectName(_fromUtf8("maxSpin3"))
self.horizontalLayout_3.addWidget(self.maxSpin3) self.horizontalLayout_3.addWidget(self.maxSpin3)
self.gridLayout_2.addLayout(self.horizontalLayout_3, 5, 2, 1, 1) self.gridLayout_2.addLayout(self.horizontalLayout_3, 6, 2, 1, 1)
self.lutCheck = QtGui.QCheckBox(self.centralwidget) self.lutCheck = QtGui.QCheckBox(self.centralwidget)
self.lutCheck.setObjectName(_fromUtf8("lutCheck")) self.lutCheck.setObjectName(_fromUtf8("lutCheck"))
self.gridLayout_2.addWidget(self.lutCheck, 6, 0, 1, 1) self.gridLayout_2.addWidget(self.lutCheck, 7, 0, 1, 1)
self.alphaCheck = QtGui.QCheckBox(self.centralwidget) self.alphaCheck = QtGui.QCheckBox(self.centralwidget)
self.alphaCheck.setObjectName(_fromUtf8("alphaCheck")) self.alphaCheck.setObjectName(_fromUtf8("alphaCheck"))
self.gridLayout_2.addWidget(self.alphaCheck, 6, 1, 1, 1) self.gridLayout_2.addWidget(self.alphaCheck, 7, 1, 1, 1)
self.gradient = GradientWidget(self.centralwidget) self.gradient = GradientWidget(self.centralwidget)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -147,9 +150,9 @@ class Ui_MainWindow(object):
sizePolicy.setHeightForWidth(self.gradient.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.gradient.sizePolicy().hasHeightForWidth())
self.gradient.setSizePolicy(sizePolicy) self.gradient.setSizePolicy(sizePolicy)
self.gradient.setObjectName(_fromUtf8("gradient")) self.gradient.setObjectName(_fromUtf8("gradient"))
self.gridLayout_2.addWidget(self.gradient, 6, 2, 1, 2) self.gridLayout_2.addWidget(self.gradient, 7, 2, 1, 2)
spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_2.addItem(spacerItem, 2, 3, 1, 1) self.gridLayout_2.addItem(spacerItem, 3, 3, 1, 1)
self.fpsLabel = QtGui.QLabel(self.centralwidget) self.fpsLabel = QtGui.QLabel(self.centralwidget)
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(12) font.setPointSize(12)
@ -159,7 +162,34 @@ class Ui_MainWindow(object):
self.gridLayout_2.addWidget(self.fpsLabel, 0, 0, 1, 4) self.gridLayout_2.addWidget(self.fpsLabel, 0, 0, 1, 4)
self.rgbCheck = QtGui.QCheckBox(self.centralwidget) self.rgbCheck = QtGui.QCheckBox(self.centralwidget)
self.rgbCheck.setObjectName(_fromUtf8("rgbCheck")) self.rgbCheck.setObjectName(_fromUtf8("rgbCheck"))
self.gridLayout_2.addWidget(self.rgbCheck, 2, 1, 1, 1) self.gridLayout_2.addWidget(self.rgbCheck, 3, 1, 1, 1)
self.label_5 = QtGui.QLabel(self.centralwidget)
self.label_5.setObjectName(_fromUtf8("label_5"))
self.gridLayout_2.addWidget(self.label_5, 2, 0, 1, 1)
self.horizontalLayout_4 = QtGui.QHBoxLayout()
self.horizontalLayout_4.setObjectName(_fromUtf8("horizontalLayout_4"))
self.framesSpin = QtGui.QSpinBox(self.centralwidget)
self.framesSpin.setButtonSymbols(QtGui.QAbstractSpinBox.NoButtons)
self.framesSpin.setProperty("value", 10)
self.framesSpin.setObjectName(_fromUtf8("framesSpin"))
self.horizontalLayout_4.addWidget(self.framesSpin)
self.widthSpin = QtGui.QSpinBox(self.centralwidget)
self.widthSpin.setButtonSymbols(QtGui.QAbstractSpinBox.PlusMinus)
self.widthSpin.setMaximum(10000)
self.widthSpin.setProperty("value", 512)
self.widthSpin.setObjectName(_fromUtf8("widthSpin"))
self.horizontalLayout_4.addWidget(self.widthSpin)
self.heightSpin = QtGui.QSpinBox(self.centralwidget)
self.heightSpin.setButtonSymbols(QtGui.QAbstractSpinBox.NoButtons)
self.heightSpin.setMaximum(10000)
self.heightSpin.setProperty("value", 512)
self.heightSpin.setObjectName(_fromUtf8("heightSpin"))
self.horizontalLayout_4.addWidget(self.heightSpin)
self.gridLayout_2.addLayout(self.horizontalLayout_4, 2, 1, 1, 2)
self.sizeLabel = QtGui.QLabel(self.centralwidget)
self.sizeLabel.setText(_fromUtf8(""))
self.sizeLabel.setObjectName(_fromUtf8("sizeLabel"))
self.gridLayout_2.addWidget(self.sizeLabel, 2, 3, 1, 1)
MainWindow.setCentralWidget(self.centralwidget) MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow) self.retranslateUi(MainWindow)
@ -168,22 +198,24 @@ class Ui_MainWindow(object):
def retranslateUi(self, MainWindow): def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None)) MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
self.downsampleCheck.setText(_translate("MainWindow", "Auto downsample", None))
self.scaleCheck.setText(_translate("MainWindow", "Scale Data", None))
self.rawRadio.setText(_translate("MainWindow", "RawImageWidget", None)) self.rawRadio.setText(_translate("MainWindow", "RawImageWidget", None))
self.gfxRadio.setText(_translate("MainWindow", "GraphicsView + ImageItem", None)) self.gfxRadio.setText(_translate("MainWindow", "GraphicsView + ImageItem", None))
self.rawGLRadio.setText(_translate("MainWindow", "RawGLImageWidget", None)) self.rawGLRadio.setText(_translate("MainWindow", "RawGLImageWidget", None))
self.label.setText(_translate("MainWindow", "Data type", None))
self.dtypeCombo.setItemText(0, _translate("MainWindow", "uint8", None)) self.dtypeCombo.setItemText(0, _translate("MainWindow", "uint8", None))
self.dtypeCombo.setItemText(1, _translate("MainWindow", "uint16", None)) self.dtypeCombo.setItemText(1, _translate("MainWindow", "uint16", None))
self.dtypeCombo.setItemText(2, _translate("MainWindow", "float", None)) self.dtypeCombo.setItemText(2, _translate("MainWindow", "float", None))
self.scaleCheck.setText(_translate("MainWindow", "Scale Data", None)) self.label.setText(_translate("MainWindow", "Data type", None))
self.rgbLevelsCheck.setText(_translate("MainWindow", "RGB", None)) self.rgbLevelsCheck.setText(_translate("MainWindow", "RGB", None))
self.label_2.setText(_translate("MainWindow", "<--->", None))
self.label_3.setText(_translate("MainWindow", "<--->", None)) self.label_3.setText(_translate("MainWindow", "<--->", None))
self.label_2.setText(_translate("MainWindow", "<--->", None))
self.label_4.setText(_translate("MainWindow", "<--->", None)) self.label_4.setText(_translate("MainWindow", "<--->", None))
self.lutCheck.setText(_translate("MainWindow", "Use Lookup Table", None)) self.lutCheck.setText(_translate("MainWindow", "Use Lookup Table", None))
self.alphaCheck.setText(_translate("MainWindow", "alpha", None)) self.alphaCheck.setText(_translate("MainWindow", "alpha", None))
self.fpsLabel.setText(_translate("MainWindow", "FPS", None)) self.fpsLabel.setText(_translate("MainWindow", "FPS", None))
self.rgbCheck.setText(_translate("MainWindow", "RGB", None)) self.rgbCheck.setText(_translate("MainWindow", "RGB", None))
self.label_5.setText(_translate("MainWindow", "Image size", None))
from pyqtgraph.widgets.RawImageWidget import RawImageGLWidget, RawImageWidget from pyqtgraph.widgets.RawImageWidget import RawImageGLWidget, RawImageWidget
from pyqtgraph import GradientWidget, SpinBox, GraphicsView from pyqtgraph import GradientWidget, SpinBox, GraphicsView

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Form implementation generated from reading ui file './VideoTemplate.ui' # Form implementation generated from reading ui file './examples/VideoTemplate.ui'
# #
# Created: Sat Nov 16 20:07:10 2013 # Created: Mon Feb 17 20:39:30 2014
# by: pyside-uic 0.2.14 running on PySide 1.1.2 # by: pyside-uic 0.2.14 running on PySide 1.1.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -17,6 +17,12 @@ class Ui_MainWindow(object):
self.centralwidget.setObjectName("centralwidget") self.centralwidget.setObjectName("centralwidget")
self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget) self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget)
self.gridLayout_2.setObjectName("gridLayout_2") self.gridLayout_2.setObjectName("gridLayout_2")
self.downsampleCheck = QtGui.QCheckBox(self.centralwidget)
self.downsampleCheck.setObjectName("downsampleCheck")
self.gridLayout_2.addWidget(self.downsampleCheck, 8, 0, 1, 2)
self.scaleCheck = QtGui.QCheckBox(self.centralwidget)
self.scaleCheck.setObjectName("scaleCheck")
self.gridLayout_2.addWidget(self.scaleCheck, 4, 0, 1, 1)
self.gridLayout = QtGui.QGridLayout() self.gridLayout = QtGui.QGridLayout()
self.gridLayout.setObjectName("gridLayout") self.gridLayout.setObjectName("gridLayout")
self.rawRadio = QtGui.QRadioButton(self.centralwidget) self.rawRadio = QtGui.QRadioButton(self.centralwidget)
@ -62,34 +68,18 @@ class Ui_MainWindow(object):
self.rawGLRadio.setObjectName("rawGLRadio") self.rawGLRadio.setObjectName("rawGLRadio")
self.gridLayout.addWidget(self.rawGLRadio, 4, 0, 1, 1) self.gridLayout.addWidget(self.rawGLRadio, 4, 0, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 1, 0, 1, 4) self.gridLayout_2.addLayout(self.gridLayout, 1, 0, 1, 4)
self.label = QtGui.QLabel(self.centralwidget)
self.label.setObjectName("label")
self.gridLayout_2.addWidget(self.label, 2, 0, 1, 1)
self.dtypeCombo = QtGui.QComboBox(self.centralwidget) self.dtypeCombo = QtGui.QComboBox(self.centralwidget)
self.dtypeCombo.setObjectName("dtypeCombo") self.dtypeCombo.setObjectName("dtypeCombo")
self.dtypeCombo.addItem("") self.dtypeCombo.addItem("")
self.dtypeCombo.addItem("") self.dtypeCombo.addItem("")
self.dtypeCombo.addItem("") self.dtypeCombo.addItem("")
self.gridLayout_2.addWidget(self.dtypeCombo, 2, 2, 1, 1) self.gridLayout_2.addWidget(self.dtypeCombo, 3, 2, 1, 1)
self.scaleCheck = QtGui.QCheckBox(self.centralwidget) self.label = QtGui.QLabel(self.centralwidget)
self.scaleCheck.setObjectName("scaleCheck") self.label.setObjectName("label")
self.gridLayout_2.addWidget(self.scaleCheck, 3, 0, 1, 1) self.gridLayout_2.addWidget(self.label, 3, 0, 1, 1)
self.rgbLevelsCheck = QtGui.QCheckBox(self.centralwidget) self.rgbLevelsCheck = QtGui.QCheckBox(self.centralwidget)
self.rgbLevelsCheck.setObjectName("rgbLevelsCheck") self.rgbLevelsCheck.setObjectName("rgbLevelsCheck")
self.gridLayout_2.addWidget(self.rgbLevelsCheck, 3, 1, 1, 1) self.gridLayout_2.addWidget(self.rgbLevelsCheck, 4, 1, 1, 1)
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.minSpin1 = SpinBox(self.centralwidget)
self.minSpin1.setObjectName("minSpin1")
self.horizontalLayout.addWidget(self.minSpin1)
self.label_2 = QtGui.QLabel(self.centralwidget)
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName("label_2")
self.horizontalLayout.addWidget(self.label_2)
self.maxSpin1 = SpinBox(self.centralwidget)
self.maxSpin1.setObjectName("maxSpin1")
self.horizontalLayout.addWidget(self.maxSpin1)
self.gridLayout_2.addLayout(self.horizontalLayout, 3, 2, 1, 1)
self.horizontalLayout_2 = QtGui.QHBoxLayout() self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.minSpin2 = SpinBox(self.centralwidget) self.minSpin2 = SpinBox(self.centralwidget)
@ -104,7 +94,20 @@ class Ui_MainWindow(object):
self.maxSpin2.setEnabled(False) self.maxSpin2.setEnabled(False)
self.maxSpin2.setObjectName("maxSpin2") self.maxSpin2.setObjectName("maxSpin2")
self.horizontalLayout_2.addWidget(self.maxSpin2) self.horizontalLayout_2.addWidget(self.maxSpin2)
self.gridLayout_2.addLayout(self.horizontalLayout_2, 4, 2, 1, 1) self.gridLayout_2.addLayout(self.horizontalLayout_2, 5, 2, 1, 1)
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.minSpin1 = SpinBox(self.centralwidget)
self.minSpin1.setObjectName("minSpin1")
self.horizontalLayout.addWidget(self.minSpin1)
self.label_2 = QtGui.QLabel(self.centralwidget)
self.label_2.setAlignment(QtCore.Qt.AlignCenter)
self.label_2.setObjectName("label_2")
self.horizontalLayout.addWidget(self.label_2)
self.maxSpin1 = SpinBox(self.centralwidget)
self.maxSpin1.setObjectName("maxSpin1")
self.horizontalLayout.addWidget(self.maxSpin1)
self.gridLayout_2.addLayout(self.horizontalLayout, 4, 2, 1, 1)
self.horizontalLayout_3 = QtGui.QHBoxLayout() self.horizontalLayout_3 = QtGui.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.minSpin3 = SpinBox(self.centralwidget) self.minSpin3 = SpinBox(self.centralwidget)
@ -119,13 +122,13 @@ class Ui_MainWindow(object):
self.maxSpin3.setEnabled(False) self.maxSpin3.setEnabled(False)
self.maxSpin3.setObjectName("maxSpin3") self.maxSpin3.setObjectName("maxSpin3")
self.horizontalLayout_3.addWidget(self.maxSpin3) self.horizontalLayout_3.addWidget(self.maxSpin3)
self.gridLayout_2.addLayout(self.horizontalLayout_3, 5, 2, 1, 1) self.gridLayout_2.addLayout(self.horizontalLayout_3, 6, 2, 1, 1)
self.lutCheck = QtGui.QCheckBox(self.centralwidget) self.lutCheck = QtGui.QCheckBox(self.centralwidget)
self.lutCheck.setObjectName("lutCheck") self.lutCheck.setObjectName("lutCheck")
self.gridLayout_2.addWidget(self.lutCheck, 6, 0, 1, 1) self.gridLayout_2.addWidget(self.lutCheck, 7, 0, 1, 1)
self.alphaCheck = QtGui.QCheckBox(self.centralwidget) self.alphaCheck = QtGui.QCheckBox(self.centralwidget)
self.alphaCheck.setObjectName("alphaCheck") self.alphaCheck.setObjectName("alphaCheck")
self.gridLayout_2.addWidget(self.alphaCheck, 6, 1, 1, 1) self.gridLayout_2.addWidget(self.alphaCheck, 7, 1, 1, 1)
self.gradient = GradientWidget(self.centralwidget) self.gradient = GradientWidget(self.centralwidget)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -133,9 +136,9 @@ class Ui_MainWindow(object):
sizePolicy.setHeightForWidth(self.gradient.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.gradient.sizePolicy().hasHeightForWidth())
self.gradient.setSizePolicy(sizePolicy) self.gradient.setSizePolicy(sizePolicy)
self.gradient.setObjectName("gradient") self.gradient.setObjectName("gradient")
self.gridLayout_2.addWidget(self.gradient, 6, 2, 1, 2) self.gridLayout_2.addWidget(self.gradient, 7, 2, 1, 2)
spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
self.gridLayout_2.addItem(spacerItem, 2, 3, 1, 1) self.gridLayout_2.addItem(spacerItem, 3, 3, 1, 1)
self.fpsLabel = QtGui.QLabel(self.centralwidget) self.fpsLabel = QtGui.QLabel(self.centralwidget)
font = QtGui.QFont() font = QtGui.QFont()
font.setPointSize(12) font.setPointSize(12)
@ -145,7 +148,34 @@ class Ui_MainWindow(object):
self.gridLayout_2.addWidget(self.fpsLabel, 0, 0, 1, 4) self.gridLayout_2.addWidget(self.fpsLabel, 0, 0, 1, 4)
self.rgbCheck = QtGui.QCheckBox(self.centralwidget) self.rgbCheck = QtGui.QCheckBox(self.centralwidget)
self.rgbCheck.setObjectName("rgbCheck") self.rgbCheck.setObjectName("rgbCheck")
self.gridLayout_2.addWidget(self.rgbCheck, 2, 1, 1, 1) self.gridLayout_2.addWidget(self.rgbCheck, 3, 1, 1, 1)
self.label_5 = QtGui.QLabel(self.centralwidget)
self.label_5.setObjectName("label_5")
self.gridLayout_2.addWidget(self.label_5, 2, 0, 1, 1)
self.horizontalLayout_4 = QtGui.QHBoxLayout()
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
self.framesSpin = QtGui.QSpinBox(self.centralwidget)
self.framesSpin.setButtonSymbols(QtGui.QAbstractSpinBox.NoButtons)
self.framesSpin.setProperty("value", 10)
self.framesSpin.setObjectName("framesSpin")
self.horizontalLayout_4.addWidget(self.framesSpin)
self.widthSpin = QtGui.QSpinBox(self.centralwidget)
self.widthSpin.setButtonSymbols(QtGui.QAbstractSpinBox.PlusMinus)
self.widthSpin.setMaximum(10000)
self.widthSpin.setProperty("value", 512)
self.widthSpin.setObjectName("widthSpin")
self.horizontalLayout_4.addWidget(self.widthSpin)
self.heightSpin = QtGui.QSpinBox(self.centralwidget)
self.heightSpin.setButtonSymbols(QtGui.QAbstractSpinBox.NoButtons)
self.heightSpin.setMaximum(10000)
self.heightSpin.setProperty("value", 512)
self.heightSpin.setObjectName("heightSpin")
self.horizontalLayout_4.addWidget(self.heightSpin)
self.gridLayout_2.addLayout(self.horizontalLayout_4, 2, 1, 1, 2)
self.sizeLabel = QtGui.QLabel(self.centralwidget)
self.sizeLabel.setText("")
self.sizeLabel.setObjectName("sizeLabel")
self.gridLayout_2.addWidget(self.sizeLabel, 2, 3, 1, 1)
MainWindow.setCentralWidget(self.centralwidget) MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow) self.retranslateUi(MainWindow)
@ -154,22 +184,24 @@ class Ui_MainWindow(object):
def retranslateUi(self, MainWindow): def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8)) MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
self.downsampleCheck.setText(QtGui.QApplication.translate("MainWindow", "Auto downsample", None, QtGui.QApplication.UnicodeUTF8))
self.scaleCheck.setText(QtGui.QApplication.translate("MainWindow", "Scale Data", None, QtGui.QApplication.UnicodeUTF8))
self.rawRadio.setText(QtGui.QApplication.translate("MainWindow", "RawImageWidget", None, QtGui.QApplication.UnicodeUTF8)) self.rawRadio.setText(QtGui.QApplication.translate("MainWindow", "RawImageWidget", None, QtGui.QApplication.UnicodeUTF8))
self.gfxRadio.setText(QtGui.QApplication.translate("MainWindow", "GraphicsView + ImageItem", None, QtGui.QApplication.UnicodeUTF8)) self.gfxRadio.setText(QtGui.QApplication.translate("MainWindow", "GraphicsView + ImageItem", None, QtGui.QApplication.UnicodeUTF8))
self.rawGLRadio.setText(QtGui.QApplication.translate("MainWindow", "RawGLImageWidget", None, QtGui.QApplication.UnicodeUTF8)) self.rawGLRadio.setText(QtGui.QApplication.translate("MainWindow", "RawGLImageWidget", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("MainWindow", "Data type", None, QtGui.QApplication.UnicodeUTF8))
self.dtypeCombo.setItemText(0, QtGui.QApplication.translate("MainWindow", "uint8", None, QtGui.QApplication.UnicodeUTF8)) self.dtypeCombo.setItemText(0, QtGui.QApplication.translate("MainWindow", "uint8", None, QtGui.QApplication.UnicodeUTF8))
self.dtypeCombo.setItemText(1, QtGui.QApplication.translate("MainWindow", "uint16", None, QtGui.QApplication.UnicodeUTF8)) self.dtypeCombo.setItemText(1, QtGui.QApplication.translate("MainWindow", "uint16", None, QtGui.QApplication.UnicodeUTF8))
self.dtypeCombo.setItemText(2, QtGui.QApplication.translate("MainWindow", "float", None, QtGui.QApplication.UnicodeUTF8)) self.dtypeCombo.setItemText(2, QtGui.QApplication.translate("MainWindow", "float", None, QtGui.QApplication.UnicodeUTF8))
self.scaleCheck.setText(QtGui.QApplication.translate("MainWindow", "Scale Data", None, QtGui.QApplication.UnicodeUTF8)) self.label.setText(QtGui.QApplication.translate("MainWindow", "Data type", None, QtGui.QApplication.UnicodeUTF8))
self.rgbLevelsCheck.setText(QtGui.QApplication.translate("MainWindow", "RGB", None, QtGui.QApplication.UnicodeUTF8)) self.rgbLevelsCheck.setText(QtGui.QApplication.translate("MainWindow", "RGB", None, QtGui.QApplication.UnicodeUTF8))
self.label_2.setText(QtGui.QApplication.translate("MainWindow", "<--->", None, QtGui.QApplication.UnicodeUTF8))
self.label_3.setText(QtGui.QApplication.translate("MainWindow", "<--->", None, QtGui.QApplication.UnicodeUTF8)) self.label_3.setText(QtGui.QApplication.translate("MainWindow", "<--->", None, QtGui.QApplication.UnicodeUTF8))
self.label_2.setText(QtGui.QApplication.translate("MainWindow", "<--->", None, QtGui.QApplication.UnicodeUTF8))
self.label_4.setText(QtGui.QApplication.translate("MainWindow", "<--->", None, QtGui.QApplication.UnicodeUTF8)) self.label_4.setText(QtGui.QApplication.translate("MainWindow", "<--->", None, QtGui.QApplication.UnicodeUTF8))
self.lutCheck.setText(QtGui.QApplication.translate("MainWindow", "Use Lookup Table", None, QtGui.QApplication.UnicodeUTF8)) self.lutCheck.setText(QtGui.QApplication.translate("MainWindow", "Use Lookup Table", None, QtGui.QApplication.UnicodeUTF8))
self.alphaCheck.setText(QtGui.QApplication.translate("MainWindow", "alpha", None, QtGui.QApplication.UnicodeUTF8)) self.alphaCheck.setText(QtGui.QApplication.translate("MainWindow", "alpha", None, QtGui.QApplication.UnicodeUTF8))
self.fpsLabel.setText(QtGui.QApplication.translate("MainWindow", "FPS", None, QtGui.QApplication.UnicodeUTF8)) self.fpsLabel.setText(QtGui.QApplication.translate("MainWindow", "FPS", None, QtGui.QApplication.UnicodeUTF8))
self.rgbCheck.setText(QtGui.QApplication.translate("MainWindow", "RGB", None, QtGui.QApplication.UnicodeUTF8)) self.rgbCheck.setText(QtGui.QApplication.translate("MainWindow", "RGB", None, QtGui.QApplication.UnicodeUTF8))
self.label_5.setText(QtGui.QApplication.translate("MainWindow", "Image size", None, QtGui.QApplication.UnicodeUTF8))
from pyqtgraph.widgets.RawImageWidget import RawImageGLWidget, RawImageWidget from pyqtgraph.widgets.RawImageWidget import RawImageGLWidget, RawImageWidget
from pyqtgraph import GradientWidget, SpinBox, GraphicsView from pyqtgraph import GradientWidget, SpinBox, GraphicsView

View File

@ -1056,6 +1056,46 @@ def colorToAlpha(data, color):
#raise Exception() #raise Exception()
return np.clip(output, 0, 255).astype(np.ubyte) return np.clip(output, 0, 255).astype(np.ubyte)
def downsample(data, n, axis=0, xvals='subsample'):
"""Downsample by averaging points together across axis.
If multiple axes are specified, runs once per axis.
If a metaArray is given, then the axis values can be either subsampled
or downsampled to match.
"""
ma = None
if (hasattr(data, 'implements') and data.implements('MetaArray')):
ma = data
data = data.view(np.ndarray)
if hasattr(axis, '__len__'):
if not hasattr(n, '__len__'):
n = [n]*len(axis)
for i in range(len(axis)):
data = downsample(data, n[i], axis[i])
return data
nPts = int(data.shape[axis] / n)
s = list(data.shape)
s[axis] = nPts
s.insert(axis+1, n)
sl = [slice(None)] * data.ndim
sl[axis] = slice(0, nPts*n)
d1 = data[tuple(sl)]
#print d1.shape, s
d1.shape = tuple(s)
d2 = d1.mean(axis+1)
if ma is None:
return d2
else:
info = ma.infoCopy()
if 'values' in info[axis]:
if xvals == 'subsample':
info[axis]['values'] = info[axis]['values'][::n][:nPts]
elif xvals == 'downsample':
info[axis]['values'] = downsample(info[axis]['values'], n)
return MetaArray(d2, info=info)
def arrayToQPath(x, y, connect='all'): def arrayToQPath(x, y, connect='all'):

View File

@ -6,6 +6,7 @@ import collections
from .. import functions as fn from .. import functions as fn
from .. import debug as debug from .. import debug as debug
from .GraphicsObject import GraphicsObject from .GraphicsObject import GraphicsObject
from ..Point import Point
__all__ = ['ImageItem'] __all__ = ['ImageItem']
class ImageItem(GraphicsObject): class ImageItem(GraphicsObject):
@ -34,20 +35,16 @@ class ImageItem(GraphicsObject):
See :func:`setImage <pyqtgraph.ImageItem.setImage>` for all allowed initialization arguments. See :func:`setImage <pyqtgraph.ImageItem.setImage>` for all allowed initialization arguments.
""" """
GraphicsObject.__init__(self) GraphicsObject.__init__(self)
#self.pixmapItem = QtGui.QGraphicsPixmapItem(self)
#self.qimage = QtGui.QImage()
#self._pixmap = None
self.menu = None self.menu = None
self.image = None ## original image data self.image = None ## original image data
self.qimage = None ## rendered image for display self.qimage = None ## rendered image for display
#self.clipMask = None
self.paintMode = None self.paintMode = None
self.levels = None ## [min, max] or [[redMin, redMax], ...] self.levels = None ## [min, max] or [[redMin, redMax], ...]
self.lut = None self.lut = None
self.autoDownsample = False
#self.clipLevel = None
self.drawKernel = None self.drawKernel = None
self.border = None self.border = None
self.removable = False self.removable = False
@ -142,7 +139,13 @@ class ImageItem(GraphicsObject):
if update: if update:
self.updateImage() self.updateImage()
def setAutoDownsample(self, ads):
self.autoDownsample = ads
self.qimage = None
self.update()
def setOpts(self, update=True, **kargs): def setOpts(self, update=True, **kargs):
if 'lut' in kargs: if 'lut' in kargs:
self.setLookupTable(kargs['lut'], update=update) self.setLookupTable(kargs['lut'], update=update)
if 'levels' in kargs: if 'levels' in kargs:
@ -158,6 +161,10 @@ class ImageItem(GraphicsObject):
if 'removable' in kargs: if 'removable' in kargs:
self.removable = kargs['removable'] self.removable = kargs['removable']
self.menu = None self.menu = None
if 'autoDownsample' in kargs:
self.setAutoDownsample(kargs['autoDownsample'])
if update:
self.update()
def setRect(self, rect): def setRect(self, rect):
"""Scale and translate the image to fit within rect (must be a QRect or QRectF).""" """Scale and translate the image to fit within rect (must be a QRect or QRectF)."""
@ -188,6 +195,9 @@ class ImageItem(GraphicsObject):
opacity (float 0.0-1.0) opacity (float 0.0-1.0)
compositionMode see :func:`setCompositionMode <pyqtgraph.ImageItem.setCompositionMode>` compositionMode see :func:`setCompositionMode <pyqtgraph.ImageItem.setCompositionMode>`
border Sets the pen used when drawing the image border. Default is None. border Sets the pen used when drawing the image border. Default is None.
autoDownsample (bool) If True, the image is automatically downsampled to match the
screen resolution. This improves performance for large images and
reduces aliasing.
================= ========================================================================= ================= =========================================================================
""" """
profile = debug.Profiler() profile = debug.Profiler()
@ -200,6 +210,9 @@ class ImageItem(GraphicsObject):
gotNewData = True gotNewData = True
shapeChanged = (self.image is None or image.shape != self.image.shape) shapeChanged = (self.image is None or image.shape != self.image.shape)
self.image = image.view(np.ndarray) self.image = image.view(np.ndarray)
if self.image.shape[0] > 2**15-1 or self.image.shape[1] > 2**15-1:
if 'autoDownsample' not in kargs:
kargs['autoDownsample'] = True
if shapeChanged: if shapeChanged:
self.prepareGeometryChange() self.prepareGeometryChange()
self.informViewBoundsChanged() self.informViewBoundsChanged()
@ -247,10 +260,9 @@ class ImageItem(GraphicsObject):
defaults.update(kargs) defaults.update(kargs)
return self.setImage(*args, **defaults) return self.setImage(*args, **defaults)
def render(self): def render(self):
# Convert data to QImage for display.
profile = debug.Profiler() profile = debug.Profiler()
if self.image is None or self.image.size == 0: if self.image is None or self.image.size == 0:
return return
@ -258,10 +270,22 @@ class ImageItem(GraphicsObject):
lut = self.lut(self.image) lut = self.lut(self.image)
else: else:
lut = self.lut lut = self.lut
#print lut.shape
#print self.lut
argb, alpha = fn.makeARGB(self.image.transpose((1, 0, 2)[:self.image.ndim]), lut=lut, levels=self.levels) if self.autoDownsample:
# reduce dimensions of image based on screen resolution
o = self.mapToDevice(QtCore.QPointF(0,0))
x = self.mapToDevice(QtCore.QPointF(1,0))
y = self.mapToDevice(QtCore.QPointF(0,1))
w = Point(x-o).length()
h = Point(y-o).length()
xds = max(1, int(1/w))
yds = max(1, int(1/h))
image = fn.downsample(self.image, xds, axis=0)
image = fn.downsample(image, yds, axis=1)
else:
image = self.image
argb, alpha = fn.makeARGB(image.transpose((1, 0, 2)[:image.ndim]), lut=lut, levels=self.levels)
self.qimage = fn.makeQImage(argb, alpha, transpose=False) self.qimage = fn.makeQImage(argb, alpha, transpose=False)
def paint(self, p, *args): def paint(self, p, *args):
@ -277,7 +301,7 @@ class ImageItem(GraphicsObject):
p.setCompositionMode(self.paintMode) p.setCompositionMode(self.paintMode)
profile('set comp mode') profile('set comp mode')
p.drawImage(QtCore.QPointF(0,0), self.qimage) p.drawImage(QtCore.QRectF(0,0,self.image.shape[0],self.image.shape[1]), self.qimage)
profile('p.drawImage') profile('p.drawImage')
if self.border is not None: if self.border is not None:
p.setPen(self.border) p.setPen(self.border)
@ -358,6 +382,11 @@ class ImageItem(GraphicsObject):
return 1,1 return 1,1
return br.width()/self.width(), br.height()/self.height() return br.width()/self.width(), br.height()/self.height()
def viewTransformChanged(self):
if self.autoDownsample:
self.qimage = None
self.update()
#def mousePressEvent(self, ev): #def mousePressEvent(self, ev):
#if self.drawKernel is not None and ev.button() == QtCore.Qt.LeftButton: #if self.drawKernel is not None and ev.button() == QtCore.Qt.LeftButton:
#self.drawAt(ev.pos(), ev) #self.drawAt(ev.pos(), ev)