尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
电镜照片颗粒统计自动化:scikit-image 批量提取粒径分布
摘要数电镜照片里的纳米颗粒是表征岗最枯燥的活——手动数几百个颗粒要一下午还会引入主观偏倚。本文用 scikit-image 写一个批量颗粒统计管线读图→预处理→分水岭分割→像素-纳米换算→粒径分布拟合并讲清过分割、边缘颗粒、尺度标定三个最容易翻车的环节。依赖scikit-image、numpy、matplotlib。一、为什么必须自动计数TEM/cryo-EM 照片的粒径统计审稿人和 CMC 审评都认数出来的分布number-weighted因为它直接反映颗粒真实尺寸——不像 DLS 是强度加权少量大颗粒能主导信号。但手动计数有三个系统性问题取样偏倚人会不自觉多数好看的、孤立的颗粒重叠和粘连的跳过——恰好把分布尾部切掉了样本量不足一张照片通常只有 50-150 个颗粒要 300 才能让分布的 D50 稳定手动数意味着 3-5 张照片;不可重复两个人数同一张照片结果可以差 10%。自动计数的意义就是把这件事从一下午变成一条命令同时让取样规则显式化、可审计。二、完整管线代码2.1 读图与预处理电镜照片常见问题背景灰度不均照明场漂移、噪声颗粒感、对比度低。预处理的目标是让阈值分割变稳importnumpyasnpimportmatplotlib.pyplotaspltfromskimageimportio,filters,morphology,measure,segmentation,featurefromscipyimportndimageasndi imgio.imread(particles.tif,as_grayTrue)# 1) 背景校正大半径开运算估计背景再相减照明不均时必需backgroundmorphology.opening(img,morphology.disk(25))corrimg-background# 2) 去噪 增强fromskimageimportexposure corrfilters.median(corr,morphology.disk(2))correxposure.equalize_adapthist(corr.astype(float)/corr.max())两个注意点disk(25)的半径要大于最大颗粒半径否则等于把颗粒本身也开掉adaptive histogram equalization 只是给阈值算法铺路不要拿增强后的图算灰度统计。2.2 阈值 分水岭处理粘连颗粒单阈值 (threshold_otsu) 对分散好的颗粒够用但电镜视野里颗粒经常粘连甚至重叠直接阈值会把两个颗粒连成一个。标准解法是距离变换 分水岭threshfilters.threshold_otsu(corr)binarycorrthresh# 距离变换每个前景像素到最近背景的距离distndi.distance_transform_edt(binary)coordsfeature.peak_local_max(dist,min_distance10,labelsbinary)markers,_ndi.label(ndi.maximum_filter(dist,size3)dist)# 简化标记markersnp.zeros(dist.shape,dtypeint)markers[tuple(coords.T)]np.arange(1,len(coords)1)labelssegmentation.watershed(-dist,markers,maskbinary)print(检出颗粒数:,labels.max())原理一句话距离变换在颗粒中心形成山峰两颗粒粘连处是山脊分水岭沿山脊切开。min_distance是最关键的参数——设小了过分割一个颗粒碎成两三个设大了粘连切不开。经验起点min_distance ≈ 预期粒径像素的一半然后对结果做 sanity check。2.3 过滤与测量分水岭输出的是带标签矩阵接下来剔除垃圾区域再测量propsmeasure.regionprops(labels)min_area,max_area50,5000# 像素²按标尺换算后设置areas_pxnp.array([p.areaforpinprops])keep(areas_pxmin_area)(areas_pxmax_area)# 边界颗粒剔除接触图像边缘的区域不完整必须排除on_edgeset(np.unique(np.concatenate([labels[0,:],labels[-1,:],labels[:,0],labels[:,-1]])))keepnp.array([p.labelnotinon_edgeforpinprops])三个必须过滤的对象太小噪声/碎屑、太大聚集体块或污物——除非你研究的就是聚集、触边不完整轮廓会低估粒径。2.4 尺度标定从像素到纳米# 方式A照片自带比例尺推荐# 手动量比例尺像素长度例如 100 nm 的标尺横跨 137 像素nm_per_px100/137# 方式B由放大倍数推# pixel_size detector_pixel_um / magnification需查相机手册diameters_nmnp.array([p.equivalent_diameterforpinnp.array(props,dtypeobject)[keep]])*nm_per_px标定是整个分析的头号误差源。同一台电镜不同放大倍数的照片绝不能混在一起统计除非各自标定后合并比例尺尽量在原始 TIFF 上量JPEG 压缩会挪动边缘。2.5 分布统计与拟合纳米颗粒粒径通常近似对数正态分布fromscipyimportstats ln_dnp.log(diameters_nm)mu,sigmaln_d.mean(),ln_d.std(ddof1)d_geonp.exp(mu)# 几何平均 中位数gsdnp.exp(sigma)# 几何标准差print(fN {len(diameters_nm)}, D50 {d_geo:.1f}nm, GSD {gsd:.2f})# 正态性检查对数空间print(log-normal 检验 p ,stats.shapiro(ln_d).pvalue)xsnp.linspace(diameters_nm.min(),diameters_nm.max(),200)plt.hist(diameters_nm,bins25,densityTrue,alpha0.6,label实测)plt.plot(xs,stats.lognorm.pdf(xs,sigma,scaled_geo),r-,labellog-normal 拟合)plt.xlabel(粒径 (nm));plt.ylabel(概率密度);plt.legend()plt.show()报告口径建议N颗粒总数、D50、D10/D90、GSD外加 KS 或 Shapiro 检验的 p 值。N 200 的分布别报百分位抽样误差比分辨率还大。三、三个高频翻车点翻车 1过分割分水岭对噪声极敏感——距离变换上的小毛刺就会被当成山峰一个大颗粒被切成三四块分布整体偏小。诊断方法把 labels 叠加回原图肉眼抽检 20 个颗粒修复方法先形态学开运算抹掉毛刺或调大min_distance或对 dist 先做一次高斯平滑再找峰。翻车 2把对比度当尺寸负染 TEM 里颗粒边缘有晕圈染色剂堆积阈值取得低则粒径系统性偏大。对同一批照片做过两种阈值otsu vs 手动 ±10%的敏感性分析D50 漂移超过 5% 说明分割对阈值敏感需要回头改预处理。翻车 3视野取样偏差自动数得快人就会偷懒只数最清楚的视野。正确做法是预先定取样规则每张碳膜网格随机取 N 个视野、焦距统一、不挑图——规则写进方法学比结果本身更重要。四、与其他表征交叉验证电镜的 number-weighted 分布和 DLS 的 intensity-weighted 分布可以直接换算对账Mie 理论假设球形换算后 DLS 预测峰应落在电镜分布乘 d⁶ 权重后的位置。两个常见对账结果DLS 峰明显偏大 → 样品里有少量大颗粒/聚集体电镜视野里容易漏因为大颗粒沉降或被稀释出去电镜分布偏小 → 负染干燥收缩或 Cryo-TEM 与 dry-TEM 的差异。NTA 给的是 number-weighted 但受检测下限影响50 nm 散射太弱。三种方法各报各的权重口径别混着比。五、小结电镜颗粒统计自动化的价值不在快在于取样规则显式化阈值、min_distance、过滤条件全部可审计可重复分水岭的 min_distance 从预期粒径一半起步结果必须叠图抽检尺度标定是最大误差源不同放大倍数照片不能混统分布报 N D50 GSD 检验 p 值N 200 不报百分位。参考scikit-image 官方文档watershed、regionprops、threshold 章节含可运行示例Meyer F. Topographic distance and watershed lines. Signal Processing, 1994分水岭算法原始文献负染/冷冻电镜样品制备对手动计数偏差的影响相关方法学讨论ISO 13322-1 粒度分析—图像分析法动态/静态图像粒度标准口径
RELATED

