mcpField
N
napari-image-viewer

napari-image-viewer

github.com/jaechang-hits数据与数据库38476 次安装6 天前更新
代码仓库

关于 napari-image-viewer

napari-image-viewer 是一项介绍 napari 的技能,帮助生物图像研究者和 Python 用户查看、标注及可视化多维科学图像。其内容涵盖分层数据视图和无显示环境下的截图导出。

主要功能

  1. 01图像、标签、点和形状分层显示
  2. 02浏览 3D 堆栈与时间序列
  3. 03带对比度控制的多通道叠加
  4. 04离屏渲染与截图导出
  5. 05基于插件的分析工作流

适用场景

  1. 01检查显微图像和分割掩码
  2. 02为分割模型标注训练数据
  3. 03比较多个图像通道
  4. 04在无显示环境中导出图像

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jaechang-hits/sciagent-skills --skill napari-image-viewer

安装后在 Claude Code 中输入/napari-image-viewer确认已加载。

详细介绍

napari — 多维图像查看器

概述

napari 是一款快速、交互式的多维科学数据查看器,基于 PyQt5 和 VisPy 构建。它将 NumPy 数组和 zarr 数组显示为分层可视化内容:用于原始数据的 Image 图层、用于分割掩膜的 Labels 图层、用于细胞质心的 Points 图层,以及用于 ROI 注释的 Shapes 图层。napari 通过插件与 scikit-image、Cellpose 和 StarDist 集成,是 Python 生物图像分析工作流中的标准可视化和注释工具。在无头环境(HPC、CI)中,napari 支持离屏渲染和 viewer.screenshot(),可自动生成图像。

适用场景

  • 在定量分析前,直观检查并进行质量控制,查看显微图像和分割掩膜
  • 为深度学习分割模型(Cellpose、StarDist)标注训练数据
  • 叠加多个图像通道(DAPI、GFP、mCherry),并独立控制对比度和颜色映射
  • 使用基于滑块的导航查看 3D z-stack 和 4D 延时实验
  • 从 GUI 导出已注释的屏幕截图或标签掩膜,用于发表论文的图表
  • 交互式运行基于插件的分析(Cellpose napari 插件、StarDist 插件、n2v 去噪)
  • 使用 ImageJ/FIJI 进行宏/批处理脚本编写,尽量减少对 Python 的依赖
  • 使用 ITK-SNAP 作为医学影像(DICOM、NIfTI)分割的替代方案

前置条件

  • Python 包:napari、numpy、scikit-image
  • Qt 后端:需要显示服务器;无头使用时设置 QT_QPA_PLATFORM=offscreen
  • 可选插件:napari-cellpose、napari-stardist、napari-animation
# Install with all backends
pip install "napari[all]"

# Or minimal install
pip install napari pyqt5

# Verify
python -c "import napari; print(napari.__version__)"
# 0.5.5

# Install useful plugins
pip install napari-cellpose napari-animation

快速入门

import napari
import numpy as np
from skimage import data

# Open viewer with a sample image
viewer = napari.Viewer()
viewer.add_image(data.cells3d()[:, 1, :, :], name="DAPI", colormap="blue")
napari.run()   # blocks until viewer closed (use in scripts)

核心 API

模块 1:Image 图层 — 显示原始图像

添加和配置多通道图像图层。

import napari
import numpy as np
from skimage import io

viewer = napari.Viewer()

# Add single grayscale image
img = io.imread("cells.tif")  # shape: (H, W)
viewer.add_image(img, name="phase contrast", colormap="gray",
                 contrast_limits=[0, img.max()])

# Add multichannel image (3 channels)
img_mc = io.imread("multichannel.tif")  # shape: (H, W, 3)
viewer.add_image(img_mc[..., 0], name="DAPI", colormap="blue", blending="additive")
viewer.add_image(img_mc[..., 1], name="GFP", colormap="green", blending="additive")
viewer.add_image(img_mc[..., 2], name="mCherry", colormap="red", blending="additive")

print(f"Layers: {[l.name for l in viewer.layers]}")
模块 2:Labels 图层 — 可视化分割掩膜

显示并编辑来自 Cellpose、StarDist 或 scikit-image 的整数标签掩膜。

import napari
import numpy as np
from skimage import io

viewer = napari.Viewer()

img = io.imread("cells.tif")
masks = np.load("masks.npy")  # integer label array: 0=background, 1..N=cells

# Add raw image
viewer.add_image(img, name="raw", colormap="gray")

# Add label mask (each cell gets a unique random color)
label_layer = viewer.add_labels(masks, name="cell_masks", opacity=0.5)

