如何在bokeh中选择图像的区域

4
在一个web应用程序中,我想让用户使用bokeh的优美框/套索选择工具选择绘制图像中感兴趣的区域。然后,我希望在python中接收选定的像素以进行进一步操作。
对于散点图来说,这与示例画廊类似,很容易实现。
import bokeh.plotting
import numpy as np

# data
X = np.linspace(0, 10, 20)
def f(x): return np.random.random(len(x))

# plot and add to document
fig = bokeh.plotting.figure(x_range=(0, 10), y_range=(0, 10),
    tools="pan,wheel_zoom,box_select,lasso_select,reset")
plot = fig.scatter(X, f(X))
#plot = fig.image([np.random.random((10,10))*255], dw=[10], dh=[10])
bokeh.plotting.curdoc().add_root(fig)

# callback
def callback(attr, old, new):
    # easily access selected points:
    print sorted(new['1d']['indices'])
    print sorted(plot.data_source.selected['1d']['indices'])
    plot.data_source.data = {'x':X, 'y':f(X)}
plot.data_source.on_change('selected', callback)

然而,如果我用其他图表替换散点图,则需要进行以下步骤。
plot = fig.image([np.random.random((10,10))*255], dw=[10], dh=[10])

使用图像上的选择工具不会改变plot.data_source.selected中的任何内容。

我相信这是预期的行为(也很合理),但如果我想选择图像的像素怎么办?当然,我可以在图像上放置一个不可见散点网格,但是否有更优雅的方法来实现这一点呢?

1个回答

1

看起来您需要的工具实际上是BoxEditTool。请注意,BoxEditTool需要一个字形列表(通常这些将是Rect实例),用于渲染ROI,并且监听更改应该使用以下设置:

rect_glyph_source.on_change('data', callback)

这将在您对ROI进行任何更改时触发“回调”函数。
相关的ColumnDataSource实例(在此示例中为“rect_glyph_source”)将被更新,以便“x”和“y”键列出图像坐标空间中每个ROI的中心位置,当然,“width”和“height”描述其大小。据我所知,目前没有内置方法来提取数据本身,因此您需要执行类似以下内容的操作:
rois = rect_glyph_source.data
roi_index = 0 # x, y, width and height are lists, and each ROI has its own index

x_center = rois['x'][roi_index]
width = rois['width'][roi_index]
y_center = rois['y'][roi_index]
height = rois['height'][roi_index]

x_start = int(x_center - 0.5 * width)
x_end = int(x_center + 0.5 * width)
y_start = int(y_center - 0.5 * height)
y_end = int(y_center + 0.5 * height)

roi_data = image_plot.source.data['image'][0][y_start:y_end, x_start:x_end]

重要提示:在当前版本的 Bokeh(0.13.0)中,存在服务器上的 BoxEditTool 同步问题,无法正常使用。这个问题将在下一个官方 Bokeh 版本中得到修复。有关更多信息和临时解决方案,请参见 this answerthis discussion


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接