相关推荐

Redis与Memcached选型指南:从数据结构到缓存治理的全面对比

Redis与Memcached选型指南:从数据结构到缓存治理的全面对比

做后端开发这些年,Redis和Memcached几乎每次聊到缓存都绕不开,特别是涉及“Redis与Memcached的区别”这种经典问题。这俩名字经常同时出现,但真被问到“具体差在哪,业务上怎么选”,能说清楚的人其实不多。作为一个跟缓…

📅 2026/9/30 11:22:45
IEC 62439-3-2016实战解析:PRP与HSR如何实现工业网络零切换冗余

IEC 62439-3-2016实战解析:PRP与HSR如何实现工业网络零切换冗余

简介:此文档为IEC 62439-3:2016(Edition 3.0)国际标准原版PDF,面向工业自动化通信网络的设计、运维与测试工程师,聚焦高可用自动化场景下的两种无缝冗余协议:并行冗余协议(PRP)与高可…

📅 2026/9/30 11:22:45
第029篇 HashMap 底层原理——数组、链表与红黑树的演进

第029篇 HashMap 底层原理——数组、链表与红黑树的演进

摘要:本篇是《Android软件开发面试从入门到精通》第 29 篇,主题为「HashMap 底层原理——数组、链表与红黑树的演进」。在Java 核心基础的进度条上,「HashMap 底层原理——数组、链表与红黑树的演进」承上启下。本篇从零讲起,但按面试官追问的深度推进,读到最后一节就有答…

📅 2026/9/30 11:22:45
MORE NEWS

更多资讯

📰

主动源面波数据处理实战:频散曲线求解程序的原理、操作与避坑指南

做场地波速测试那阵子,我经常面对几十个CMP道集的数据发呆——野外一个上午采了15炮面波记录,全手工提取频散曲线的话,每炮至少折腾两小时,而且提取结果还得看操作者心情。换到频散曲线求解程序之后,整个流程从"两…

📰

迈普交换机常用命令实战指南:配置验证与安全回滚

简介:本资源是一份面向网络运维工程师、企业IT管理员及通信类专业学习者的迈普交换机实操配置指南,聚焦日常设备管理与故障排查核心需求。手册系统梳理了迈普交换机四大命令模式(普通用户、特权用户、全局、端口配置)的进入方式、…

📰

uniapp+Vue3自动导入配置实战:解决API手动import痛点

1. 为什么uniapp项目里手动import Vue API成了“体力活”? 在uniapp中用Vue3组合式API开发,最开始我也是老老实实写 import { ref, reactive, computed, onMounted } from vue ——直到某天一个页面里写了17次 import { ... } from vue ,…

📰

Maven实战:从依赖管理到构建部署的Web开发避坑指南

1. 为什么Web开发离不开Maven?——从手动搬jar包的噩梦说起如果你入行做Java Web开发超过几年,大概率经历过那个"手动管理依赖"的时代。我刚接触Web开发时,项目里要引入一个JSON库,流程是这样的:打开搜索引擎…

📰

SSH断开后程序退出?Linux进程会话与SIGHUP机制详解

1. 项目概述:为什么SSH断开后程序会“突然消失”?你有没有遇到过这样的情况:在Linux服务器上用SSH远程执行一个耗时较长的命令,比如python train.py训练模型、tar -czf backup.tar.gz /data打包大目录,或者npm run bui…

📰

Linux命令创意组合:从管道原理到实战,一行命令搞定运维

在运维这行摸爬滚打十来年,我慢慢发现一个规律:真正干活厉害的人,电脑里不一定存着几百页linux常用命令大全,但他们一定很会“拼”命令。单看ls、grep、awk、sed这些工具,谁都不陌生,可一旦把它们串进同一条…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