Skimage.draw.ellipse 生成两条不需要的线
Skimage.draw.ellipse generates two undesired lines
我有一个布尔图像,其中零是背景,我想绘制包含从 skimage.measure.regionprops
检索到的对象的长轴和短轴的椭圆。模块 skimage.draw.ellipse_perimeter
生成了预期的椭圆,但也生成了两条不需要的线。
代码(输入图像为here):
import skimage
import skimage.draw
from skimage.measure import label
from skimage.measure import regionprops
import matplotlib.pyplot as plt
# load example image
TP_mask = plt.imread('https://i.stack.imgur.com/UYLE0.png')
# connect region with same integer value
region = label(TP_mask)
# obtain RegionProperties
props = regionprops(region)
props = props[0]
# define centroid
y0,x0 = props.centroid
# draw ellipse perimeter
rr,cc = skimage.draw.ellipse_perimeter(int(x0),int(y0),int(props.minor_axis_length*0.5),int(props.major_axis_length*0.5), orientation = props.orientation)
# plot
plt.plot(rr,cc, color = 'yellow')
plt.imshow(TP_mask, cmap = 'gray')
plt.show()
但是,如果我创建一个简化的示例如下,我将获得预期的椭圆。有人可以帮助我了解我做错了什么吗?
import numpy as np
img = np.zeros((1000,1000))
img[200:800,200:400] = 1
region = label(img)
props = regionprops(region)
props = props[0]
y0,x0 = props.centroid
rr,cc = skimage.draw.ellipse_perimeter(int(x0),int(y0),int(props.minor_axis_length*0.5),int(props.major_axis_length*0.5), orientation = props.orientation)
plt.plot(rr,cc, color = 'yellow')
plt.imshow(img, cmap = 'gray')
plt.show()
原来draw
模块返回的坐标是设计成索引到数组中的,如图in this example,而不是plot:
rr, cc = ellipse_perimeter(120, 400, 60, 20, orientation=math.pi / 4.)
img[rr, cc, :] = (1, 0, 1)
要使用 plt.plot
并绘制线图,坐标需要围绕 circle/ellipse 进行排序。默认情况下,它们 未 正确排序,因为椭圆实际上是在四个单独的象限中绘制的,您可以通过 looking at the relevant part of the source code 找到它们。 (一个线索:线条恰好位于椭圆垂直或水平的位置。)
因为你有一个凸面,计算每个点和椭圆中心之间的角度就足以对点进行排序。请尝试以下操作:
fig, ax = plt.subplots()
_ = ax.imshow(TP_mask, cmap='gray')
angle = np.arctan2(rr - np.mean(rr), cc - np.mean(cc))
sorted_by_angle = np.argsort(angle)
rrs = rr[sorted_by_angle]
ccs = cc[sorted_by_angle]
_ = ax.plot(rrs, ccs, color='red')
给出:
我有一个布尔图像,其中零是背景,我想绘制包含从 skimage.measure.regionprops
检索到的对象的长轴和短轴的椭圆。模块 skimage.draw.ellipse_perimeter
生成了预期的椭圆,但也生成了两条不需要的线。
代码(输入图像为here):
import skimage
import skimage.draw
from skimage.measure import label
from skimage.measure import regionprops
import matplotlib.pyplot as plt
# load example image
TP_mask = plt.imread('https://i.stack.imgur.com/UYLE0.png')
# connect region with same integer value
region = label(TP_mask)
# obtain RegionProperties
props = regionprops(region)
props = props[0]
# define centroid
y0,x0 = props.centroid
# draw ellipse perimeter
rr,cc = skimage.draw.ellipse_perimeter(int(x0),int(y0),int(props.minor_axis_length*0.5),int(props.major_axis_length*0.5), orientation = props.orientation)
# plot
plt.plot(rr,cc, color = 'yellow')
plt.imshow(TP_mask, cmap = 'gray')
plt.show()
但是,如果我创建一个简化的示例如下,我将获得预期的椭圆。有人可以帮助我了解我做错了什么吗?
import numpy as np
img = np.zeros((1000,1000))
img[200:800,200:400] = 1
region = label(img)
props = regionprops(region)
props = props[0]
y0,x0 = props.centroid
rr,cc = skimage.draw.ellipse_perimeter(int(x0),int(y0),int(props.minor_axis_length*0.5),int(props.major_axis_length*0.5), orientation = props.orientation)
plt.plot(rr,cc, color = 'yellow')
plt.imshow(img, cmap = 'gray')
plt.show()
原来draw
模块返回的坐标是设计成索引到数组中的,如图in this example,而不是plot:
rr, cc = ellipse_perimeter(120, 400, 60, 20, orientation=math.pi / 4.)
img[rr, cc, :] = (1, 0, 1)
要使用 plt.plot
并绘制线图,坐标需要围绕 circle/ellipse 进行排序。默认情况下,它们 未 正确排序,因为椭圆实际上是在四个单独的象限中绘制的,您可以通过 looking at the relevant part of the source code 找到它们。 (一个线索:线条恰好位于椭圆垂直或水平的位置。)
因为你有一个凸面,计算每个点和椭圆中心之间的角度就足以对点进行排序。请尝试以下操作:
fig, ax = plt.subplots()
_ = ax.imshow(TP_mask, cmap='gray')
angle = np.arctan2(rr - np.mean(rr), cc - np.mean(cc))
sorted_by_angle = np.argsort(angle)
rrs = rr[sorted_by_angle]
ccs = cc[sorted_by_angle]
_ = ax.plot(rrs, ccs, color='red')
给出: