From 2f510de2caafdd536c8c8b6329d022202a7374b0 Mon Sep 17 00:00:00 2001 From: Luke Campagnola Date: Wed, 13 Mar 2013 17:17:39 -0400 Subject: [PATCH] Added PolyLineROI.getArrayRegion --- examples/ROIExamples.py | 2 +- pyqtgraph/graphicsItems/ImageItem.py | 4 ++- pyqtgraph/graphicsItems/ROI.py | 42 ++++++++++++++++++++++++---- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/examples/ROIExamples.py b/examples/ROIExamples.py index 56d6b13c..a67e279d 100644 --- a/examples/ROIExamples.py +++ b/examples/ROIExamples.py @@ -56,7 +56,7 @@ rois.append(pg.MultiRectROI([[20, 90], [50, 60], [60, 90]], width=5, pen=(2,9))) rois.append(pg.EllipseROI([60, 10], [30, 20], pen=(3,9))) rois.append(pg.CircleROI([80, 50], [20, 20], pen=(4,9))) #rois.append(pg.LineSegmentROI([[110, 50], [20, 20]], pen=(5,9))) -#rois.append(pg.PolyLineROI([[110, 60], [20, 30], [50, 10]], pen=(6,9))) +rois.append(pg.PolyLineROI([[80, 60], [90, 30], [60, 40]], pen=(6,9), closed=True)) def update(roi): img1b.setImage(roi.getArrayRegion(arr, img1a), levels=(0, arr.max())) diff --git a/pyqtgraph/graphicsItems/ImageItem.py b/pyqtgraph/graphicsItems/ImageItem.py index 123612b8..fad88bee 100644 --- a/pyqtgraph/graphicsItems/ImageItem.py +++ b/pyqtgraph/graphicsItems/ImageItem.py @@ -249,7 +249,7 @@ class ImageItem(GraphicsObject): def render(self): prof = debug.Profiler('ImageItem.render', disabled=True) - if self.image is None: + if self.image is None or self.image.size == 0: return if isinstance(self.lut, collections.Callable): lut = self.lut(self.image) @@ -269,6 +269,8 @@ class ImageItem(GraphicsObject): return if self.qimage is None: self.render() + if self.qimage is None: + return prof.mark('render QImage') if self.paintMode is not None: p.setCompositionMode(self.paintMode) diff --git a/pyqtgraph/graphicsItems/ROI.py b/pyqtgraph/graphicsItems/ROI.py index 4da8fa4a..9cdc8c29 100644 --- a/pyqtgraph/graphicsItems/ROI.py +++ b/pyqtgraph/graphicsItems/ROI.py @@ -802,7 +802,11 @@ class ROI(GraphicsObject): Also returns the transform which maps the ROI into data coordinates. If returnSlice is set to False, the function returns a pair of tuples with the values that would have - been used to generate the slice objects. ((ax0Start, ax0Stop), (ax1Start, ax1Stop))""" + been used to generate the slice objects. ((ax0Start, ax0Stop), (ax1Start, ax1Stop)) + + If the slice can not be computed (usually because the scene/transforms are not properly + constructed yet), then the method returns None. + """ #print "getArraySlice" ## Determine shape of array along ROI axes @@ -810,8 +814,11 @@ class ROI(GraphicsObject): #print " dshape", dShape ## Determine transform that maps ROI bounding box to image coordinates - tr = self.sceneTransform() * fn.invertQTransform(img.sceneTransform()) - + try: + tr = self.sceneTransform() * fn.invertQTransform(img.sceneTransform()) + except np.linalg.linalg.LinAlgError: + return None + ## Modify transform to scale from image coords to data coords #m = QtGui.QTransform() tr.scale(float(dShape[0]) / img.width(), float(dShape[1]) / img.height()) @@ -1737,11 +1744,34 @@ class PolyLineROI(ROI): def shape(self): p = QtGui.QPainterPath() + if len(self.handles) == 0: + return p p.moveTo(self.handles[0]['item'].pos()) for i in range(len(self.handles)): p.lineTo(self.handles[i]['item'].pos()) p.lineTo(self.handles[0]['item'].pos()) - return p + return p + + def getArrayRegion(self, data, img, axes=(0,1), returnMappedCoords=False, **kwds): + sl = self.getArraySlice(data, img, axes=(0,1)) + if sl is None: + return None + sliced = data[sl[0]] + im = QtGui.QImage(sliced.shape[axes[0]], sliced.shape[axes[1]], QtGui.QImage.Format_ARGB32) + im.fill(0x0) + p = QtGui.QPainter(im) + p.setPen(fn.mkPen(None)) + p.setBrush(fn.mkBrush('w')) + p.setTransform(self.itemTransform(img)[0]) + bounds = self.mapRectToItem(img, self.boundingRect()) + p.translate(-bounds.left(), -bounds.top()) + p.drawPath(self.shape()) + p.end() + mask = fn.imageToArray(im)[:,:,0].astype(float) / 255. + shape = [1] * data.ndim + shape[axes[0]] = sliced.shape[axes[0]] + shape[axes[1]] = sliced.shape[axes[1]] + return sliced * mask class LineSegmentROI(ROI): @@ -1845,8 +1875,8 @@ class SpiralROI(ROI): #for h in self.handles: #h['pos'] = h['item'].pos()/self.state['size'][0] - def stateChanged(self): - ROI.stateChanged(self) + def stateChanged(self, finish=True): + ROI.stateChanged(self, finish=finish) if len(self.handles) > 1: self.path = QtGui.QPainterPath() h0 = Point(self.handles[0]['item'].pos()).length()