Python --数据处理

参考链接:http://www.cnblogs.com/denny402

文章目录:

一、图片的打开与显示

二、图片通道/几何变换/裁剪
1.彩色图像转灰度通道
2.通道合并与分离
3.裁剪图片
4.几何变换

三、图像中的像素访问

四、图像直方图

一、图片的打开与显示

要使用python,必须先安装python,一般是2.7版本以上

使用python进行数字图片处理,得安装Pillow包。虽然python里面自带一个PIL(python images library), 但这个库现在已经停止更新了,所以使用Pillow, 它是由PIL发展而来的。

pip install Pillow


from PIL import Image
img=Image.open('d:/dog.png')
img.show()

这种图片显示方式是调用操作系统自带的图片浏览器来打开图片

from PIL import Image
import matplotlib.pyplot as plt
img = Image.open('/home/mwp/1.png')
plt.figure('cancer')
plt.imshow(img)
plt.show()
print(img.size) #图片尺寸
print(img.mode) #图片模式
print(img.format) #图片格式
plt.axis('off')  #默认是on
img.save('/home/mwp/1.jpg') #不仅能保存图片,还能转换格式

二、图像通道/几何变换/裁剪

1.彩色图像转灰度图

from PIL import Image
import matplotlib.pyplot as plt
img = Image.open('/home/mwp/1.jpeg')
gray = img.convert('L') #转换成灰度
plt.figure('food')
plt.imshow(gray,cmap='gray')
plt.axis('off')
plt.show()

这里写图片描述
使用函数convert()来进行转换,它是图像实例对象的一个方法,接受一个 mode 参数,用以指定一种色彩模式,mode 的取值可以是如下几种:

· 1 (1-bit pixels, black and white, stored with one pixel per byte)
· L (8-bit pixels, black and white)
· P (8-bit pixels, mapped to any other mode using a colour palette)
· RGB (3x8-bit pixels, true colour)
· RGBA (4x8-bit pixels, true colour with transparency mask)
· CMYK (4x8-bit pixels, colour separation)
· YCbCr (3x8-bit pixels, colour video format)
· I (32-bit signed integer pixels)
· F (32-bit floating point pixels)

2、通道分离与合并

from PIL import Image
import matplotlib.pyplot as plt
img = Image.open('/home/mwp/1.jpeg')
gray = img.convert('L')
r,g,b = img.split()  #分离三通道
pic = Image.merge('RGB', (r,g,b)) #合并三通道
plt.figure('food')

plt.subplot(2,3,1)
plt.title('origin')
plt.imshow(img)
plt.axis('off')

plt.subplot(2,3,2)
plt.title('gray')
plt.imshow(gray,cmap='gray')
plt.axis('off')

plt.subplot(2,3,3)
plt.title('merge')
plt.imshow(pic)
plt.axis('off')

plt.subplot(2,3,4)
plt.title('r')
plt.imshow(r,cmap='gray')
plt.axis('off')

plt.subplot(2,3,5)
plt.title('g')
plt.imshow(g,cmap='gray')
plt.axis('off')

plt.subplot(2,3,6)
plt.title('b')
plt.imshow(b,cmap='gray')
plt.axis('off')

plt.show()

这里写图片描述

3.裁剪图片

from PIL import Image
import matplotlib.pyplot as plt
img = Image.open('/home/mwp/1.jpeg')
plt.figure('cancer')
plt.subplot(1,2,1)
plt.title('origin')
plt.imshow(img)
#plt.axis('off')

box=(80,100,260,300)
roi = img.crop(box)
plt.subplot(1,2,2)
plt.title('roi')
plt.imshow(roi)
#plt.axis('off')

plt.show()

这里写图片描述
用plot绘制显示出图片后,将鼠标移动到图片上,会在右下角出现当前点的坐标,以及像素值。

4.几何变换

Image类有resize()、rotate()和transpose()方法进行几何变换。
(1)图像的缩放和旋转

dst = img.resize((128, 128)) #图片缩放
dst = img.rotate(45) # 顺时针角度表示

(2)转换图像

dst = im.transpose(Image.FLIP_LEFT_RIGHT) #左右互换
dst = im.transpose(Image.FLIP_TOP_BOTTOM) #上下互换
dst = im.transpose(Image.ROTATE_90)  #顺时针旋转
dst = im.transpose(Image.ROTATE_180)
dst = im.transpose(Image.ROTATE_270)

transpose()和rotate()没有性能差别。

三、图像中的像素访问

前面的一些例子中,我们都是利用Image.open()来打开一幅图像,然后直接对这个PIL对象进行操作。如果只是简单的操作还可以,但是如果操作稍微复杂一些,就比较吃力了。因此,通常我们加载完图片后,都是把图片转换成矩阵来进行更加复杂的操作。

python中利用numpy库和scipy库来进行各种数据操作和科学计算。我们可以通过pip来直接安装这两个库

pip install numpy
pip install scipy

