在一个学校项目中,我正在分析一些elegans图像的中心线。我已经成功地生成了一个合理的阈值,并使用skimage.morphology.skeletonize
来生成中心线:
然后我使用np.nonzero
来获得中心线的坐标,最终目标是参数化这些点,以获得对中心线几何的一些了解。在
但是,当我使用scipy.interpolate.interp1d
时,我得到了这样的混乱:
我相当肯定会发生这种情况,因为当np.nonzero
查找非零值时,它会自下而上、从右向左排列,并按这样的顺序排列点,这就是为什么在插值过程中会出现锯齿效应。有什么方法可以重新排列这些点,使interp1d
更好地处理它们?在
这是我的代码:
import cv2
import numpy as np
from matplotlib import pyplot as plt
from scipy import ndimage
from scipy import stats
from scipy import misc
from skimage.morphology import skeletonize
from scipy.interpolate import interp1d
"""Curved Worm"""
img = misc.imread("model_image_crop_curved.tif")
plt.imshow(img)
plt.show()
imgThresh = img>200
plt.imshow(imgThresh)
plt.show()
misc.imsave('model_image_crop_curved_binary.tif',imgThresh)
imgSkel = skeletonize(imgThresh)
plt.imshow(imgSkel)
plt.show()
misc.imsave('model_image_crop_curved_skeleton.tif',imgSkel)
cv2Skel = cv2.imread('model_image_crop_curved_skeleton.tif',cv2.IMREAD_GRAYSCALE)
skelCoord = np.nonzero(imgSkel)
x = skelCoord[1]
y = skelCoord[0]
plt.plot(x,y,'.')
plt.show()
i = np.arange(len(x))
interp_i = np.linspace(0,i.max(),5*i.max())
interpKind = 'linear'
xi = interp1d(i,x,kind=interpKind)(interp_i)
yi = interp1d(i,y,kind=interpKind)(interp_i)
fig, ax = plt.subplots()
ax.plot(xi,yi,'b-')
ax.plot(x,y,'ko')
plt.show()
以下是我从np.nonzero
得到的观点:
编辑
为了解决订购问题,我遵循了ev-br的建议,从终点开始。我使用了一系列可能的端点方向和ndimage.binary_hit_or_miss
函数来隔离端点。然后我编写了一个函数,通过检查每个像素的邻域以查找骨架中的下一个像素,移动到该像素,并保存一个运行列表。这个运行列表成了我要寻找的有序点集。在
然而,在经历了几个小时的挫折之后(包括花了整整半个小时为一个很容易解决的问题而苦恼,在我的一个if
语句中用or
来代替{
如果有人想看到我为实现这一点而编写的代码,请给我留言,我很乐意与大家分享。在
正如您所注意到的,您需要对非零像素进行排序。既然您已经对图像进行了骨架化,您可以从一个端点(它正好有一个邻居)开始,沿着路径一直走到另一个端点。这样,就得到了一个有序的像素坐标列表,然后对其进行插值。但是请注意,如何参数化曲线的问题并不简单,您可能需要做的事情不仅仅是在
interp1d
搜索互联网的关键词之一是“分析骨架”。在
与其做一维插值,不如尝试二维插值。这正是你的数据所代表的,而SciPy已经有了一个函数来完成它:
http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.interpolate.interp2d.html
相关问题 更多 >
编程相关推荐