# Access labels for editing
print(f"Unique cells: {len(np.unique(masks)) - 1}")
print(f"Label layer data shape: {label_layer.data.shape}")
模块 3:Points 图层 — 标记细胞质心

添加并设置点标记的样式,用于表示质心、基准点或检测到的特征。

import napari
import numpy as np
import pandas as pd
from skimage.measure import regionprops_table

viewer = napari.Viewer()

# Compute centroids from label mask
masks = np.load("masks.npy")
props = regionprops_table(masks, properties=["centroid", "label"])
centroids = np.column_stack([props["centroid-0"], props["centroid-1"]])

# Add centroids as Points layer
viewer.add_points(
    centroids,
    name=f"centroids ({len(centroids)} cells)",
    size=8,
    face_color="yellow",
    edge_color="black",
    edge_width=0.5,
)
print(f"Cells marked: {len(centroids)}")
模块 4:Shapes 图层 — 绘制 ROI 和注释

添加边界框、多边形和线条注释。

import napari
import numpy as np

viewer = napari.Viewer()

# Add rectangles as ROIs (format: [[y1, x1], [y2, x2]])
rois = [
    np.array([[50, 100], [200, 300]]),   # ROI 1
    np.array([[300, 150], [450, 350]]),  # ROI 2
]

shapes_layer = viewer.add_shapes(
    rois,
    shape_type="rectangle",
    name="ROIs",
    edge_color="cyan",
    face_color="transparent",
    edge_width=2,
)

# Retrieve shapes data for analysis
for i, shape in enumerate(shapes_layer.data):
    y_min, x_min = shape.min(axis=0)
    y_max, x_max = shape.max(axis=0)
    print(f"ROI {i+1}: y={y_min:.0f}-{y_max:.0f}, x={x_min:.0f}-{x_max:.0f}")
模块 5:3D 和延时可视化

使用滑块显示 z-stack 和时间序列。

import napari
import numpy as np
from skimage import data

viewer = napari.Viewer()

# 3D z-stack: shape (Z, H, W)
zstack = data.cells3d()[:, 1, :, :]   # nuclei channel
viewer.add_image(zstack, name="z-stack nuclei",
                 colormap="cyan", blending="additive")

# 4D time-lapse: shape (T, H, W) or (T, Z, H, W)
timelapse = np.random.randint(0, 65535, (10, 256, 256), dtype=np.uint16)
viewer.add_image(timelapse, name="timelapse", colormap="gray")

# napari shows axis sliders automatically for ndim > 2
print(f"z-stack shape: {zstack.shape} → slider for Z axis")
print(f"timelapse shape: {timelapse.shape} → sliders for T axis")
模块 6:无头屏幕截图导出

无需显示器即可导出屏幕截图(适用于 HPC 和 CI 环境)。

import os
os.environ["QT_QPA_PLATFORM"] = "offscreen"  # must be set BEFORE importing napari

import napari
import numpy as np
from skimage import io, data
import matplotlib
matplotlib.use("Agg")  # also set matplotlib backend

viewer = napari.Viewer(show=False)

img = data.cells3d()[30, 1, :, :]  # single z-slice
masks = (img > img.mean()).astype(int)  # simple threshold mask

viewer.add_image(img, name="DAPI", colormap="blue", blending="additive")
viewer.add_labels(masks.astype(np.int32), name="masks", opacity=0.5)

# Export screenshot
screenshot = viewer.screenshot(path="napari_export.png", canvas_only=True)
print(f"Screenshot saved: napari_export.png ({screenshot.shape})")
viewer.close()

关键参数

参数模块默认值效果
colormapadd_image"gray"颜色映射名称(matplotlib cmaps + napari 内置选项:"green"、"blue"、"cyan")
contrast_limitsadd_imageauto用于显示的强度截断范围 [min, max]
blendingadd_image"translucent"多通道叠加使用 "additive";实色显示使用 "opaque"
opacityadd_labels0.7标签图层在图像上的透明度,范围为 0–1
face_coloradd_points"white"点的填充颜色(名称、十六进制值或 RGBA)
sizeadd_points10点在数据坐标中的半径(像素)
edge_widthadd_shapes1形状轮廓宽度(像素)
showViewer()True无头/离屏模式使用 False
ndisplayViewer()2使用 3 启用 3D OpenGL 渲染模式
canvas_onlyscreenshot()False使用 True 可在导出时排除 napari 工具栏

常见工作流

工作流 1:检查 Cellpose 分割质量
import os
os.environ["QT_QPA_PLATFORM"] = "offscreen"

import napari
import numpy as np
from cellpose import models
from skimage import io
from skimage.measure import regionprops_table

