如何将 scikit 图像轮廓存储在具有单个顶点和每行轮廓数的 Pandas DataFrame 中

How to store scikit-image contours in a Pandas DataFrame with a single vertex and a contour number per row

我正在使用 this scikit-image demo 的修改版本从图像的分水岭分割产生的边缘创建轮廓。在这个结果中,每一层只有一个轮廓,由行列索引对组成。

像演示中那样显示轮廓很容易。但我想做的是使用 enumerate 循环将每个轮廓的每个顶点附加到 Pandas DataFrame,分隔行和列索引,然后添加一个 level/contour 索引在单独的专栏中。

为了说明,我将从一个小玩具示例开始,其中每个轮廓只有一个索引。使用此代码:

np.random.seed(131)
test = np.random.randint(50, size=5)
n_list = []
t_list = []
for n, t in enumerate(test):
    n_list.append(n)
    t_list.append(t)
contours_df = pd.DataFrame({'contour': n_list, 'contour': t_list})
contours_df 

我得到这个 DataFrame:

比较有代表性的例子是这样的:

np.random.seed(131)
test1 = np.random.randint(50, size=(5, 2,  2))
n_list1 = []
t_list1 = []
for n1, t1 in enumerate(test1):
    n_list1.append(n1)
    t_list1.append(t1)
contours_df1 = pd.DataFrame({'contour': n_list1, 'points': t_list1})
contours_df1

这给了我这个 DataFrame:

我可以使用 XlsxWriter 将其导出到 Excel 文件,如下所示:

# using XlsxWriter documentation example
writer = pd.ExcelWriter('contours_df1.xlsx', engine='xlsxwriter')
contours_df1.to_excel(writer, sheet_name='Sheet1')
writer.save()

得到这个:

但我真正想要的是拆分轮廓以获得类似这样的最终 Excel 输出:

您快要达到目标了,您只需要稍微玩一下:

enumerate 方法按预期工作。当我们枚举一个可迭代的 python 对象时,我们得到对象元素和 "pointer" 之间的 1-1 相关性,范围从 0len(iterable_object)-1.
从文档中查看此示例:

>>> seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]

现在实现您在这里向我们展示的内容的一种方法是使用从 enumerate 生成的指针 2 次并相应地拆分每个 test 元素的内容:

np.random.seed(131)
test1 = np.random.randint(50, size=(5, 2,  2))
contour_lst = []
row_lst = []
column_lst = []
for n, t_elem in enumerate(test1):
    # First square coordinates for this contour.
    contour_lst.append(n)
    row_lst.append(t_elem[0][0])
    column_lst.append(t_elem[0][1])
    # Second square coordinates for this contour.
    contour_lst.append(n)
    row_lst.append(t_elem[1][0])
    column_lst.append(t_elem[1][1])

contours_df1 = pd.DataFrame({
    'contour': contour_lst, 
    'row': row_lst,
    'column': column_lst,
})

我会使用 pandas 串联。对于大小合理的数据,是否为每列构建一个列表取决于个人喜好(尽管您需要第二个嵌套循环以允许任意大小的轮廓)。对于更大的数据,我认为这种方法应该更快,因为它在可能的情况下使用 NumPy/pandas 向量化。

这是一个例子:

import numpy as np
import pandas as pd

contours = [np.random.random((i, 2)
            for i in np.random.randint(3, 10, size=5)]

dataframes = []
for contour_id, contour in enumerate(contours):
    current_dataframe = pd.DataFrame(contour, columns=['row', 'column'])
    current_dataframe['contour'] = contour_id
    dataframes.append(current_dataframe)
contours_data = pd.concat(dataframes)

contours_data.to_excel('filename.xlsx', sheet_name='Sheet1')

旁注:如果您只写一个 sheet.

,则不需要创建 ExcelWriter