Python中可以处理图像的module有很多个,比如Opencv,Matplotlib, Numpy, PIL以及今天要分享的SciPy。其他几个后续都会总结一下,今天主要是SciPy。SciPy是Python 中一个科学计算(线性代数,统计,优化等)的module,但它的功能不限于计算,还包括信号和图像处理。Python中科学计算比较有名还有Pandas,堪称数据处理中的“瑞士军刀”。其中Numpy和SciPy底层是用c语言实现的,所以速度很快,所以使用它们的频率非常高,经常会把数据处理成numpy数组的形式。由于我现在主要做的图像这块,所以对每个module中图像处理的都比较感兴趣,会对比它们之间处理图像的区别。今天先把SciPy中图像处理的方法做个总结。
先把要使用的module导入进来
# coding:utf-8 - * -
import scipy
from scipy import ndimage
from scipy import misc
import numpy as np
SciPy中图像处理的方法主要在misc和ndimage这两个子模块下面
先来看一张德普的帅照("depu.jpg"),然后接下来我们对他做各种处理, 看看会是什么样子。
## misc ##
# 图像的读取和保存
首先是读取原始图片,imread是读图的函数。第一个参数是文件名,第二个参数表示是不是要把图片压平。第三个表示图像的模式。我们的原始图为RGB图,所以这里就是RGB,类型为str。也可以不写,默认会根据你图片的文件格式,自动识别。
保存图片的函数是misc.imsave, 第一个参数是保存的文件名或者文件路径加文件名,第二个数要保存的n维数组,我们把压平之后的图片保存一下,就是图2.
img = misc.imread("depu.jpg", flatten=False,
mode='RGB')
print img.shape
# (768L, 1000L, 3L)
img = misc.imread("depu.jpg", flatten=True,
mode='RGB')
print img.shape
# (768L, 1000L)
misc.imsave("depu_1.jpg", img)
然后就是介个样子的。
图2: “depu_1.jpg”
print type(img)
<type 'numpy.ndarray'>
img的类型为numpy的n维数组,所以我们平时看到的图片,其实 在我心里就是一堆阿拉伯数字!囧!
# 改变图像的大小
imresize(arr, size, interp='bilinear', mode=None):
misc.imresize方法可以改变图像的大小,第一个参数是原始图像的数组,第二个参数是改变后图像的大小,第三个是插值的方法,第四个和read的mode是一样的。
默认的插值方法是线性插值,另外还有紧邻插值,样条插值等,下面我们对比一下,每种插值得到图像的区别。
method_list = list(('nearest', 'lanczos', 'bilinear',
'bicubic' , 'cubic'))
for method in method_list:
new_height = 64 # 这里可以自己设置大小
new_width = 100
img_resize = misc.imresize(img,
size=(new_height, new_width),
interp="{}".format(method))
misc.imsave("depu_resize_{}_{}_{}.jpg".
format(method, new_height, new_width),
img_resize)
然后大家自己去对比一下结果,图片传上来,也看出来效果了。貌似近邻插值的效果比较差。
# 图片显示
imshow方法主要用在交互式环境下,比如IPython,一般不用。
misc.imshow(img)
# 图片旋转
图片旋转的就是把图片旋转。!!旋转之后的区别在于旋转角度的不同而不同。misc.imrotate方法,其中第二个参数代表旋转角度, 第三个是插值方法。
imrotate(arr, angle, interp='bilinear')
img = misc.imread("depu.jpg", flatten=False,
mode='RGB')
angle_list = [30, 45, 60, 90, 270, 360]
for angle in angle_list:
img_rotate = misc.imrotate(img, angle,
interp="bilinear")
misc.imsave("imrotate_{}.jpg".format(angle),
img_rotate)
然后来一波连连看。。!
# # 270
## 90
## 60
## 45
## 30
## ndimage ##
# 滤波, Filters
ndimage是一个多维图像处理的库,包括滤波,插值,傅里叶滤波,图像形态学,以及对图片的特征统计方法。这个我用的不多,简单举几个栗子,抛砖引玉。
接下来我们换个更帅的照片(depu_1.jpg),就是这个
先来看第一个方法,高斯滤波。图像滤波我们在前面曾经说过一次,不了解的童鞋可以看一下前面的文章。
gaussian_filter(input,
sigma,
order=0,
output=None,
mode="reflect",
cval=0.0,
truncate=4.0)
ndimage.gaussian_filter是做高斯滤波的函数,input,输入,sigma是高斯滤波核的标准差,看一下文档中的一个栗子,输入一个5x5的矩阵a,经过标准差为1的高斯滤波器,输出的5x5矩阵。
>>> a = np.arange(50, step=2).reshape((5,5))
>>> a
array([[ 0, 2, 4, 6, 8],
[10, 12, 14, 16, 18],
[20, 22, 24, 26, 28],
[30, 32, 34, 36, 38],
[40, 42, 44, 46, 48]])
>>> gaussian_filter(a, sigma=1)
array([[ 4, 6, 8, 9, 11],
[10, 12, 14, 15, 17],
[20, 22, 24, 25, 27],
[29, 31, 33, 34, 36],
[35, 37, 39, 40, 42]])
然后我们实验一下不同标准差的滤波器,得到的图像会有什么差别。
depu = ndimage.imread("depu_1.jpg")
print depu.shape
# (1024L, 1280L, 3L)
sigma_list = [5, 10, 20]
for sigma in sigma_list:
depu_gaussian_filter = ndimage.gaussian_filter(depu,
sigma=sigma)
misc.imsave("blurred_face_{}.jpg".format(sigma),
depu_gaussian_filter)
## 5
## 10
## 20
通过实验我们发现,标准差越大,图像越模糊,这个可以这样来理解一下。标准差大,说明滤波器的方差就大,方差大,就是滤波器的值要更加分散,那么他的粒度就要粗一下,也就是计算得到的相邻像素的差距比较大,所以会更加模糊!
# 傅里叶滤波, Fourier filters
fourier_gaussian(input, sigma, n=-1, axis=-1, output=None)
from scipy.ndimage import fourier_gaussian
depu_1 = misc.imread("depu_1.jpg")
depu_1_fg = fourier_gaussian(depu_1, sigma=0.36)
这里你也可以去试试不同的标准差,看看是什么效果
# 其他滤波方法。。。
此处省略1w字
# 最后我们看一个多维图像的栗子
最近在做天池的比赛,遇到的数据就是多维数据,刚把数据下载下来之后,我是懵逼的,.zraw, .mhd格式的数据,这是什么啊,从来没见过!然后我就开始各种百度,Google,最终知道的。哎,都怪自己头发短,见识少啊。以前一直接触的是RGB,话说还三个通道呢啊,其实这仅仅是二维图像。这里的二维可以理解为平面。而三维图像,就是一个立体的感觉,看起来有立体感。继续还有四维,五维图像,,,等等。别去想他们什么样,超过3维的东西,大脑是很难想象的,把它想成一个n维数组就好了,就和之前接触的ndarray一样。
zoom(input, zoom, output=None, order=3, mode='constant',
cval=0.0, prefilter=True)
zoom 方法是一个做插值的方法,可以针对n维图像。其中zoom参数是一个浮点数或者序列类型。
数据是这个样子的,全部数据是这样的600个。
.zraw格式是raw格式的压缩版,而.raw格式是一种常用的图像存储方法。有很多方法可以把图像变化为.raw格式,比如:
img = misc.imread("depu.jpg")
img.tofile('depu.raw')
我们需要另外一个库,叫SimpleITK,就是ITK库的简化版,ITK安装比较麻烦,尤其是Windows,所以我就安装了SimpleITk。
import SimpleITK as sitk
from scipy.ndimage import zoom
test_file = "LKDS-00001.mhd"
scan_data = sitk.ReadImage(test_file)
data = sitk.GetArrayFromImage(scan_data)
print data.shape
# (281L, 512L, 512L)
spacing = np.array(list(
reversed(scan_data.GetSpacing())))
print spacing
# [ 1.25 0.80664098 0.80664098]
slices = zoom(data, spacing, mode='nearest')
print slices.shape
# (351L, 413L, 413L)
好了, SciPy的图像处理就介绍到这里了,大家玩的开心!另外祝大家粽子节快乐!吃好玩好!!!反正我就在朋友圈看世界!(./ 摊手)
附录:ndimage方法列表
"""
=========================================================
Multi-dimensional image processing
=========================================================
Filters
=======
convolve - Multi-dimensional convolution
convolve1d - 1-D convolution along the given axis
correlate - Multi-dimensional correlation
correlate1d - 1-D correlation along the given axis
gaussian_filter
gaussian_filter1d
gaussian_gradient_magnitude
gaussian_laplace
generic_filter - Multi-dimensional filter using a given function
generic_filter1d - 1-D generic filter along the given axis
generic_gradient_magnitude
generic_laplace
laplace - n-D Laplace filter based on approximate second derivatives
maximum_filter
maximum_filter1d
median_filter - Calculates a multi-dimensional median filter
minimum_filter
minimum_filter1d
percentile_filter - Calculates a multi-dimensional percentile filter
prewitt
rank_filter - Calculates a multi-dimensional rank filter
sobel
uniform_filter - Multi-dimensional uniform filter
uniform_filter1d - 1-D uniform filter along the given axis
Fourier filters
===============
fourier_ellipsoid
fourier_gaussian
fourier_shift
fourier_uniform
Interpolation
=============
affine_transform - Apply an affine transformation
geometric_transform - Apply an arbritrary geometric transform
map_coordinates - Map input array to new coordinates by interpolation
rotate - Rotate an array
shift - Shift an array
spline_filter
spline_filter1d
zoom - Zoom an array
Measurements
============
center_of_mass - The center of mass of the values of an array at labels
extrema - Min's and max's of an array at labels, with their positions
find_objects - Find objects in a labeled array
histogram - Histogram of the values of an array, optionally at labels
label - Label features in an array
labeled_comprehension
maximum
maximum_position
mean - Mean of the values of an array at labels
median
minimum
minimum_position
standard_deviation - Standard deviation of an n-D image array
sum - Sum of the values of the array
variance - Variance of the values of an n-D image array
watershed_ift
Morphology
==========
binary_closing
binary_dilation
binary_erosion
binary_fill_holes
binary_hit_or_miss
binary_opening
binary_propagation
black_tophat
distance_transform_bf
distance_transform_cdt
distance_transform_edt
generate_binary_structure
grey_closing
grey_dilation
grey_erosion
grey_opening
iterate_structure
morphological_gradient
morphological_laplace
white_tophat
Utility
=======
imread - Load an image from a file
"""
哦,现在有原创标志了,我就不厚脸皮说是自己原创了,哈哈哈。!!
[参考文献]
1. http://www.scipy-lectures.org/packages/scikit-image/
2. https://www.scipy.org/