使用来自skimage的view_as_windows沿二进制圆形线/路径提取窗口/子阵列

时间:2022-02-01 01:48:41

I have an 8bit binary image that shows me the outline of a circle. The outline is only 1 pixel wide. Using the function view_as_windows lets me generate smaller arrays or windows of an input array like this picture, with adjacent overlapping windows. The size of this image is 250×250.

我有一个8位二进制图像,向我显示一个圆的轮廓。轮廓只有1个像素宽。使用view_as_windows函数可以生成像这张图片一样的输入数组的较小数组或窗口,以及相邻的重叠窗口。此图像的大小为250×250。

from skimage.io import imread
from skimage.util import view_as_windows

fname = "C:\\Users\\Username\\Desktop\\Circle.tif"

array = imread(fname)
window_shape = (50, 50)
step = 20

new_array = view_as_windows(array, window_shape, step=step)

This gives me 11×11 overplapping windows. However, I want to extract only windows along the line of the circle so that I can reassemble this object at a later time. The line of a each window should be positioned centrally or in a way so that I have access to the information right under the circle.

这给了我11×11的重叠窗口。但是,我想只沿圆的线提取窗口,以便我可以在以后重新组合这个对象。每个窗口的线应位于*或以某种方式定位,以便我可以访问圆圈下方的信息。

This is what I have tried so far:

这是我到目前为止所尝试的:

First I replaced the values (0) and (255) with (1) and (0), respectively. This way, math is a bit easier.

首先,我分别用(1)和(0)替换值(0)和(255)。这样,数学就容易多了。

array[array==0] = 1
array[array==255] = 0

Then I iterated over the windows in new_array. In this case over the first two dimensions. new_array.shape is (11, 11, 50, 50)

然后我在new_array中遍历窗口。在这种情况下,前两个维度。 new_array.shape是(11,11,50,50)

for j in range(new_array.shape[0]):
    for i in range(new_array.shape[1]):
        Window = new_array[j, i]
        SliceOfWindow = Slice[20:30, 20:30]
        sumAxis0 = np.sum(Slice, axis=0)
        sumSlice = np.sum(sumAxis0)
        if sumSlice >= SliceOfWindow.shape[0]
            imsave(...) 

I created a smaller slice of the shape = (10, 10) within each window, placed in the center. If the sum of each slice >= the length of a slice I have saved that array as an image.

我在每个窗口中创建了一个较小的形状=(10,10)的切片,放在中心。如果每个切片的总和> =切片的长度,我将该数组保存为图像。

Can this be done in a more precise way? Is there a way to yield better results (better windows!)?

这可以用更精确的方式完成吗?有没有办法产生更好的结果(更好的窗户!)?

1 个解决方案

#1


0  

For a convex curve, you could use polar coordinates and sort the edge pixels by their angle through numpy.argsort and numpy.arctan2.

对于凸曲线,您可以使用极坐标并通过numpy.argsort和numpy.arctan2按角度对边缘像素进行排序。

Demo

from skimage import io
import matplotlib.pyplot as plt
import numpy as np

img = io.imread('https://i.stack.imgur.com/r3D6I.png')

# Arbitrary point inside the curve
row_cen, col_cen = 125, 125

# Coordinates of the edge pixels
row, col = np.nonzero(img == 0)

# Put the origin on the lower left corner
x = col - col_cen
y = -(row - row_cen)

# Indices of the centers of the windows
step = 60
idx = np.argsort(np.arctan2(y, x))[::step]

windows = np.zeros_like(img)
size = 15
for _, n in enumerate(idx):
    windows[row[n] - size:row[n] + size, col[n] - size:col[n] + size] = 255

plt.imshow(windows, cmap='gray')
for i, n in enumerate(idx):
    plt.text(col[n], row[n], i, fontsize='14',
             horizontalalignment='center', 
             verticalalignment='center')
plt.show()

使用来自skimage的view_as_windows沿二进制圆形线/路径提取窗口/子阵列

#1


0  

For a convex curve, you could use polar coordinates and sort the edge pixels by their angle through numpy.argsort and numpy.arctan2.

对于凸曲线,您可以使用极坐标并通过numpy.argsort和numpy.arctan2按角度对边缘像素进行排序。

Demo

from skimage import io
import matplotlib.pyplot as plt
import numpy as np

img = io.imread('https://i.stack.imgur.com/r3D6I.png')

# Arbitrary point inside the curve
row_cen, col_cen = 125, 125

# Coordinates of the edge pixels
row, col = np.nonzero(img == 0)

# Put the origin on the lower left corner
x = col - col_cen
y = -(row - row_cen)

# Indices of the centers of the windows
step = 60
idx = np.argsort(np.arctan2(y, x))[::step]

windows = np.zeros_like(img)
size = 15
for _, n in enumerate(idx):
    windows[row[n] - size:row[n] + size, col[n] - size:col[n] + size] = 255

plt.imshow(windows, cmap='gray')
for i, n in enumerate(idx):
    plt.text(col[n], row[n], i, fontsize='14',
             horizontalalignment='center', 
             verticalalignment='center')
plt.show()

使用来自skimage的view_as_windows沿二进制圆形线/路径提取窗口/子阵列