来自 df 中像素的复杂形状的平均直径,Python
Average diameter of complex shapes from pixels in df, Python
我有一个由多个粒子组成的 DataFrame,它的组号 (1,2,3,4) 如下所示:
Groups:
[[0 0 0 1 1 1 0 0]
[0 2 0 1 1 1 0 0]
[0 0 0 1 1 1 0 0]
[0 0 0 0 1 0 0 0]
[0 3 3 0 0 4 0 0]
[0 3 0 0 0 4 0 0]
[0 0 0 0 0 4 0 0]
[0 0 0 0 0 4 0 0]]
Number of particles: 4
然后我计算了粒子的面积并创建了一个 DataFrame(假设 1 像素 = 1 纳米):
Particle # Size [pixel #] A [nm2]
1 1 10 10
2 2 1 1
3 3 3 3
4 4 4 4
现在我要计算粒子的直径。然而,颗粒的形状很复杂,因此我正在寻找一种计算平均直径的方法(考虑到形状不是完美的圆形)并在 A [nm2] 旁边添加另一列,其中包含平均直径。
这可能吗?
这是我的完整代码:
import numpy as np
from skimage import measure
import pandas as pd
final = [
[0, 0, 0, 255, 255, 255, 0, 0],
[0, 255, 0, 255, 255, 255, 0, 0],
[0, 0, 0, 255, 255, 255, 0, 0, ],
[0, 0, 0, 0, 255, 0, 0, 0],
[0, 255, 255, 0, 0, 255, 0, 0],
[0, 255, 0, 0, 0, 255, 0, 0],
[0, 0, 0, 0, 0, 255, 0, 0],
[0, 0, 0, 0, 0, 255, 0, 0]
]
final = np.asarray(final)
groups, group_count = measure.label(final > 0, return_num = True, connectivity = 1)
print('Groups: \n', groups)
print(f'Number of particles: {group_count}')
df = (pd.DataFrame(dict(zip(['Particle #', 'Size [pixel #]'],
np.unique(groups, return_counts=True))))
.loc[lambda d: d['Particle #'].ne(0)]
)
pixel_nm_size = 1*1
df['A [nm2]'] = df['Size [pixel #]'] * pixel_nm_size
感谢任何帮助!
IIUC,您可以使用自定义函数找到边界框的 height/width 并计算两个维度的平均值:
def get_diameter(g):
a = (groups==g)
h = (a.sum(1)!=0).sum()
w = (a.sum(0)!=0).sum()
return (h+w)/2
df['diameter'] = df['Particle #'].map(get_diameter)
输出:
Particle # Size [pixel #] A [nm2] diameter
1 1 10 10 3.5
2 2 1 1 1.0
3 3 3 3 2.0
4 4 4 4 2.5
我想你正在寻找 regionprops。
具体来说,equivalent_diameter
,或者 perimeter
。
props = measure.regionprops_table(groups, properties = ['label', 'equivalent_diameter', 'perimeter'])
df = pd.DataFrame(props)
编辑
来自文档:
equivalent_diameter_area: float
The diameter of a circle with the same area as the region.
因此,该函数采用您标记的区域,测量面积并用该区域构建一个圆(每个区域只有一个这样的圆)。
然后它测量圆的直径。
你也可以看看major_axis_length
和minor_axis_length
。这些是通过在对象周围拟合一个椭圆并测量定义它的长轴和短轴来计算的。
我有一个由多个粒子组成的 DataFrame,它的组号 (1,2,3,4) 如下所示:
Groups:
[[0 0 0 1 1 1 0 0]
[0 2 0 1 1 1 0 0]
[0 0 0 1 1 1 0 0]
[0 0 0 0 1 0 0 0]
[0 3 3 0 0 4 0 0]
[0 3 0 0 0 4 0 0]
[0 0 0 0 0 4 0 0]
[0 0 0 0 0 4 0 0]]
Number of particles: 4
然后我计算了粒子的面积并创建了一个 DataFrame(假设 1 像素 = 1 纳米):
Particle # Size [pixel #] A [nm2]
1 1 10 10
2 2 1 1
3 3 3 3
4 4 4 4
现在我要计算粒子的直径。然而,颗粒的形状很复杂,因此我正在寻找一种计算平均直径的方法(考虑到形状不是完美的圆形)并在 A [nm2] 旁边添加另一列,其中包含平均直径。
这可能吗?
这是我的完整代码:
import numpy as np
from skimage import measure
import pandas as pd
final = [
[0, 0, 0, 255, 255, 255, 0, 0],
[0, 255, 0, 255, 255, 255, 0, 0],
[0, 0, 0, 255, 255, 255, 0, 0, ],
[0, 0, 0, 0, 255, 0, 0, 0],
[0, 255, 255, 0, 0, 255, 0, 0],
[0, 255, 0, 0, 0, 255, 0, 0],
[0, 0, 0, 0, 0, 255, 0, 0],
[0, 0, 0, 0, 0, 255, 0, 0]
]
final = np.asarray(final)
groups, group_count = measure.label(final > 0, return_num = True, connectivity = 1)
print('Groups: \n', groups)
print(f'Number of particles: {group_count}')
df = (pd.DataFrame(dict(zip(['Particle #', 'Size [pixel #]'],
np.unique(groups, return_counts=True))))
.loc[lambda d: d['Particle #'].ne(0)]
)
pixel_nm_size = 1*1
df['A [nm2]'] = df['Size [pixel #]'] * pixel_nm_size
感谢任何帮助!
IIUC,您可以使用自定义函数找到边界框的 height/width 并计算两个维度的平均值:
def get_diameter(g):
a = (groups==g)
h = (a.sum(1)!=0).sum()
w = (a.sum(0)!=0).sum()
return (h+w)/2
df['diameter'] = df['Particle #'].map(get_diameter)
输出:
Particle # Size [pixel #] A [nm2] diameter
1 1 10 10 3.5
2 2 1 1 1.0
3 3 3 3 2.0
4 4 4 4 2.5
我想你正在寻找 regionprops。
具体来说,equivalent_diameter
,或者 perimeter
。
props = measure.regionprops_table(groups, properties = ['label', 'equivalent_diameter', 'perimeter'])
df = pd.DataFrame(props)
编辑
来自文档:
equivalent_diameter_area: float The diameter of a circle with the same area as the region.
因此,该函数采用您标记的区域,测量面积并用该区域构建一个圆(每个区域只有一个这样的圆)。 然后它测量圆的直径。
你也可以看看major_axis_length
和minor_axis_length
。这些是通过在对象周围拟合一个椭圆并测量定义它的长轴和短轴来计算的。