use*_*250 12 python numpy scipy watershed
我的目标是跟踪其中包含许多不同形状的图形,并将这些形状分割为单独的图像.它是白色的黑色.我是numpy,opencv&co的新手 - 但这是我目前的想法:
我不擅长这些事情,有更好的方法吗?
首先,我试图找到分水岭结果的矩形边界框(这或多或少是一个例子的拼贴画):
from numpy import *
import numpy as np
from scipy import ndimage
np.set_printoptions(threshold=np.nan)
a = np.zeros((512, 512)).astype(np.uint8) #unsigned integer type needed by watershed
y, x = np.ogrid[0:512, 0:512]
m1 = ((y-200)**2 + (x-100)**2 < 30**2)
m2 = ((y-350)**2 + (x-400)**2 < 20**2)
m3 = ((y-260)**2 + (x-200)**2 < 20**2)
a[m1+m2+m3]=1
markers = np.zeros_like(a).astype(int16)
markers[0, 0] = 1
markers[200, 100] = 2
markers[350, 400] = 3
markers[260, 200] = 4
res = ndimage.watershed_ift(a.astype(uint8), markers)
unique(res)
B = argwhere(res.astype(uint8))
(ystart, xstart), (ystop, xstop) = B.min(0), B.max(0) + 1
tr = a[ystart:ystop, xstart:xstop]
print tr
Run Code Online (Sandbox Code Playgroud)
不知何故,当我使用原始数组(a)时,argwhere似乎工作,但在分水岭(res)之后它只是再次输出完整的数组.
下一步可能是找到形状周围的多边形路径,但现在边界框会很棒!
请帮忙!
Joe*_*ton 14
@Hooked已经回答了你的大部分问题,但当他回答时我正在写这篇文章,所以我会发布它,希望它仍然有用......
你正试图跳过一些太多的箍.你不需要watershed_ift
.
您可以scipy.ndimage.label
用来区分布尔数组中的单独对象,并scipy.ndimage.find_objects
查找每个对象的边界框.
让我们稍微分解一下.
import numpy as np
from scipy import ndimage
import matplotlib.pyplot as plt
def draw_circle(grid, x0, y0, radius):
ny, nx = grid.shape
y, x = np.ogrid[:ny, :nx]
dist = np.hypot(x - x0, y - y0)
grid[dist < radius] = True
return grid
# Generate 3 circles...
a = np.zeros((512, 512), dtype=np.bool)
draw_circle(a, 100, 200, 30)
draw_circle(a, 400, 350, 20)
draw_circle(a, 200, 260, 20)
# Label the objects in the array.
labels, numobjects = ndimage.label(a)
# Now find their bounding boxes (This will be a tuple of slice objects)
# You can use each one to directly index your data.
# E.g. a[slices[0]] gives you the original data within the bounding box of the
# first object.
slices = ndimage.find_objects(labels)
#-- Plotting... -------------------------------------
fig, ax = plt.subplots()
ax.imshow(a)
ax.set_title('Original Data')
fig, ax = plt.subplots()
ax.imshow(labels)
ax.set_title('Labeled objects')
fig, axes = plt.subplots(ncols=numobjects)
for ax, sli in zip(axes.flat, slices):
ax.imshow(labels[sli], vmin=0, vmax=numobjects)
tpl = 'BBox:\nymin:{0.start}, ymax:{0.stop}\nxmin:{1.start}, xmax:{1.stop}'
ax.set_title(tpl.format(*sli))
fig.suptitle('Individual Objects')
plt.show()
Run Code Online (Sandbox Code Playgroud)
希望如何找到对象的边界框更清晰.
使用ndimage
scipy中的库.该函数label
在阈值内的每个像素块上放置唯一标记.这标识了唯一的簇(形状).从您的定义开始a
:
from scipy import ndimage
image_threshold = .5
label_array, n_features = ndimage.label(a>image_threshold)
# Plot the resulting shapes
import pylab as plt
plt.subplot(121)
plt.imshow(a)
plt.subplot(122)
plt.imshow(label_array)
plt.show()
Run Code Online (Sandbox Code Playgroud)