交互式 skimage 查看器画布工具 RectangleTool

Interactive skimage viewer canvastools RectangleTool

我 运行 遇到了 skimage.viewer.canvastools.RectangleTool() 的麻烦,如果能提供任何帮助,我将不胜感激。

我希望选择框是交互式的,即在绘制之后,可以使用手柄编辑所选区域。此功能 appears to workmatplotlib.widgets.RectangleSelector()...例如

from matplotlib.widgets import  RectangleSelector
from pylab import *

def onselect(eclick, erelease):
  'Dummy function'

x = arange(100)/(99.0)
y = sin(x)
fig = figure
ax = subplot(111)
ax.plot(x,y)

test = RectangleSelector(ax, onselect,
                         drawtype='box',
                         interactive=True)
show()

然而,随着 skimage.viewer.canvastools.RectangleTool() 当我使用

rect_tool = RectangleTool(viewer,
                      on_enter=save_region,
                      interactive=True) 

我被扔了:

TypeError: init() got an unexpected keyword argument 'interactive'

...如果我使用

rect_tool = RectangleTool(viewer,
                      on_enter=save_region,
                      rect_props=dict(interactive=True))  

我遇到了这个错误:

AttributeError: Unknown property interactive

我是不是误解了manpage

非常感谢!


这是我所在的位置(RectangleTool 不是交互式的):

import skimage.io
from skimage.viewer import ImageViewer
from skimage.viewer.canvastools import RectangleTool

import numpy as np

from tkinter import Tk
from tkinter.filedialog import askopenfilename
from tkinter.simpledialog import askfloat


Tk().withdraw() # we don't want a full GUI, so keep the root window from appearing
filename = askopenfilename() # show an "Open" dialog box and return the path to the selected file
print(filename)

image_rgb = skimage.io.imread(filename)
image_r = image_rgb[:,:,0] # extract red channel


########
# Does this need to be initialised differently to make the rectangle interactive?
viewer = ImageViewer(image_r)


intensity_dumps = [] # used to store pixel values for selected regions

def save_region(extents):
    global image_r, intensity_dumps
    xmin = np.floor(extents[0]).astype('uint16')
    xmax = np.ceil(extents[1]).astype('uint16')
    ymin = np.floor(extents[2]).astype('uint16')
    ymax = np.ceil(extents[3]).astype('uint16')
    region = image_r[ymin:ymax,xmin:xmax]
    intensity_dumps.append(np.ndarray.flatten(region))
    print('Mean:',np.mean(region))
    print('Std. dev.:',np.std(region))
    print('Max:',np.max(region))


########
# Here is where I believe the problem lies...
rect_tool = RectangleTool(viewer,
                          on_enter=save_region)


thresholded = viewer.show()[0][0]

是的,我想你误会了。请注意 RectangleTool 没有 interactive= 参数。相反,有一个 rect_props 参数,它是一个 字典 。字典项将作为关键字参数传递给 RectangleSelector。所以你想要:RectangleTool(..., rect_props=dict(interactive=True).

感谢 Juan 提出的一些有用的建议。

我的目标是拥有滑块和交互式矩形选择器。最后我决定不使用 scikit-image 库,而是直接使用 matplotlib

这是我的代码的简化版本,供将来遇到类似问题时可能会觉得有用的其他人使用:

from matplotlib.widgets import  RectangleSelector
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider

def onselect(eclick, erelease):
  'Dummy function'

# Lists to store pixel values
intensity_dumps = []

def toggle_selector(event):
    #print(' Key pressed.')
    if event.key in ['Q', 'q'] and toggle_selector.RS.active:
        print(' RectangleSelector deactivated.')
        toggle_selector.RS.set_active(False)
    if event.key in ['B', 'b']:
        extents = toggle_selector.RS.extents
        xmin = np.floor(extents[0]).astype('uint16')
        xmax = np.ceil(extents[1]).astype('uint16')
        ymin = np.floor(extents[2]).astype('uint16')
        ymax = np.ceil(extents[3]).astype('uint16')
#        print(xmin,xmax,ymin,ymax)
        intensity_dumps.append(image_cropped[ymin:ymax,xmin:xmax])


ax = plt.subplot(111)
plt.subplots_adjust(left=0.2, bottom=0.11, top=0.99)

#plt.xlabel('x (pixels)')
#plt.ylabel('y (pixels)')
ax.set_title('Select region; type <b> to save to list')

img = ax.imshow(image, interpolation='nearest', cmap='terrain')
cb = plt.colorbar(img)


ax_cmin = plt.axes([0.2, 0.01, 0.65, 0.03])
ax_cmax  = plt.axes([0.2, 0.06, 0.65, 0.03])

s_cmin = Slider(ax_cmin, 'min percentile', 0, 100, valinit=1)
s_cmax = Slider(ax_cmax, 'max percentile', 0, 100, valinit=99)

def update(val, s=None):
    min_display = np.percentile(image, s_cmin.val)
    max_display = np.percentile(image, s_cmax.val)
    img.set_clim([min_display, max_display])
    plt.draw()

s_cmin.on_changed(update)
s_cmax.on_changed(update)

toggle_selector.RS = RectangleSelector(ax,
                                       onselect,
                                       spancoords='pixels',
                                       drawtype='box',
                                       interactive=True)
plt.connect('key_press_event', toggle_selector)

plt.show()