【问题标题】:Interactive skimage viewer canvastools RectangleTool交互式 skimage 查看器 canvastools RectangleTool
【发布时间】:2019-01-27 20:03:54
【问题描述】:

我遇到了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() 得到了一个意外的关键字参数 'interactive'

...如果我使用

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

我遇到了这个错误:

AttributeError:未知属性交互

我误解了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]

【问题讨论】:

    标签: python image-processing interactive scikit-image viewer


    【解决方案1】:

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

    【讨论】:

    • 谢谢胡安。不幸的是,使用rect_props=dict(interactive=True) 引发了不同的错误:“AttributeError: Unknown property interactive”...
    • 噢噢噢噢。对不起,我误读了文档。 (像你一样大声笑)。 rect_propspatches.Rectangle 的属性,即补丁的视觉特征。基于the code,看起来没有办法将interactive=True 传递给RectangleSelector。但是,代码的后面部分让我认为它应该允许调整大小。如果忽略interactive,是不是不能调整大小?
    • 好建议 :) 不幸的是 active_handle 已经是 True (将其设置为 False 完全阻止交互)。
    • 我在 RectangleTool 上看到 init 使用 Matplotlib 的 RectangleSelector...在我的示例中确实接受 interactive=True 作为参数。如果这个参数可以传递给 scikit-image 的 RectangleTool 初始化,那么我想我们会启动并运行 - 对吗?
    • 我认为是对的。您可以从源代码安装 skimage,更改该行,然后查看它是否有效。 scikit-image.org/docs/dev/install.html 如果是这样,我们欢迎拉取请求来添加它!
    【解决方案2】:

    感谢 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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-26
      • 1970-01-01
      • 1970-01-01
      • 2010-11-19
      • 1970-01-01
      • 1970-01-01
      • 2011-12-21
      相关资源
      最近更新 更多