python基本的图像操作和处理
目录:
-
PIL
- Matplotlib
- Numpy
PIL(图像处理类库)提供大量的图像处理操作,如:图像缩减、裁剪、旋转、颜色转换等。
1、读取图像
from PIL import Image
from matplotlib import pyplot as plt
img = Image.open('image.jpg')
plt.imshow(img)
type(img)
PIL.JpegImagePlugin.JpegImageFile
2、将彩色图像转化为灰度图像(还是matlab舒服:rgb2gray(img) 一步到位。。。)
img = Image.open('image.jpg').convert('L')
plt.imshow(img)
<matplotlib.image.AxesImage at 0x201011d6828>
3、保存图像为多种格式的文件
open()函数用于创建PIL图像对象,save()方法用于保存图像到具体指定文件名的文件;
#指定多种格式进行保存
img.save('image1.jpg')
4、创建缩略图
thumbnail()方法接受一个元组参数:也就是指定生成缩略图的大小(像素)
img.thumbnail((128,128))
plt.imshow(img)
<matplotlib.image.AxesImage at 0x2017ffaf780>
5、复制和粘贴图像区域
crop()方法从一幅图像中裁剪指定区域;该区域用四元组来指定;四元组坐标是(左,上,右,下),左上角起始左上角坐标(0,0),可以通过旋转上面的代码获取的区域,再通过paste()方法将该区域放回去;
box = (40,40,50,50)
region = img.crop(box)
plt.imshow(region)
<matplotlib.image.AxesImage at 0x2010130c3c8>
region = region.transpose(Image.ROTATE_180)
img.paste(region,box)
plt.imshow(img)
<matplotlib.image.AxesImage at 0x20101258e10>
6、调整尺寸和旋转
使用resize()方法,参数是一个元组,用以指定新图像的大小;然后使用逆时针旋转角度,然后调用rotate()方法
out = img.resize((128,128))
out = img.rotate(45)
plt.imshow(out)
<matplotlib.image.AxesImage at 0x201012b4278>
Matplotlib主要用于绘制图表
1、Matplotlib 可以绘制出较好的条形图、饼状图、散点图等;
from PIL import Image
from pylab import *
img = array(Image.open('jianzhu.jpg'))
imshow(img)
#定义一些点:对应(x,y)坐标
x = [100,100,300,300]
y = [200,400,200,400]
#使用红星标记绘制点
plot(x,y,'r*')
#绘制连接前两个点的线
plot(x[:2],y[:2])
#绘制前三个点
plot(x[:3],y[:3])
#添加标题,显示绘制的图像
title('Plotting: "jianzhu.jpg"')
show()
#不显示坐标
axis('off')
Text(0.5, 1.0, 'Plotting: "jianzhu.jpg"')
plot(x,y) # 默认为蓝色实线
plot(x,y,'r*') # 红色星状标记
plot(x,y,'go-') # 带有圆圈标记的绿线
plot(x,y,'ks:') # 带有正方形标记的黑色虚线
表1 pylab库绘制图的基本颜色格式命令
'b' | 蓝色 |
'g' | 绿色 |
'r' | 红色 |
'c' | 青色 |
'm' | 品红 |
'y' | 黄色 |
'k' | 黑色 |
'w' | 白色 |
表2 用pylab库绘制基本线型格式命令
线型 | |
'_' | 实线 |
’__' | 虚线 |
':' | 点线 |
表3 用pylab库绘图的基本绘制标记格式命令
标记 | |
'.' | 点 |
'o' | 圆圈 |
's' | 正方形 |
'*' | 星形 |
'+' | 加号 |
'×' | 叉号 |
2、图像的轮廓和直方图
因为绘制轮廓需要对每个坐标 [x, y] 的像素值施加同一个阈值,所以首先需要将图像灰度化,前面已经说过如何转换灰度图像
hist() 函数的第二个参数指定小区间的数目。需要注意的是,因为 hist() 只接受一维数组作为输入,所以我们在绘制图像直方图之前,必须先对图像进行压平处理。flatten() 方法将任意数组按照行优先准则转换成一维数组。
from PIL import Image
from pylab import *
im = array(Image.open('jianzhu.jpg').convert('L'))
#新建一个图像
figure()
gray()
contour(im,origin='image')
axis('equal')
axis('off')
figure()
hist(im.flatten(),128)
show()
3、交互式标注
使用ginput()函数可以在一幅图像中标记一些点或者标注一些训练数据
from PIL import Image
from pylab import *
im = array(Image.open('jianzhu.jpg'))
imshow(im)
print('Please click 3 points!')
x = ginput(3)
print('you clicked:',x)
show()
NumPy:python科学计算工具包;在线说明书:http://docs.scipy.org/doc/numpy/
其中的数组对象是多维的,可以用来表示向量、矩阵和图像
1、图像数组表示
im = array(Image.open('jianzhu.jpg'))
#查看图像的信息
print(im.shape,im.dtype)
(625, 500, 3) uint8
im = array(Image.open('jianzhu.jpg').convert('L'))
print(im.shape,im.dtype)
(625, 500) uint8
表示图像数组的大小(行、列、颜色通道) ,紧接着的字符串表示数组元素的数据类型
数组中的元素可以使用下标访问;
value = im[i,j,k]
多个数组元素可以使用数组切片方式进行访问,切片方式返回的是以指定间隔下标访问数组的元素值;负数切片表示从最后一个元素逆向计数;
im[i,:] = im[j,:] # 将第 j 行的数值赋值给第 i 行
im[:,i] = 100 # 将第 i 列的所有数值设为 100
im[:100,:50].sum() # 计算前 100 行、前 50 列所有数值的和
im[50:100,50:100] # 50~100 行,50~100 列(不包括第 100 行和第 100 列)
im[i].mean() # 第 i 行所有数值的平均值
im[:,-1] # 最后一列
im[-2,:] (or im[-2]) # 倒数第二行
2、灰度变换
array()变换的相反操作可以使用PIL的fromarray()函数完成,也就是一个反向操作,将数组类型转回去
from PIL import Image
from numpy import *
#转为灰度图像
im = array(Image.open('jianzhu.jpg').convert('L'))
#对图像进行反相处理
im2 = 255 - im
#将像素值变换到100...200区间
im3 = (100.0/255)*im + 100
#将图像像素值求平方后得到的图像
im4 = 255.0 * (im/255.0)**2
#像素的最小和最大值
print(int(im3.min()),int(im3.max()))
#将三个图像绘制在一张图像上
import matplotlib.pyplot as plt
plt.figure()
plt.subplot(1,3,1)
title('im2')
plt.imshow(im2)
axis('off')
plt.subplot(1,3,2)
title('im3')
plt.imshow(im3)
axis('off')
plt.subplot(1,3,3)
title('im4')
plt.imshow(im4)
axis('off')
plt.show()
100 200
type(im2)
numpy.ndarray
pil_im = Image.fromarray(im)
#查看转换后的类型
type(pil_im)
pil_im = Image.fromarray(uint8(im))
type(pil_im)
PIL.Image.Image
3、图像缩放
NumPy的数组对象是我们处理图像和数据的主要工具
def imresize(im,sz):
pil_im = Image.fromarray(uint8(im))
return array(pil_im.imresize(sz))
4、直方图均衡化
直方图均衡化是将一幅图像的灰度直方图变平,使变换后的图像中每个灰度值的分布概率都相同;直方图均衡化是对图像灰度值进行归一化的一个好的方法,可以增强图像的对比度。
直方图均衡化的变换函数是图像中像素值的累积分布函数(cumulative distribution function,简写为 cdf,将像素值的范围映射到目标范围的归一化操作)
#直方图均衡化
#前提是输入图像是灰度图像;得将彩色图像转换为灰度图像
def histeq(im,nbr_bins=256):
imhist,bins = histogram(im.flatten(),nbr_bins,normed=True)
cdf = imhist.cumsum()
cdf = 255 * cdf / cdf[-1] #归一化
#使用累积分布函数的线性插值,计算新的像素值
im2 = interp(im.flatten(),bins[:-1],cdf)
return im2.reshape(im.shape),cdf
from PIL import Image
from numpy import *
im1 = array(Image.open('jianzhu.jpg').convert('L'))
im2,cdf = histeq(im1)
import matplotlib.pyplot as plt
plt.imshow(im2)
<matplotlib.image.AxesImage at 0x25d09527a58>
hist(cdf,128)
处理前的直方图:im1
5、图像平均
主要用于减少图像噪声,通常用于艺术特效;
#计算图像列表的平均图像
def compute_average(imlist):
averageim = array(Image.open(imhist[0]),'f')
for imname in imlist[1:]:
try:
averageim += array(Image.open(imname))
except:
print(imname+'...skipped')
averageim /= len(imlist)
return array(averageim,'uint8')
同样也可以使用mean()函数计算平均图像,mean()函数需要将所有的图像堆积到一个数组中!
参考:python计算机视觉编程!!!
上一篇: Java8中的流操作-基本使用&性能测试
下一篇: 希尔排序—Shell