以后,只要是在python中进行数字图像处理,我们都需要导入这些包:

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt

打开图像并转化为矩阵,并显示:

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
img = np.array(Image.open('/home/mwp/1.png')) #打开图像并转换为数字矩阵
plt.figure('cancer')
plt.imshow(img)
plt.axis('off')
plt.show()

#查看图片信息
print(img.shape)
print(img.dtype)
print(img.size)
print(type(img))

这里写图片描述
如果是RGB图片,那么转换为array之后,就变成了一个rows*cols*channels的三维矩阵,因此,我们可以使用 img[i,j,k] 来访问像素值

例1:打开图片,并随机添加一些椒盐噪声

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
img=np.array(Image.open('/home/mwp/1.jpeg'))

#随机生成5000个椒盐
rows,cols,dims=img.shape
for i in range(5000):
    x=np.random.randint(0,rows)
    y=np.random.randint(0,cols)
    img[x,y,:]=255

plt.figure("beauty")
plt.imshow(img)
plt.axis('off')
plt.show()

这里写图片描述

例2:将lena图像二值化,像素值大于128的变为1,否则变为0

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
img = np.array(Image.open('/home/mwp/1.jpeg').convert('L'))

rows,cols=img.shape
for i in range(rows):
    for j in range(cols):
        if(img[i,j]<=128):
            img[i,j] = 0
        else:
            img[i,j] = 1

plt.figure('food')
plt.imshow(img,cmap='gray')
plt.axis('off')
plt.show()

这里写图片描述

如果要对多个像素点进行操作,可以使用数组切片方式访问。切片方式返回的是以指定间隔下标访问 该数组的像素值。下面是有关灰度图像的一些例子:

img[i,:] = im[j,:] # 将第 j 行的数值赋值给第 i 行

img[:,i] = 100 # 将第 i 列的所有数值设为 100

img[:100,:50].sum() # 计算前 100 行、前 50 列所有数值的和

img[50:100,50:100] # 50~100 行,50~100 列(不包括第 100 行和第 100 列)

img[i].mean() # 第 i 行所有数值的平均值

img[:,-1] # 最后一列

img[-2,:] (or im[-2]) # 倒数第二行

四、图像直方图

import numpy as np

#生成一个一维数组
vec = np.arange(15)
print('vec:',vec)

#将一维数组变成一个3*5的二维矩阵,用reshape()
mat = vec.reshape(3,5)
print('mat:',mat)

#将一个二维矩阵变成一个一维数组,用flatten()
a1 = mat.reshape(1,-1) #-1表示为任意,让系统自动计算
print('a1:',a1)

a2 = mat.flatten()
print('a2:',a2)
vec: [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]

mat: [[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]

a1: [[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]]

a2: [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14]

可以看出,用reshape进行变换,实际上变换后还是二维数组,两个方括号,因此只能用flatten.

我们要对图像求直方图,就需要先把图像矩阵进行flatten操作,使之变为一维数组,然后再进行统计。

1.画灰度图直方图

绘图都可以调用matplotlib.pyplot库来进行,其中的hist函数可以直接绘制直方图。

调用方式:

n, bins, patches = plt.hist(arr, bins=50, normed=1, facecolor='green', alpha=0.75)

hist的参数非常多,但常用的就这五个,只有第一个是必须的,后面四个可选

arr: 需要计算直方图的一维数组
bins: 直方图的柱数,可选项,默认为10
normed: 是否将得到的直方图向量归一化。默认为0
facecolor: 直方图颜色
alpha: 透明度

返回值 :
n: 直方图向量,是否归一化由参数设定
bins: 返回各个bin的区间范围
patches: 返回每个bin里面包含的数据,是一个list

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
img = np.array(Image.open('/home/mwp/1.jpeg').convert('L'))

plt.figure('lena')
arr = img.flatten()
n,bins,patches = plt.hist(arr, bins=256, normed=1, facecolor='blue', alpha=0.75)
plt.show()

这里写图片描述

2.彩色图片直方图

实际上是和灰度直方图一样的,只是分别画出三通道的直方图,然后叠加在一起。

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
src = Image.open('/home/mwp/1.jpeg')
r,g,b = src.split()

plt.figure('lena')

#r通道
ar = np.array(r).flatten()
plt.hist(ar, bins=256, normed=1, facecolor='r', edgecolor='r', hold=1)

#g通道
ag = np.array(g).flatten()
plt.hist(ag, bins=256, normed=1, facecolor='g', edgecolor='g',hold=1)

#b通道
ab = np.array(b).flatten()
plt.hist(ab, bins=256, normed=1, facecolor='b', edgecolor='b',hold=1)

plt.show()

这里写图片描述

由此可见,matplotlib的画图功能是非常强大的,直方图只是其中非常小的一部分,更多的请参看官方文档:

http://matplotlib.org/api/pyplot_summary.html

猜你喜欢

转载自blog.csdn.net/yato0514/article/details/79903389