重新排序图像骨架坐标以使interp1d工作b

2024-10-17 06:26:22 发布

您现在位置:Python中文网/ 问答频道 /正文

在一个学校项目中,我正在分析一些elegans图像的中心线。我已经成功地生成了一个合理的阈值,并使用skimage.morphology.skeletonize来生成中心线:

enter image description here

然后我使用np.nonzero来获得中心线的坐标,最终目标是参数化这些点,以获得对中心线几何的一些了解。在

但是,当我使用scipy.interpolate.interp1d时,我得到了这样的混乱: enter image description here 我相当肯定会发生这种情况,因为当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得到的观点:

^{pr2}$

编辑

为了解决订购问题,我遵循了ev-br的建议,从终点开始。我使用了一系列可能的端点方向和ndimage.binary_hit_or_miss函数来隔离端点。然后我编写了一个函数,通过检查每个像素的邻域以查找骨架中的下一个像素,移动到该像素,并保存一个运行列表。这个运行列表成了我要寻找的有序点集。在

然而,在经历了几个小时的挫折之后(包括花了整整半个小时为一个很容易解决的问题而苦恼,在我的一个if语句中用or来代替{}),我意识到,当我插入这些数据点时,它们确实没有提供太多额外的信息。因为我沿着骨架行走收集的数据点本身是参数化的,所以我所做的任何参数化分析都可以使用这些点。所以,虽然我知道如何对点排序是件好事,但无论如何插值并不是最终目标。在

如果有人想看到我为实现这一点而编写的代码,请给我留言,我很乐意与大家分享。在


Tags: fromcropimageimportmodelshownpplt
2条回答

正如您所注意到的,您需要对非零像素进行排序。既然您已经对图像进行了骨架化,您可以从一个端点(它正好有一个邻居)开始,沿着路径一直走到另一个端点。这样,就得到了一个有序的像素坐标列表,然后对其进行插值。但是请注意,如何参数化曲线的问题并不简单,您可能需要做的事情不仅仅是在interp1d

搜索互联网的关键词之一是“分析骨架”。在

与其做一维插值,不如尝试二维插值。这正是你的数据所代表的,而SciPy已经有了一个函数来完成它:

http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.interpolate.interp2d.html

相关问题 更多 >