前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[编程经验] SciPy之图像处理小结

[编程经验] SciPy之图像处理小结

作者头像
用户1622570
发布2018-04-11 15:57:15
3K0
发布2018-04-11 15:57:15
举报
文章被收录于专栏:机器学习和数学

Python中可以处理图像的module有很多个,比如Opencv,Matplotlib, Numpy, PIL以及今天要分享的SciPy。其他几个后续都会总结一下,今天主要是SciPy。SciPy是Python 中一个科学计算(线性代数,统计,优化等)的module,但它的功能不限于计算,还包括信号和图像处理。Python中科学计算比较有名还有Pandas,堪称数据处理中的“瑞士军刀”。其中Numpy和SciPy底层是用c语言实现的,所以速度很快,所以使用它们的频率非常高,经常会把数据处理成numpy数组的形式。由于我现在主要做的图像这块,所以对每个module中图像处理的都比较感兴趣,会对比它们之间处理图像的区别。今天先把SciPy中图像处理的方法做个总结。

先把要使用的module导入进来

代码语言:javascript
复制
# 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.

代码语言:javascript
复制
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”

代码语言:javascript
复制
print type(img)

<type 'numpy.ndarray'>

img的类型为numpy的n维数组,所以我们平时看到的图片,其实 在我心里就是一堆阿拉伯数字!囧!

# 改变图像的大小

代码语言:javascript
复制
imresize(arr, size, interp='bilinear', mode=None):

misc.imresize方法可以改变图像的大小,第一个参数是原始图像的数组,第二个参数是改变后图像的大小,第三个是插值的方法,第四个和read的mode是一样的。

默认的插值方法是线性插值,另外还有紧邻插值,样条插值等,下面我们对比一下,每种插值得到图像的区别。

代码语言:javascript
复制
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,一般不用。

代码语言:javascript
复制
misc.imshow(img)

# 图片旋转

图片旋转的就是把图片旋转。!!旋转之后的区别在于旋转角度的不同而不同。misc.imrotate方法,其中第二个参数代表旋转角度, 第三个是插值方法。

代码语言:javascript
复制
imrotate(arr, angle, interp='bilinear')
代码语言:javascript
复制
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),就是这个

先来看第一个方法,高斯滤波。图像滤波我们在前面曾经说过一次,不了解的童鞋可以看一下前面的文章。

代码语言:javascript
复制
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矩阵。

代码语言:javascript
复制
>>> 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]])

然后我们实验一下不同标准差的滤波器,得到的图像会有什么差别。

代码语言:javascript
复制
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

代码语言:javascript
复制
fourier_gaussian(input, sigma, n=-1, axis=-1, output=None)
代码语言:javascript
复制
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一样。

代码语言:javascript
复制
zoom(input, zoom, output=None, order=3, mode='constant',
     cval=0.0, prefilter=True)

zoom 方法是一个做插值的方法,可以针对n维图像。其中zoom参数是一个浮点数或者序列类型。

数据是这个样子的,全部数据是这样的600个。

.zraw格式是raw格式的压缩版,而.raw格式是一种常用的图像存储方法。有很多方法可以把图像变化为.raw格式,比如:

代码语言:javascript
复制
img = misc.imread("depu.jpg")
img.tofile('depu.raw')  

我们需要另外一个库,叫SimpleITK,就是ITK库的简化版,ITK安装比较麻烦,尤其是Windows,所以我就安装了SimpleITk。

代码语言:javascript
复制
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方法列表

代码语言:javascript
复制
"""
=========================================================
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/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-05-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 机器学习和数学 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档