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

时间:2022-05-08
本文章向大家介绍[编程经验] SciPy之图像处理小结,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

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/