# Segment with Cellpose
img = io.imread("cells.tif")
model = models.Cellpose(model_type="cyto3", gpu=False)
masks, _, _, diams = model.eval(img, diameter=0, channels=[0, 0])

# Visualize in napari (headless for export)
viewer = napari.Viewer(show=False)
viewer.add_image(img, name="raw", colormap="gray")
viewer.add_labels(masks, name=f"masks ({masks.max()} cells)", opacity=0.6)

# Add centroids
props = regionprops_table(masks, properties=["centroid"])
centroids = np.column_stack([props["centroid-0"], props["centroid-1"]])
viewer.add_points(centroids, name="centroids", size=6, face_color="yellow")

viewer.screenshot(path="segmentation_review.png", canvas_only=True)
viewer.close()
print(f"QC export: segmentation_review.png — {masks.max()} cells detected")
工作流 2:多通道 FISH 图像分析
import napari
import numpy as np
from skimage import io

# Load 4-channel FISH image: DAPI + 3 RNA probes
img = io.imread("fish_4channel.tif")  # shape: (H, W, 4)

viewer = napari.Viewer()
channels = [
    ("DAPI", "blue", img[..., 0]),
    ("probe_A_cy3", "yellow", img[..., 1]),
    ("probe_B_cy5", "red", img[..., 2]),
    ("probe_C_gfp", "green", img[..., 3]),
]

for name, colormap, channel in channels:
    viewer.add_image(channel, name=name, colormap=colormap,
                     blending="additive",
                     contrast_limits=[channel.min(), np.percentile(channel, 99.5)])

napari.run()

常用配方

配方 1:将所有图层导出为已注释图像
import os
os.environ["QT_QPA_PLATFORM"] = "offscreen"

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

viewer = napari.Viewer(show=False)

img = io.imread("cells.tif")
masks = np.load("masks.npy")

viewer.add_image(img, name="raw", colormap="gray")
viewer.add_labels(masks, name="segmentation", opacity=0.5)

# Set camera zoom and position
viewer.camera.zoom = 1.5
viewer.camera.center = (img.shape[0] // 2, img.shape[1] // 2)

screenshot = viewer.screenshot(path="figure_panel.png", canvas_only=True)
viewer.close()

# Add scalebar with matplotlib
fig, ax = plt.subplots(figsize=(6, 6))
ax.imshow(screenshot)
ax.axis("off")
plt.tight_layout()
plt.savefig("figure_final.pdf", dpi=300, bbox_inches="tight")
print("Exported: figure_final.pdf")
配方 2:批量导出 z-stack 投影
import os
os.environ["QT_QPA_PLATFORM"] = "offscreen"

import napari
import numpy as np
from skimage import io
from pathlib import Path

output_dir = Path("projections")
output_dir.mkdir(exist_ok=True)

for img_path in sorted(Path("zstacks").glob("*.tif")):
    zstack = io.imread(img_path)  # shape: (Z, H, W)
    max_proj = zstack.max(axis=0)
    
    viewer = napari.Viewer(show=False)
    viewer.add_image(max_proj, name="max_projection", colormap="gray")
    viewer.screenshot(path=str(output_dir / f"{img_path.stem}_maxproj.png"), canvas_only=True)
    viewer.close()
    print(f"Exported: {img_path.stem}_maxproj.png")

print("All z-stack projections exported.")

故障排查

问题原因解决方案
qt.qpa.plugin: Could not load the Qt platform plugin "xcb"缺少显示设备或 Qt 平台插件在导入 napari 前设置 QT_QPA_PLATFORM=offscreen;安装 libxcb-util-dev
napari 窗口未打开在 SSH 中运行,且未启用 X 转发使用 viewer = napari.Viewer(show=False),并通过 screenshot() 导出
大型图像渲染缓慢图像对于 GPU 显存来说过大使用 viewer.add_image(img, multiscale=True) 进行金字塔渲染
Labels 图层显示的颜色不正确掩码数据类型溢出确保掩码为 int32 而非 uint8(超过 255 个单元格时会溢出)
napari.run() 阻塞 Jupyter 笔记本Qt 事件循环冲突在 Jupyter 中使用 %gui qt 魔法命令;或使用 viewer.show(),而不调用 napari.run()
截图为黑屏或空白截图前查看器尚未完全渲染在调用 screenshot() 前添加 viewer.update() 或稍作延迟
菜单中未显示插件插件未安装或 napari 版本不兼容执行 pip install napari-<plugin>;在 napari-hub 上检查 napari 版本兼容性
3D 渲染缓慢几何结构复杂或体积数据过大将 viewer.dims.ndisplay = 2;减少 z 轴堆栈深度

参考资料

评论

支持 Markdown