scikit-image 图像处理

scikit-image 图像处理

一、实验说明

scikit-image 是用于图像处理的 Python 包,使用原生的 NumPy 数组作为图像对象。

本实验译自官方文档 与 这篇笔记

1. 环境登录

无需密码自动登录,系统用户名shiyanlou

2. 环境介绍

本课程实验环境使用Spyder。首先打开terminal,然后输入以下命令:

spyder -w scientific-python-lectures   (-w 参数指定工作目录)

关于Spyder的使用可参考文档:https://pythonhosted.org/spyder/

本实验基本在控制台下进行,可关闭 spyder 中的其余窗口,只保留控制台。如需要调出窗口,可以通过 view->windows and toolbar 调出。比如希望在py文件中编写代码,可以 view->windows and toolbar->Editor 调出编辑器窗口。

二、实验内容

文件输入输出

模块:skimage.io

from skimage import io

读取图像文件(注:读取与保存都是使用外部图形插件,比如 PIL)

filename = os.path.join(skimage.data_dir, 'camera.png')
camera = io.imread(filename)

还可以从 URL 路径读取图片

logo = io.imread('http://labfile.oss.aliyuncs.com/courses/370/ascii_dora.png')

保存文件

io.imsave('local_logo.png', logo)

数据类型

图像数组的数据类型可以是整型或者浮点型的。

要小心处理整型数据溢出的情况

camera = data.camera()
camera.dtype

输出:

dtype('uint8')

输入:

camera_multiply = 3 * camera # 溢出

整型8,16,32位,signed,unsigned都有可能,图片处理前建议先检查数据类型。

浮点型的范围是 [-1, 1],scikit-image 的一些图像处理的例程处理的是浮点化的图像,所以可能导致输入是整型数组,输出是浮点数组。

from skimage import filter
camera_sobel = filter.sobel(camera)
camera_sobel.max()

输出:

0.8365106670670005

skimage.util 模组帮助进行数据类型的转换,转换函数有 util.img_as_floatutil.img_as_ubyte 等。

颜色空间

彩色图形的形状可能是(N,M,3)或者(N,M,4)(4是因为可能多了一个 alpha 透明值)

lena = data.lena()
lena.shape

输出:

(512, 512, 3)

skimage.color模块中 color.rgb2hsvcolor.lab2rgb 可以完成颜色空间的转换。

图像坐标

因为我们是用 numpy 数组来表现图片,不同于一般笛卡尔坐标的(x,y),我们使用(row,col)进行定位。彩色图片或者其它多通道图片还会多一个坐标维度 ch。如果是 3d 图片的情况,会多一个平面坐标维度,记作 pln 或者 p

具体见下表

图像类型 坐标
2D 灰度图 (row, col)
2D 多通道图 (比如RGB) (row, col, ch)
3D 灰度图 (pln, row, col)
3D 多通道图 (pln, row, col, ch)

几何变换

scikit-image 支持几种基础的几何变换:相似,仿射,投射 与 多项式变换

这里举一个相似变换的例子:

import math
import skimage.transform as tf

text = data.text()

tform = tf.SimilarityTransform(scale=1, rotation=math.pi / 4,
                               translation=(text.shape[0] / 2, -100))

rotated = tf.warp(text, tform)
back_rotated = tf.warp(rotated, tform.inverse)

fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(8, 3))
plt.gray()
ax1.imshow(text)
ax1.axis('off')
ax2.imshow(rotated)
ax2.axis('off')
ax3.imshow(back_rotated)
ax3.axis('off')

图像处理

局部过滤

局部过滤对像素操作依据其相邻像素。

提取轮廓的例子:

from skimage import data, filter
import matplotlib.pyplot as plt

text = data.text()
hsobel_text = filter.hsobel(text)

plt.figure(figsize=(12, 3))

plt.subplot(121)
plt.imshow(text, cmap='gray', interpolation='nearest')
plt.axis('off')
plt.subplot(122)
plt.imshow(hsobel_text, cmap='jet', interpolation='nearest')
plt.axis('off')
plt.tight_layout()
plt.show()

非局部过滤

非局部过滤对像素操作依据图像上的大块像素(或是所有像素)

增强对比度的例子:

from skimage import data, exposure
import matplotlib.pyplot as plt

camera = data.camera()
camera_equalized = exposure.equalize(camera) 



plt.figure(figsize=(7, 3))

plt.subplot(121)
plt.imshow(camera, cmap='gray', interpolation='nearest')
plt.axis('off')
plt.subplot(122)
plt.imshow(camera_equalized, cmap='gray', interpolation='nearest')
plt.axis('off')
plt.tight_layout()
plt.show()

图像分割

图像分割(Segmentation)指的是将数字图像细分为多个图像子区域(像素的集合)(也被称作超像素)的过程。图像分割的目的是简化或改变图像的表示形式,使得图像更容易理解和分析。图像分割通常用于定位图像中的物体和边界(线,曲线等)。更精确的,图像分割是对图像中的每个像素加标签的一个过程,这一过程使得具有相同标签的像素具有某种共同视觉特性。

otsu 阀值法是一个简单的启发式方法可以区分出图像的前景和背景

from skimage import data
from skimage import filter

camera = data.camera()
val = filter.threshold_otsu(camera)
mask = camera < val
io.imshow(mask)

对图像连通的部分加标签

n = 20
l = 256
im = np.zeros((l, l))
points = l*np.random.random((2, n**2))
im[(points[0]).astype(np.int), (points[1]).astype(np.int)] = 1
im = ndimage.gaussian_filter(im, sigma=l/(4.*n))
blobs = im > im.mean()

#对连通的部分加标签
all_labels = morphology.label(blobs)
#去掉背景的部分,不为背景加标签
blobs_labels = morphology.label(blobs, background=0)

特征提取

特征提取有以下作用:

  • 对图像的部分进行归类(比如归类天空与建筑物)
  • 匹配图像中的物品
  • 计算机视觉方面的林林总总

使用 Harris 角点检测检测角点的例子。

from skimage import data
from skimage.feature import corner_harris, corner_subpix, corner_peaks
from skimage.transform import warp, AffineTransform


tform = AffineTransform(scale=(1.3, 1.1), rotation=1, shear=0.7,
                        translation=(210, 50))
image = warp(data.checkerboard(), tform.inverse, output_shape=(350, 350))

coords = corner_peaks(corner_harris(image), min_distance=5)
coords_subpix = corner_subpix(image, coords, window_size=13)

plt.gray()
plt.imshow(image, interpolation='nearest')
plt.plot(coords_subpix[:, 1], coords_subpix[:, 0], '+r', markersize=15, mew=5)
plt.plot(coords[:, 1], coords[:, 0], '.b', markersize=7)
plt.axis('off')
plt.show()

延伸阅读

  • scikit-image 示例库

License

本作品在 知识共享协议 3.0 下授权发布

你可能感兴趣的:(Python科学计算)