import numpy as np from numba import jit from scipy.ndimage import label, generate_binary_structure from skimage.morphology import watershed as skwsh from scipy.misc import imread, imsave def neighbors(shape, conn=1): dim = len(shape) block = generate_binary_structure(dim, conn) block[tuple([1]*dim)] = 0 idx = np.where(block>0) idx = np.array(idx, dtype=np.uint8).T idx = np.array(idx-[1]*dim) acc = np.cumprod((1,)+shape[::-1][:-1]) return np.dot(idx, acc[::-1]) @jit def step(img, msk, pts, s, level, up, nbs): cur = 0 while curlevel or not up and img[p]0xfff0:mark[i]=0 def watershed(img, mark, conn=1, up=True): ndim = img.ndim for n in range(ndim): idx = [slice(None) if i==n else [0,-1] for i in range(ndim)] mark[tuple(idx)] = 0xffff nbs = neighbors(img.shape, conn) img = img.ravel() mark = mark.ravel() pts = np.zeros(img.size//3, dtype=np.int64) s, bins = collect(img, mark, nbs, pts) for level in range(len(bins))[::1 if up else -1]: if bins[level]==0:continue s, c = clear(pts, s, 0) s = step(img, mark, pts, s, level, up, nbs) erose(mark) return mark if __name__ == '__main__': from scipy.misc import imread import matplotlib.pyplot as plt from time import time dem = imread('ice.png') mark = imread('mark.png') mark, n = label(mark>0, generate_binary_structure(2,2), output=np.uint16) start = time() #skrst = skwsh(dem, mark, watershed_line=True) print('skimage:', time()-start) watershed(dem, mark.copy()) start = time() watershed(dem, mark, 1) print('mine:', time()-start) imsave('line.png', ((mark>0)*255).astype(np.uint8))