文章目录
- pip install scikit-image 或使用 conda: conda install -c conda-forge scikit-image
- import numpy as np import matplotlib.pyplot as plt from skimage import io, color, filters, transform, feature, morphology, segmentation, exposure, measure, util
- image = io.imread(‘sample.jpg’) plt.imshow(image) plt.axis(‘off’) plt.show() 灰度化: gray = color.rgb2gray(image) plt.imshow(gray, cmap=’gray’)
- resized = transform.resize(image, (200, 200)) cropped = image[50:150, 80:180]
- rotated = transform.rotate(image, angle=45) warped = transform.warp(image, transform.AffineTransform(scale=(0.8, 0.8)))
- from skimage import exposure eq = exposure.equalize_hist(gray) plt.imshow(eq, cmap=’gray’) 自适应均衡化(CLAHE): clahe = exposure.equalize_adapthist(gray, clip_limit=0.03)
- gamma_corrected = exposure.adjust_gamma(gray, 0.5) brightened = exposure.adjust_log(gray)
- from skimage import img_as_ubyte, img_as_float img_uint8 = img_as_ubyte(gray) img_float = img_as_float(image)
- from skimage.filters import threshold_otsu thresh = threshold_otsu(gray) binary = gray > thresh
- from skimage.filters import threshold_local binary_local = gray > threshold_local(gray, block_size=35)
- from skimage.measure import label, regionprops labeled = label(binary) regions = regionprops(labeled)
- from skimage.segmentation import slic, mark_boundaries segments = slic(image, n_segments=200, compactness=10) plt.imshow(mark_boundaries(image, segments))
- from skimage.segmentation import watershed from scipy import ndimage as ndi distance = ndi.distance_transform_edt(binary) markers = ndi.label(binary)[0] labels = watershed(-distance, markers, mask=binary)
- from skimage.morphology import erosion, dilation, disk eroded = erosion(binary, disk(3)) dilated = dilation(binary, disk(3))
- opened = morphology.opening(binary, disk(3)) closed = morphology.closing(binary, disk(3))
- skeleton = morphology.skeletonize(binary)
- hull = morphology.convex_hull_image(binary)
- orb = feature.ORB(n_keypoints=200) orb.detect_and_extract(gray) plt.imshow(feature.plot_matches(image, image, orb.keypoints, orb.keypoints))
- from skimage.feature import hog hog_vec, hog_img = hog(gray, visualize=True) plt.imshow(hog_img, cmap=’gray’)
- from skimage.feature import match_template result = match_template(gray, template) ij = np.unravel_index(np.argmax(result), result.shape)
- coins = io.imread(‘https://scikit-image.org/docs/stable/_static/img/coins.png’) gray = color.rgb2gray(coins) edges = filters.sobel(gray) thresh = filters.threshold_otsu(edges) binary = edges > thresh labels = measure.label(binary) count = len(measure.regionprops(labels)) print(“硬币数量:”, count)
- cells = io.imread(‘cells.png’) gray = color.rgb2gray(cells) thresh = filters.threshold_otsu(gray) binary = morphology.closing(gray > thresh, morphology.disk(3)) distance = ndi.distance_transform_edt(binary) markers = ndi.label(binary)[0] labels = watershed(-distance, markers, mask=binary)
- dark = io.imread(‘dark_scene.jpg’) gray = color.rgb2gray(dark) enhanced = exposure.equalize_adapthist(gray, clip_limit=0.03) plt.imshow(enhanced, cmap=’gray’)
- from skimage.feature import ORB, match_descriptors from skimage.transform import ProjectiveTransform, warp orb = ORB(n_keypoints=200) orb.detect_and_extract(img1_gray) keypoints1, descriptors1 = orb.keypoints, orb.descriptors orb.detect_and_extract(img2_gray) keypoints2, descriptors2 = orb.keypoints, orb.descriptors matches = match_descriptors(descriptors1, descriptors2, cross_check=True)
目录
- 一、前言:为什么要学 scikit-image
- 二、安装与环境准备
- 1. 安装命令
- 2. 导入模块
- 3. 读取与显示图像
- 三、图像输入输出与数据模型
- 1. 支持的格式
- 2. 数据结构
- 四、图像预处理与增强
- 1. 调整大小与裁剪
- 2. 旋转与仿射变换
- 3. 直方图均衡化与对比度增强
- 4. 亮度与伽马校正
- 5. 图像归一化与类型转换
- 五、滤波与去噪
- 1. 平滑与模糊
- 均值滤波
- 高斯滤波
- 2. 边缘保留滤波:双边与非局部均值
- 3. 锐化处理
- 六、边缘检测与特征提取
- 1. Sobel 边缘检测
- 2. Canny 边缘检测
- 3. Laplacian 算子
- 4. Hough 变换:检测直线与圆
- 七、图像分割(Segmentation)
- 1. 阈值分割
- 2. 自适应阈值
- 3. 区域增长与连通组件
- 4. 超像素分割(SLIC)
- 5. 分水岭算法
- 八、形态学操作
- 1. 腐蚀与膨胀
- 2. 开运算与闭运算
- 3. 骨架提取
- 4. 凸包检测
- 九、对象测量与分析
- 1. 连通区域标记
- 2. 统计属性提取
- 3. 计算对象数量与面积
- 十、特征提取与图像匹配
- 1. ORB 特征点检测
- 2. HOG(方向梯度直方图)
- 3. 模板匹配
- 十一、颜色空间与通道操作
- 十二、三维图像与体数据处理
- 十三、实战案例
- 案例一:硬币识别与计数
- 案例二:细胞分割
- 案例三:低光图像增强
- 案例四:图像配准与特征匹配
- 十四、性能优化与 OpenCV 对比
- 十五、与深度学习结合
- 十六、常见错误与解决方法
- 十七、生态整合与未来方向
- 十八、总结
在计算机视觉与图像分析领域,Python 已成为事实上的标准语言。开发者在图像处理中通常会使用三个核心库:
- OpenCV:工业界最常用的视觉库,功能强大但偏底层;
- Pillow (PIL):操作简便,但主要面向基本的图像读写与简单处理;
- scikit-image:科研级图像处理库,强调算法的数学完整性、模块化和 NumPy 兼容性。
scikit-image 是 SciPy 生态的一部分,构建在 NumPy、SciPy、matplotlib 基础之上,旨在为科学计算和机器学习中的图像处理提供高质量、纯 Python 实现的算法。
它不仅适用于科研和教学,也在医学影像、遥感分析、工业检测、AI 数据增强等领域被广泛使用。
本文将从入门到实战,深入讲解 scikit-image 的方方面面,包括:
- 图像 I/O、显示与基本操作
- 滤波、去噪、增强与变换
- 边缘检测与分割算法
- 形态学与对象测量
- 特征提取与图像配准
- 实战案例:分割细胞、识别硬币、增强低光图像
- 性能优化与与 OpenCV 的对比
读完本文,你将具备独立使用 scikit-image 构建完整图像分析管线的能力。
pip install scikit-image
或使用 conda:
conda install -c conda-forge scikit-image
import numpy as np
import matplotlib.pyplot as plt
from skimage import io, color, filters, transform, feature, morphology, segmentation, exposure, measure, util
image = io.imread('sample.jpg')
plt.imshow(image)
plt.axis('off')
plt.show()
灰度化:
gray = color.rgb2gray(image) plt.imshow(gray, cmap='gray')
scikit-image 的 I/O 模块基于 imageio,支持:
- PNG, JPG, TIFF, BMP, GIF, DICOM 等。
img = io.imread('image.png')
io.imsave('output.jpg', img)
scikit-image 所有图像都表示为 NumPy 数组:
| 图像类型 | 维度 | dtype |
|---|---|---|
| 灰度图 | (H, W) | float64 |
| 彩色 图 | (H, W, 3) | float64 |
| 二值图 | (H, W) | bool |
像素值被归一化为 [0, 1] 的浮点数。
当与 OpenCV 结合使用时,需要乘以 255 并转换为 uint8。
resized = transform.resize(image, (200, 200))
cropped = image[50:150, 80:180]
rotated = transform.rotate(image, angle=45)
warped = transform.warp(image, transform.AffineTransform(scale=(0.8, 0.8)))
from skimage import exposure
eq = exposure.equalize_hist(gray)
plt.imshow(eq, cmap='gray')
自适应均衡化(CLAHE):
clahe = exposure.equalize_adapthist(gray, clip_limit=0.03)
gamma_corrected = exposure.adjust_gamma(gray, 0.5)
brightened = exposure.adjust_log(gray)
from skimage import img_as_ubyte, img_as_float
img_uint8 = img_as_ubyte(gray)
img_float = img_as_float(image)
from skimage.filters import rank
from skimage.morphology import disk
blurred = rank.mean(img_as_ubyte(gray), disk(5))
gaussian = filters.gaussian(gray, sigma=2)
from skimage.restoration import denoise_bilateral, denoise_nl_means
bilateral = denoise_bilateral(image, sigma_color=0.05, sigma_spatial=15)
nlmeans = denoise_nl_means(image, h=0.1)
from skimage.filters import unsharp_mask
sharpened = unsharp_mask(gray, radius=1, amount=1.5)
edges_sobel = filters.sobel(gray)
plt.imshow(edges_sobel, cmap='gray')
edges = feature.canny(gray, sigma=2)
lap = filters.laplace(gray)
from skimage.transform import hough_line, hough_circle, hough_circle_peaks
edges = feature.canny(gray)
h, theta, d = hough_line(edges)
from skimage.filters import threshold_otsu
thresh = threshold_otsu(gray)
binary = gray > thresh
from skimage.filters import threshold_local
binary_local = gray > threshold_local(gray, block_size=35)
from skimage.measure import label, regionprops
labeled = label(binary)
regions = regionprops(labeled)
from skimage.segmentation import slic, mark_boundaries
segments = slic(image, n_segments=200, compactness=10)
plt.imshow(mark_boundaries(image, segments))
from skimage.segmentation import watershed
from scipy import ndimage as ndi
distance = ndi.distance_transform_edt(binary)
markers = ndi.label(binary)[0]
labels = watershed(-distance, markers, mask=binary)
形态学用于二值或灰度图像的形状分析。
from skimage.morphology import erosion, dilation, disk
eroded = erosion(binary, disk(3))
dilated = dilation(binary, disk(3))
opened = morphology.opening(binary, disk(3))
closed = morphology.closing(binary, disk(3))
skeleton = morphology.skeletonize(binary)
hull = morphology.convex_hull_image(binary)
labels = measure.label(binary)
plt.imshow(labels)
props = measure.regionprops_table(labels, properties=('area', 'centroid', 'bbox'))
print(props)
count = len(np.unique(labels)) - 1
total_area = sum([r.area for r in measure.regionprops(labels)])
orb = feature.ORB(n_keypoints=200)
orb.detect_and_extract(gray)
plt.imshow(feature.plot_matches(image, image, orb.keypoints, orb.keypoints))
from skimage.feature import hog
hog_vec, hog_img = hog(gray, visualize=True)
plt.imshow(hog_img, cmap='gray')
from skimage.feature import match_template
result = match_template(gray, template)
ij = np.unravel_index(np.argmax(result), result.shape)
from skimage import color
hsv = color.rgb2hsv(image)
lab = color.rgb2lab(image)
ycbcr = color.rgb2ycbcr(image)
提取单通道:
r = image[:, :, 0] g = image[:, :, 1] b = image[:, :, 2]
scikit-image 同样支持 3D 图像(如 CT、MRI)。
volume = io.imread('ct_scan.tif')
from skimage.filters import sobel
edges = sobel(volume)
3D 分割与等值面重建:
from skimage import measure verts, faces, _, _ = measure.marching_cubes(volume, level=0.5)
coins = io.imread('https://scikit-image.org/docs/stable/_static/img/coins.png')
gray = color.rgb2gray(coins)
edges = filters.sobel(gray)
thresh = filters.threshold_otsu(edges)
binary = edges > thresh
labels = measure.label(binary)
count = len(measure.regionprops(labels))
print("硬币数量:", count)
cells = io.imread('cells.png')
gray = color.rgb2gray(cells)
thresh = filters.threshold_otsu(gray)
binary = morphology.closing(gray > thresh, morphology.disk(3))
distance = ndi.distance_transform_edt(binary)
markers = ndi.label(binary)[0]
labels = watershed(-distance, markers, mask=binary)
dark = io.imread('dark_scene.jpg')
gray = color.rgb2gray(dark)
enhanced = exposure.equalize_adapthist(gray, clip_limit=0.03)
plt.imshow(enhanced, cmap='gray')
from skimage.feature import ORB, match_descriptors
from skimage.transform import ProjectiveTransform, warp
orb = ORB(n_keypoints=200)
orb.detect_and_extract(img1_gray)
keypoints1, descriptors1 = orb.keypoints, orb.descriptors
orb.detect_and_extract(img2_gray)
keypoints2, descriptors2 = orb.keypoints, orb.descriptors
matches = match_descriptors(descriptors1, descriptors2, cross_check=True)
| 项目 | scikit-image | OpenCV |
|---|---|---|
| 语言实现 | 纯 Python + NumPy | C/C++ |
| 安装依赖 | 简单 | 较复杂 |
| 性能 | 较慢(可结合 NumExpr 加速) | 高性能 |
| 学术算法 | 丰富(适合科研) | 偏实用 |
| 可读性 | 高 | 中等 |
| 接口风格 | NumPy 风格 | 函数式 |
在科研和算法教学中推荐使用 scikit-image,而在实时工业部署中可用 OpenCV 替代。
在 PyTorch 或 TensorFlow 训练管线中,可用 scikit-image 进行数据预处理:
import torch
from skimage import transform, exposure
def preprocess(img):
img = transform.resize(img, (224, 224))
img = exposure.equalize_adapthist(img)
return torch.tensor(img.transpose(2,0,1)).float()
也可结合 scikit-learn:
from sklearn.cluster import KMeans features = gray.reshape(-1, 1) kmeans = KMeans(n_clusters=2).fit(features) segmented = kmeans.labels_.reshape(gray.shape)
| 错误 | 原因 | 解决方案 |
|---|---|---|
| ValueError: Input image must be 2D | 输入不是灰度图 | 使用 color.rgb2gray() |
| Plugin not found | 图像格式不支持 | 安装 imageio[ffmpeg] |
| TypeError: dtype mismatch | 没有使用 float 类型 | 使用 img_as_float() |
| 内存不足 | 图像太大 | 分块处理或降采样 |
scikit-image 与以下生态紧密结合:
scikit-learn:机器学习特征提取与分类;matplotlib:图像可视化;numpy/scipy:数学计算;napari:交互式科学图像查看;SimpleITK、pydicom:医学影像支持。
未来版本(0.25+)将增强:
- GPU 加速(CuPy 支持)
- 更高维度体数据处理
- AI 增强图像分割接口(深度学习集成)
scikit-image 是 Python 图像处理领域最具科学性与优雅性的库之一。它的设计哲学是:
“让图像处理像数学运算一样清晰。”
本文系统讲解了从图像读写、增强、分割、特征提取到实战案例的全过程。
在科研实验、算法教学、AI 数据预处理等场景中,它都是不可或缺的利器。
无论你是科研人员、AI 工程师,还是计算机视觉爱好者,掌握 scikit-image,意味着你真正理解了图像处理的底层逻辑与科学思维。
以上就是Python图像处理库scikit-image的使用方法详解的详细内容,更多关于Python图像处理库scikit-image的资料请关注风君子博客其它相关文章!
您可能感兴趣的文章:
- 详解python opencv、scikit-image和PIL图像处理库比较
- Python的scikit-image模块实例讲解
- Python 图像处理Pillow安装、使用实战应用小结
- Python图像处理必备技巧分享
- Python图像处理篇之opencv实现坐姿检测