Commit 34802c8a authored by Luke Campagnola's avatar Luke Campagnola
Browse files

Added pg.gaussianFilter, removed all dependency on gaussian_filter

parent ff697ce4
......@@ -11,7 +11,6 @@ a 2D plane and interpolate data along that plane to generate a slice image
import initExample
import numpy as np
import scipy
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
......
......@@ -12,7 +12,6 @@ from pyqtgraph.flowchart.library.common import CtrlNode
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
import numpy as np
import scipy.ndimage
app = QtGui.QApplication([])
......@@ -44,7 +43,7 @@ win.show()
## generate random input data
data = np.random.normal(size=(100,100))
data = 25 * scipy.ndimage.gaussian_filter(data, (5,5))
data = 25 * pg.gaussianFilter(data, (5,5))
data += np.random.normal(size=(100,100))
data[40:60, 40:60] += 15.0
data[30:50, 30:50] += 15.0
......@@ -90,7 +89,7 @@ class ImageViewNode(Node):
## CtrlNode is just a convenience class that automatically creates its
## control widget based on a simple data structure.
class UnsharpMaskNode(CtrlNode):
"""Return the input data passed through scipy.ndimage.gaussian_filter."""
"""Return the input data passed through pg.gaussianFilter."""
nodeName = "UnsharpMask"
uiTemplate = [
('sigma', 'spin', {'value': 1.0, 'step': 1.0, 'range': [0.0, None]}),
......@@ -110,7 +109,7 @@ class UnsharpMaskNode(CtrlNode):
# CtrlNode has created self.ctrls, which is a dict containing {ctrlName: widget}
sigma = self.ctrls['sigma'].value()
strength = self.ctrls['strength'].value()
output = dataIn - (strength * scipy.ndimage.gaussian_filter(dataIn, (sigma,sigma)))
output = dataIn - (strength * pg.gaussianFilter(dataIn, (sigma,sigma)))
return {'dataOut': output}
......
......@@ -12,7 +12,6 @@ from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph.opengl as gl
import pyqtgraph as pg
import numpy as np
import scipy.ndimage as ndi
app = QtGui.QApplication([])
w = gl.GLViewWidget()
......@@ -22,8 +21,8 @@ w.setWindowTitle('pyqtgraph example: GLImageItem')
## create volume data set to slice three images from
shape = (100,100,70)
data = ndi.gaussian_filter(np.random.normal(size=shape), (4,4,4))
data += ndi.gaussian_filter(np.random.normal(size=shape), (15,15,15))*15
data = pg.gaussianFilter(np.random.normal(size=shape), (4,4,4))
data += pg.gaussianFilter(np.random.normal(size=shape), (15,15,15))*15
## slice out three planes, convert to RGBA for OpenGL texture
levels = (-0.08, 0.08)
......
......@@ -10,7 +10,6 @@ import initExample
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
import pyqtgraph.opengl as gl
import scipy.ndimage as ndi
import numpy as np
## Create a GL View widget to display data
......@@ -29,7 +28,7 @@ w.addItem(g)
## Simple surface plot example
## x, y values are not specified, so assumed to be 0:50
z = ndi.gaussian_filter(np.random.normal(size=(50,50)), (1,1))
z = pg.gaussianFilter(np.random.normal(size=(50,50)), (1,1))
p1 = gl.GLSurfacePlotItem(z=z, shader='shaded', color=(0.5, 0.5, 1, 1))
p1.scale(16./49., 16./49., 1.0)
p1.translate(-18, 2, 0)
......@@ -46,7 +45,7 @@ w.addItem(p2)
## Manually specified colors
z = ndi.gaussian_filter(np.random.normal(size=(50,50)), (1,1))
z = pg.gaussianFilter(np.random.normal(size=(50,50)), (1,1))
x = np.linspace(-12, 12, 50)
y = np.linspace(-12, 12, 50)
colors = np.ones((50,50,4), dtype=float)
......
......@@ -7,7 +7,6 @@ Use a HistogramLUTWidget to control the contrast / coloration of an image.
import initExample
import numpy as np
import scipy.ndimage as ndi
from pyqtgraph.Qt import QtGui, QtCore
import pyqtgraph as pg
......@@ -34,7 +33,7 @@ l.addWidget(v, 0, 0)
w = pg.HistogramLUTWidget()
l.addWidget(w, 0, 1)
data = ndi.gaussian_filter(np.random.normal(size=(256, 256)), (20, 20))
data = pg.gaussianFilter(np.random.normal(size=(256, 256)), (20, 20))
for i in range(32):
for j in range(32):
data[i*8, j*8] += .1
......
......@@ -14,7 +14,6 @@ displaying and analyzing 2D and 3D data. ImageView provides:
import initExample
import numpy as np
import scipy.ndimage
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
......@@ -29,7 +28,7 @@ win.show()
win.setWindowTitle('pyqtgraph example: ImageView')
## Create random 3D data set with noisy signals
img = scipy.ndimage.gaussian_filter(np.random.normal(size=(200, 200)), (5, 5)) * 20 + 100
img = pg.gaussianFilter(np.random.normal(size=(200, 200)), (5, 5)) * 20 + 100
img = img[np.newaxis,:,:]
decay = np.exp(-np.linspace(0,0.3,100))[:,np.newaxis,np.newaxis]
data = np.random.normal(size=(100, 200, 200))
......
......@@ -13,7 +13,6 @@ import initExample ## Add path to library (just for examples; you do not need th
from pyqtgraph.Qt import QtGui, QtCore, USE_PYSIDE
import numpy as np
import pyqtgraph as pg
import scipy.ndimage as ndi
import pyqtgraph.ptime as ptime
if USE_PYSIDE:
......@@ -95,10 +94,13 @@ def mkData():
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))
data = pg.gaussianFilter(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))
print frames, width, height, loc, scale
data = pg.gaussianFilter(data, (0, 6, 6))
print data[0]
pg.image(data)
if dtype[0] != 'float':
data = np.clip(data, 0, mx)
data = data.astype(dt)
......
......@@ -7,7 +7,6 @@ the mouse.
import initExample ## Add path to library (just for examples; you do not need this)
import numpy as np
import scipy.ndimage as ndi
import pyqtgraph as pg
from pyqtgraph.Qt import QtGui, QtCore
from pyqtgraph.Point import Point
......@@ -33,8 +32,8 @@ p1.setAutoVisible(y=True)
#create numpy arrays
#make the numbers large to show that the xrange shows data from 10000 to all the way 0
data1 = 10000 + 15000 * ndi.gaussian_filter(np.random.random(size=10000), 10) + 3000 * np.random.random(size=10000)
data2 = 15000 + 15000 * ndi.gaussian_filter(np.random.random(size=10000), 10) + 3000 * np.random.random(size=10000)
data1 = 10000 + 15000 * pg.gaussianFilter(np.random.random(size=10000), 10) + 3000 * np.random.random(size=10000)
data2 = 15000 + 15000 * pg.gaussianFilter(np.random.random(size=10000), 10) + 3000 * np.random.random(size=10000)
p1.plot(data1, pen="r")
p1.plot(data2, pen="g")
......
......@@ -10,7 +10,6 @@ import initExample ## Add path to library (just for examples; you do not need th
from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
import scipy.ndimage as ndi
app = QtGui.QApplication([])
......@@ -18,7 +17,7 @@ app = QtGui.QApplication([])
frames = 200
data = np.random.normal(size=(frames,30,30), loc=0, scale=100)
data = np.concatenate([data, data], axis=0)
data = ndi.gaussian_filter(data, (10, 10, 10))[frames/2:frames + frames/2]
data = pg.gaussianFilter(data, (10, 10, 10))[frames/2:frames + frames/2]
data[:, 15:16, 15:17] += 1
win = pg.GraphicsWindow()
......
......@@ -2,6 +2,7 @@
from ...Qt import QtCore, QtGui
from ..Node import Node
from . import functions
from ... import functions as pgfn
from .common import *
import numpy as np
......@@ -161,7 +162,7 @@ class Gaussian(CtrlNode):
import scipy.ndimage
except ImportError:
raise Exception("GaussianFilter node requires the package scipy.ndimage.")
return scipy.ndimage.gaussian_filter(data, self.ctrls['sigma'].value())
return pgfn.gaussianFilter(data, self.ctrls['sigma'].value())
class Derivative(CtrlNode):
......
......@@ -1120,6 +1120,45 @@ def colorToAlpha(data, color):
#raise Exception()
return np.clip(output, 0, 255).astype(np.ubyte)
def gaussianFilter(data, sigma):
"""
Drop-in replacement for scipy.ndimage.gaussian_filter.
(note: results are only approximately equal to the output of
gaussian_filter)
"""
if np.isscalar(sigma):
sigma = (sigma,) * data.ndim
baseline = data.mean()
filtered = data - baseline
for ax in range(data.ndim):
s = sigma[ax]
if s == 0:
continue
# generate 1D gaussian kernel
ksize = int(s * 6)
x = np.arange(-ksize, ksize)
kernel = np.exp(-x**2 / (2*s**2))
kshape = [1,] * data.ndim
kshape[ax] = len(kernel)
kernel = kernel.reshape(kshape)
# convolve as product of FFTs
shape = data.shape[ax] + ksize
scale = 1.0 / (abs(s) * (2*np.pi)**0.5)
filtered = scale * np.fft.irfft(np.fft.rfft(filtered, shape, axis=ax) *
np.fft.rfft(kernel, shape, axis=ax),
axis=ax)
# clip off extra data
sl = [slice(None)] * data.ndim
sl[ax] = slice(filtered.shape[ax]-data.shape[ax],None,None)
filtered = filtered[sl]
return filtered + baseline
def downsample(data, n, axis=0, xvals='subsample'):
"""Downsample by averaging points together across axis.
......@@ -1556,7 +1595,7 @@ def traceImage(image, values, smooth=0.5):
paths = []
for i in range(diff.shape[-1]):
d = (labels==i).astype(float)
d = ndi.gaussian_filter(d, (smooth, smooth))
d = gaussianFilter(d, (smooth, smooth))
lines = isocurve(d, 0.5, connected=True, extendToEdge=True)
path = QtGui.QPainterPath()
for line in lines:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment