
计算机视觉图像处理科学计算【免费下载链接】scikit-imageImage processing in Python项目地址https://gitcode.com/gh_mirrors/sc/scikit-image点击查看免费下载本文基于 scikit-image 官方 SKIPscikit-image Improvement Proposal文档《SKIP 4 — Transitioning to scikit-image 2.0》见 doc/source/skips/4-transition-to-v2.rst整理而成并结合当前仓库中已落地的skimage2/_skimage2实现与迁移工具源码进行印证。读完本文你将理解 scikit-image 为何选择以新命名空间 渐进式迁移的方式推进 2.0 API了解其两阶段实施路线、新旧 API 并存的导入层级约束、弃用警告机制以及从skimage迁移到skimage2时仓库中已有的工具与迁移指南。scikit-image 正朝着 2.0 版本演进。由于项目在过去 12 年以上的时间里由背景各异的社区贡献者有机增长API 中存在大量历史遗留的不一致其中不少变更只改返回值、不改函数签名无法通过常规弃用流程温和地完成。SKIP 4 提出了一条替代路径在现有skimage命名空间之外随包引入一个全新的实验性命名空间skimage2让用户显式选择opt-in使用新 API从而在不破坏既有用户代码的前提下完成 API 的清理与现代化。一、SKIP 4 提案概览SKIP 4 是一份状态为Draft草稿的标准类Standards Track提案由 Juan Nunez-Iglesias、Lars Grüter、Stéfan van der Walt、Matthew Brett、Marianne Corvellec 等人起草创建于 2025-08-16截至本文撰写时Resolution决议仍为 Pending待定。提案的核心主张可以概括为三步走引入新命名空间skimage2在过渡期内它与现有skimage命名空间一同包含在同一个发行包中新 API 先在skimage2中落地初期标记为不稳定、实验性experimental旧 API 继续正常工作待新 API 成熟后逐步弃用旧命名空间当skimage2中的 API 完备后skimage将被逐步弃用并最终移除。也就是说迁移不是一刀切而是让新旧两套 API 在同一环境中长时间共存用户可按自己的节奏逐步迁移代码。二、动机与范围为什么要做 2.0SKIP 4 的 Motivation 部分大量沿用了此前被否决的 SKIP 3见 doc/source/skips/3-transition-to-v1.rst。核心动机是scikit-image 的 API 在长期演进中积累了诸多不一致其中一些问题的修复在现有弃用框架下几乎不可行。2.1 典型问题一坐标轴顺序不一致skimage.transform.warp会反转坐标顺序。例如一个平移参数(45, 32)在 2D 场景下实际是把 NumPy 数组的值沿第 0 轴移动 32、沿第 1 轴移动 45——但仅限 2D。在 3D 场景下(45, 32, 77)又会按位置一一对应地移动各轴。这种维度相关的行为差异极易让用户写出隐蔽的 bug。2.2 典型问题二静默的数据类型转换与数值重缩放scikit-image 会自动把图像转换为各种数据类型并在转换过程中对数值进行重缩放。例如uint8图像取值范围 [0, 255]会被自动转换为取值 [0, 1] 的float64图像取值范围 [0, 65535] 的uint16图像会被缩放到 [0, 1]显微镜领域常见的 12 位uint16图像取值范围 [0, 4095]则会被缩放到 [0, 0.0625]。这些静默转换已经造成了大量用户困惑。而要改变这一约定几乎需要给所有scikit-image 函数增加一个preserve_range关键字参数其默认值需要历经约 4 个版本从 False 翻转为 True无论弃用曲线设计得多么温和最终仍然是一次向后不兼容的变更。2.3 典型问题三返回结构需要调整skimage.measure.regionprops等核心函数同样需要 API 微调——例如改为返回标签 → 属性的字典映射而不是当前的列表结构。2.4 为什么不能靠常规弃用周期解决虽然语义化版本Semantic Versioning在技术上允许主版本号升级时引入 API 变更但 SKIP 4 明确指出必须正视两个现实依赖方数量庞大数量巨大的项目依赖 scikit-image任何向后不兼容的变更都会波及它们科学 Python 社区尚无普遍的上限约束习惯绝大多数项目不会在依赖清单里写scikit-image1.*或scikit-image2.*因此直接发布带破坏性变更的 2.0 会冲击大量用户。此外大范围 API 变更还会使海量 StackOverflow 回答与既有用户指南失效更重要的是一次性发布大量变更意味着用户无法渐进式迁移——旧代码库只能整体搬迁因为无法同时依赖同一 API 的两个版本。这对许多用户来说是一个极高的迁移门槛。基于上述原因SKIP 4 提出发布一个可以应用十多年开发经验教训、而又不打扰现有用户群体的新命名空间。三、详细方案新 API 的具体变更方向SKIP 4 明确指出完整列出skimage2的所有 API 变更超出本文档范围许多变更尚未定案且一旦 SKIP 通过2.0 迁移的范围和野心还可能继续扩大。该 SKIP 的核心贡献是提供一套不破坏用户代码的迁移管理机制而非逐条罗列变更清单。不过文档仍给出了一些示例性方向停止在 dtype 必须强制转换为 float 时对输入数组进行重缩放对应上文 2.2 的问题停止在不同上下文如绘制、warp中互换坐标轴顺序对应上文 2.1 的问题允许函数返回非 NumPy 类型只要该返回值可通过numpy.asarray转换为 NumPy 数组即可统一不同函数中语义相同的参数名目前不同函数里random_seed、random_state、seed、sample_seed各自存在含义完全相同将measure.regionprops的返回值从列表改为字典合并功能相同的函数例如把watershed、slic、felzenschwalb归入公共命名空间方便新用户按任务寻找合适函数也有助于社区围绕统一 API 成长——目前 scikit-image 的 API 几乎每个函数一套。除此之外文档还提到更完整的变更清单维护在项目 Wiki 的 API changes for skimage2 页面中仓库内文档不包含该清单正文。四、相关项目经验命名空间迁移的先例SKIP 4 用专门一节回顾了业界已有的成功先例pandas于 2020 年 1 月发布 1.0.0包含大量向后不兼容的 API 变更SciPy于 2017 年发布 1.0但考虑到其成熟度与在科学 Python 生态中的基础地位选择不做大规模破坏性变更不过 SciPy 采纳了给依赖加上限的策略承认整个生态按2 个版本的弃用周期推进向后不兼容变更多个库已成功将社区迁移到带版本号的新命名空间OpenCV导入名为cv2、BeautifulSoupbs4、Jinjajinja2、psycopg当前导入名为psycopg2更远一些R 语言的 ggplot 以ggplot2之名使用。这些先例为在新命名空间中推进新 API、旧命名空间继续可用的做法提供了实践支撑。五、实施细节第一阶段——构建skimage25.1 仓库中已落地的命名空间结构SKIP 4 规划了两个新的 Python 命名空间/包与现有src/skimage并列位于src/_skimage2与src/skimage2_skimage2临时命名空间新 API 在此构建。当前仓库中 src/_skimage2/init.py 已包含color、data、draw、exposure、feature、filters、graph、io、measure、metrics、morphology、registration、restoration、segmentation、transform、util等完整子模块__version__为0.26.1rc0.dev0skimage2围绕_skimage2的轻量包装wrapper用于对外暴露新 API 供早期测试并在导入时警告用户该命名空间仍不稳定。当前仓库的 src/skimage2/init.py 完全吻合这一设计它通过lazy_loader将 16 个子模块转发到_skimage2对应模块并在模块顶层发出ExperimentalAPIWarning警告Importing from theskimage2namespace is experimental. Its API is under development and considered unstable!。以transform子模块为例src/skimage2/transform/init.py 的实现非常薄——只是把__getattr__、__dir__、__all__全部转发给_skimage2.transform印证了 SKIP 中一个 API 是另一个 API 的简单包装One implementation原则。5.2 构建新 API 的七条原则SKIP 4 明确提出构建新 API 的过程围绕以下原则展开One implementation单一实现只要可能只保留一份实现另一套 API 只是前者的简单包装Import hierarchy导入层级skimage与skimage2只能从_skimage2导入而_skimage2应当自包含self-contained。例外情况例如在_skimage2中导入skimage只是临时的且必须以内联导入inlined imports方式实现。第一阶段结束时_skimage2中的实现不应再依赖skimage中的代码Test coverage of both APIs两套 API 的测试覆盖skimage的测试套件应复制到_skimage2函数上测试需调整以验证新行为为抵消测试复制带来的变慢将借助依赖分析挑选测试仓库中对应的 PR #7749Minimize API difference最小化 API 差异尽量缩小新旧 API 的差异以降低用户迁移成本。新变更一般只引入_skimage2但若有充分理由也允许在skimage内走常规弃用周期Backwards compatible向后兼容旧skimageAPI 的行为应当可以通过某种skimage2API 调用组合复现。个别无法遵守该规则的情况必须给出论证并尽量提供辅助函数Migration guide迁移指南将详细记录从旧 API 迁移到新 API 的路径每条 API 差异都会被文档化。仓库中的对应物是 doc/source/user_guide/skimage2_migration.rst.tpl它是一份由 Jinja 模板驱动的迁移指南逐项列出已完成的迁移建议adviceLocal deprecation warnings局部弃用警告在旧 API 中加入特定弃用警告。这些警告是静默的——作为PendingDeprecationWarning的子类默认不向用户展示。第 7 条原则在仓库中有完整实现skimage命名空间中新增了PendingSkimage2Change警告类定义于 src/skimage/util/init.py它继承自PendingDeprecationWarning。SKIP 文档给出的示例是skimage.data.binary_blobs可能会发出PendingSkimage2Change警告建议用户改用skimage2.data.binary_blobs并说明如何适配新签名。仓库中的 src/skimage/_migration.py 实现了Skimage2Migration装饰器ski2_migration_decorator它会解析带条件标记cond-start: warning/cond-start: doc的 ReST 迁移文案一部分生成警告消息、一部分生成迁移文档片段并把skimage.xxx限定名自动替换为skimage2.xxx。目前该装饰器已应用于 src/skimage/data/_binary_blobs.py、src/skimage/morphology/gray.py、src/skimage/filters/_gaussian.py、src/skimage/feature/corner.py、src/skimage/feature/_canny.py、src/skimage/metrics/_contingency_table.py、src/skimage/future/trainable_segmentation.py 等一批文件说明局部弃用警告机制已经进入实质落地阶段。此外第一阶段期间新增量功能仍可继续引入旧的skimage命名空间并非只能进入新命名空间。5.3 用户如何提前启用迁移警告迁移指南模板doc/source/user_guide/skimage2_migration.rst.tpl给出了在skimage2正式发布前即可执行的警告启用方式——在代码使用 scikit-image 之前运行以下 warnings filterimport warnings import skimage as ski warnings.filterwarnings(actiondefault, categoryski.util.PendingSkimage2Change)这会让需要修改才能在 skimage2 下继续工作的代码提前暴露警告帮助用户在迁移窗口期早期就着手准备。警告类的对应源码可参见 src/skimage/util/init.py。5.4 实验性警告的实现细节ExperimentalAPIWarning定义于 src/_skimage2/_shared/_warnings.py继承自UserWarning供_skimage2与skimage2共用同一个警告类型便于统一过滤。skimage2在导入时立即触发该警告而不是等到某个属性被使用时才触发SKIP 4 在 Rationale 中明确解释了这一选择曾考虑用自定义__getattr__延迟警告但团队倾向于尽可能早地发出警告。六、实施细节第二阶段——过渡到skimage2当skimage2中的 API 被认为完备且稳定后进入第二阶段合并与转正src/_skimage2并入src/skimage2移除实验性警告旧 API 标记弃用改为在skimage命名空间导入时发出单一的顶层警告鼓励用户迁移到skimage2。该警告应链接到迁移指南并说明如何启用更具体的局部警告。文档特别注明在这一阶段skimage2不应再需要从skimage导入以免触发这条新警告正式发布该状态将以完整发行版scikit-image2.0.0发布。从此时起导入skimage2被鼓励新功能开发只应在skimage2中进行skimage中的 bug 仍可修复并随 2.0.0 的版本发布宽限期与常规弃用流程一致为从skimage移植到skimage2所需的每项变更提供可见警告的宽限期——至少 2 个发行版或 2 年取更长者之后用户代码才可能被破坏最终移除上述流程完成后skimage命名空间将被彻底移除。七、代码翻译辅助工具SKIP 4 还设想探索构建一个代码翻译工具帮助用户自动化迁移到skimage2以减轻切换成本——尤其是那些容易自动化的场景。文档同时承认该工具可能无法支持更模糊或更复杂的 API 更新场景也无法覆盖用户使用库的所有复杂方式支持这些场景可能不可能或需要高昂的开发成本。因此用户与下游库必须始终有其他手动完成迁移的手段例如借助常规弃用警告。若该工具成功实现它将在第二阶段开始时作为entry point与skimage2一同提供。仓库中的迁移文档模板正是手动迁移路径的载体。八、向后兼容性SKIP 4 承认本提案在库的众多位置打破了向后兼容性——但这一切发生在一个新命名空间内因此不会对现有用户构成向后兼容性顾虑。作者仍将尽量把不兼容变更限制在能显著改善整体用户体验的范围内并预期把skimage代码移植到skimage2是一个直接了当的过程。官方将在skimage2发布时同步发布迁移用户指南用户会通过例如scikit-image 1.1 中的警告获知这些资源。九、设计依据Rationale9.1 为什么需要这么多命名空间多命名空间显著简化了第一阶段渐进式移植的过程新 API v2 可以在独立命名空间里逐步充实并开放给社区测试。将_skimage2与skimage2分离则简化了必须警告用户 API v2 处于实验状态的要求——位于_skimage2的移植实现可以被skimage中的包装器复用而不会触发skimage2的导入警告。替代方案用自定义__getattr__延迟到属性被使用时才警告被否决理由是团队希望尽早触发警告。9.2 为什么限制命名空间之间的导入在从skimage向_skimage2渐进移植实现与 API 的过程中两个命名空间可能相互需要对方的功能极易引发混乱的循环导入错误。为将这种可能性降到最低SKIP 定义了明确的导入层级见上文 5.2 第 2 条。由于第一阶段结束时skimage2必须独立于skimage只允许临时的内联导入。十、备选方案Alternatives与取舍SKIP 4 系统性地评估了其他迁移路径并解释了为何被否决在同一个包内用语义化版本直接发布新 API即 SKIP 3见 doc/source/skips/3-transition-to-v1.rst在与社区讨论后被否决跨多个版本持续弃用例如为自动转换/重缩放的函数添加默认值为 False 的preserve_range参数先弃用默认值、再逐步翻转。这类操作必须对上述所有变更同步进行。核心团队最终认为这种做法给 scikit-image 开发者与下游库开发者都带来更多工作而收益存疑——最终版本仍然不兼容旧版本只是时间尺度更长更换包名新包名既然导入名要变也可顺势把包名从scikit-image改为skimage2。这与当前提案共享诸多优点核心是新skimage2命名空间且同样可对旧包导入发出警告并引导安装新包。但从同一仓库管理和发布两个包是有问题的引入新仓库又会遗留 issues 与 pull requests并使一套 API 作为另一套的包装几乎无法实现。因此 SKIP 4 建议保留scikit-image包名不做这些 API 变更即完全拒绝向后不兼容变更极端情况除外。核心团队认为这实质上等于把库钉死在 0.19 版本上。10.1 skimage2 作为唯一新名字的论证在命名讨论中文档建议skimage2同时作为导入名与PyPI / conda-forge 等处的包名理由包括只引入一个新名字使项目关联名称数量保持在最低导入名与包名一致用户可能会混淆该装scikit-image2还是scikit-image-2而skimage2可避免这种困惑熟悉skimage的用户看到skimage2时很可能推断出这是包的更新版本提议的 scikit-image 1.1 发布可在安装/升级流程中明确告知用户继任者名称。反对意见主要有两点其一按最小惊讶原则scikit-image2或许是包名最不令人意外的演进其二它打破了 scikit-image 等 scikit 系列遵循的命名惯例但文档指出该惯例实际上已有一段时间不再成立且在名字里引入版本号本身已有先例。十一、讨论背景与当前状态SKIP 4 是核心团队、兄弟项目与用户群体之间多轮持续讨论的产物SKIP 3doc/source/skips/3-transition-to-v1.rst是该 SKIP 的早期迭代其Resolution章节提供了本提案动机的进一步背景科学 Python 社区的公开讨论帖A pragmatic pathway towards skimage2直接催生了该方案大量讨论发生在标记为 Path to skimage2 的 issue 与 pull request 中2025-08 维也纳 Sprint 的会议记录记录了形成该 SKIP 的大量讨论。截至本文撰写时SKIP 4 的Resolution 状态为 Pending待定即提案尚未正式决议通过。但值得注意的是仓库中_skimage2、skimage2命名空间与PendingSkimage2Change迁移警告机制已经实际存在说明提案描述的第一阶段工作已在仓库中启动。十二、版权与许可按 SKIP 流程规定所有 SKIP 均以 CC0 1.0 公共领域贡献Public Domain Dedication声明并鼓励以 CC0BY 方式注明出处。小结SKIP 4 为 scikit-image 的 2.0 演进设计了一条双命名空间并行、用户显式选择、两阶段渐进过渡的路径。它既承认语义化版本大版本升级的破坏性风险也正视了常规弃用周期对改变函数输出这类变更的无力通过_skimage2实现层、skimage2实验性包装层与最终skimage的弃用移除用户与下游库可以在长达数年、至少 2 个发行版的宽限期内从容迁移。当前仓库中的 src/_skimage2、src/skimage2、src/skimage/_migration.py 与迁移指南模板 doc/source/user_guide/skimage2_migration.rst.tpl 已构成该方案的第一阶段落地雏形。赞分享计算机视觉图像处理科学计算【免费下载链接】scikit-imageImage processing in Python项目地址https://gitcode.com/gh_mirrors/sc/scikit-image点击查看免费下载相关推荐NumPy 2.0 主命名空间的 Array API 标准支持NEP 56 全面解读与迁移实践NumPy 2.0 主命名空间的 Array API 标准支持NEP 56 全面解读与迁移实践 导读 本文基于 NEP 56 — Array API stan科学计算数据分析Deeplearning4j 命名空间重构 ADR 解读基于 OpenRewrite 迁移至 org.eclipse.deeplearning4jDeeplearning4j 命名空间重构 ADR 解读基于 OpenRewrite 迁移至 org.eclipse.deeplearning4j 本文以仓库深度学习人工智能机器学习分布式训练scikit-image 治理与决策机制全解读SKIP 1 治理章程深度剖析scikit image 治理与决策机制全解读SKIP 1 治理章程深度剖析 本篇技术指南围绕 scikit image 项目官方治理文档 SKIP 1Go计算机视觉图像处理科学计算上一篇OptiScaler3 步替换游戏超采样器免费启用 FSR 与帧生成下一篇如何在openEuler系统中高效使用ft_surface窗口操作与缓冲区优化的实用技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考