Python计算机视觉编程第一章 基本的图像操作与处理
基本的图像操作与处理
- 一、基本介绍
- 1.1PIL:Python图像处理类库
- 1.2Matplotlib
- 1.3Numpy
- 1.4Scipy
- 二、例子练习
- 2.1PIL基础操作
- 2.1.1 转换图像格式
- 2.1.2 创建缩略图
- 2.1.3 复制和粘贴图像区域
- 2.1.4 调整尺寸和旋转
- 2.2Matplotlib例子练习
- 2.2.1绘制图像、点和线
- 2.2.2 图像轮廓和直方图
- 2.2.3 交互式标注
- 2.3 Numpy例子练习
- 2.3.1 图像数组表示
- 2.3.2 灰度变换
- 2.3.3 直方图均衡化
- 2.4Scipy例子练习
- 2.4.1 图像模糊
- 2.4.2 图像导数
- 2.4.3 形态学:对象计数
一、基本介绍
1.1PIL:Python图像处理类库
PIL(Python Imaging Library,图像处理类库)提供了通用的图像处理功能,以及大量有用的基本图像操作,比如图像缩放、裁剪、旋转、颜色转换等。PIL是免费的,可以从
http://www.pytonware.com/products/pil/下载
1.2Matplotlib
我们处理数学运算、绘制图表,或者在图像上绘制点、直线和曲线时,Matplotlib是个很好的类库,具有比PIL更强大的绘图功能。Matplotlib 可以绘制出高质量的图表,就像本书中的许多插图一样。Matplotlib 中的PyLab接口包含很多方便用户创建图像的函数。Matplotlib 是开源工具,可以从http://matplotlib.sourceforge.net/
免费下载。该链接中包含非常详尽的使用说明和教程。下面的例子展示了本书中需要使用的大部分函数。
1.3Numpy
Mumy (http://www.scipy.org/NumPy/)是非常有名的Python科学计算工具包,其中包含了大量有用的思想,比如数组对象(用来表示向量、矩阵、图像等)以及线性代数函数。NumPy 中的数组对象几乎贯穿用于本书的所有例子中1数组对象可以帮助你实现数组中重要的操作,比如矩阵乘积、转置、解方程系统、向量乘积和归一化,这为图像变形、对变化进行建模、图像分类、图像聚类等提供了基础。
NumPy可以从(http://www.scipy.org/Download)免费下载,在线说明文档(http://www.scipy.org/doc/numpy/)包含了你可能遇到的大多数问题的答案。关于NumPy的更多内容,请参考开源书籍[24]。
1.4Scipy
SciPy (http://scipy.org/)是建立在NumPy基础上,用于数值运算的开源工具包。SciPy提供很多高效的操作,可以实现数值积分、优化、统计、信号处理,以及对我们来说最重要的图像处理功能。接下来,本节会介绍SciPy中大量有用的模块。SciPy是个开源工具包,可以从http://scipy .org/Download下载。
二、例子练习
2.1PIL基础操作
利用PIL中的函数,我们可以从大多数图像格式文件中读取数据:
#读取一幅图像
from PIL import Image
pil_im=Image.open('Image.jpg') #也可以具体位置('D:/PyCharm code/temp1/Image.jpg')
还可以将其转换成灰度图像:
#转换成灰度图像
pil_im=Image.open('Image.jpg').convert('L')
编写代码:
from PIL import Image
import matplotlib.pyplot as pltif __name__=='__main__':#读取图像pil_im = Image.open('Image.jpg')plt.gray()plt.subplot(121)plt.title('(a) Original Image')plt.axis('off')plt.imshow(pil_im)#灰度化图像处理pli_il = Image.open('DImage.jpg').convert('L')plt.subplot(122)plt.title('(b) Grayscale Image')plt.axis('off')plt.imshow(pli_il)plt.show()
结果如图:
2.1.1 转换图像格式
通过save方法,PIL可以将图像保存成多种格式的文件。
save(filename,format) #保存文件并指定保存格式
编写代码:
from PIL import Imageif __name__=='__main__':#图片信息具体位置要写出来例如:D:/PyCharm code/temp1/Image.jpgim = Image.open('Image.jpg','r')raccoon = im.save('Image.png', 'png')#刷新文件夹可以发现多了一个png的图像
2.1.2 创建缩略图
使用PIL可以很方便地创建缩略图。thumbnail()方法接受一个元祖参数(该参数指定生成缩略图大小),然后将图像转换成符合元组参数指定大小的缩略图。
例如,创建最长边为128像素的缩略图,可以用以下命令:
pil_im.thumbnail((128,128))
编写代码:
from PIL import Image
import matplotlib.pyplot as pltif __name__=='__main__':pil_im = Image.open('E:/student/temp/Image.jpg','r')plt.subplot(121)plt.title('(a) Original Image')plt.axis('off')plt.imshow(pil_im)pil_im.thumbnail((128, 128), resample=Image.BICUBIC)plt.subplot(122)plt.title('(b) Thumbnail Image')plt.axis('off')plt.imshow(pil_im)plt.show()
结果如下图:(这里缩略图变得模糊是由于matplot在呈现是默认将两幅图片放缩到一样的大小,实质上的缩略图是128×128像素的,将其拉伸变大就变得模糊了)
2.1.3 复制和粘贴图像区域
使用crop方法可以从一幅图像中裁剪指定区域:
box = (100,100,400,400)
region = pil_im.crop(box)
该区域使用四元组来指定。四元组的坐标依次是(左,上,右,下)。PIL中指定坐标系的左上角坐标为(0,0)。我们可以旋转上面代码获得的区域,然后使用paste方法将该区域放回去:
region = region.transpose(Image.ROTATE_180)
pil_im.paste(region,box)
编写代码:
from PIL import Image
import matplotlib.pyplot as pltif __name__=='__main__':pil_im = Image.open('E:/student/temp/Image.jpg')plt.subplot(121)plt.title('(a) Original Image')plt.axis('off')plt.imshow(pil_im)box = (100,100,400,400)region = pil_im.crop(box)region = region.transpose(Image.ROTATE_180)pil_im.paste(region,box)plt.subplot(122)plt.title('(b) Rotate Image')plt.axis('off')plt.imshow(pil_im)plt.show()
结果如下图:
2.1.4 调整尺寸和旋转
要调整一幅图像的尺寸,我们可以调用resize方法。该方法的参数是一个元祖,用来指定新图像的大小:
out = pil.resize((128,128))
要旋转一幅图像,可以使用逆时针方式表示旋转角度,然后调用rotate方法:
from PIL import Image
import matplotlib.pyplot as pltif __name__=='__main__':pil_im = Image.open('E:/学习/大三下/计算机视觉/Image.jpg')plt.subplot(131)plt.title('(a) Original Image')plt.axis('off')plt.imshow(pil_im)out1 = pil_im.resize((200,200))plt.subplot(132)plt.title('(b) Resize Image')plt.axis('off')plt.imshow(out1)out2 = pil_im.rotate(90)plt.subplot(133)plt.title('(c) Rotate Image')plt.axis('off')plt.imshow(out2)plt.show()
结果如下图:
2.2Matplotlib例子练习
2.2.1绘制图像、点和线
尽管Matplotlib可以绘制出较好的条形图、饼状图、散点图等,但是对于大多数计算机视觉应用来说,仅仅需要用到几个绘图指令。最重要的是,我们想用点和线来表示一些事物,比如兴趣点、对应点以及检测出的物体。下面是用几个点和一条线绘制图像的例子:
from PIL import Image
import matplotlib.pyplot as plt
from pylab import *if __name__=='__main__':im = array(Image.open('E:/学习/大三下/计算机视觉/WenDi.jpg'))imshow(im)x = [100,100,400,400]y = [200,500,200,500]plot(x,y,'r*') #红色星状线绘制标记点plot(x[:2],y[:2]) #连接前两个点的线title('Plotting:"WenDi.jpg"')show()
结果如图:
2.2.2 图像轮廓和直方图
绘制图像轮廓(或其他二维函数的等轮廓线)在工作中非常有用。因为绘制轮廓需要对每个坐标[x,y]的像素值施加同一个阈值,所以首先需要将图像灰度化
from PIL import Image
from pylab import *if __name__=='__main__':im = array(Image.open('E:/学习/大三下/计算机视觉/WenDI.jpg').convert('L'))figure()gray()contour(im,origin='image')axis('equal')axis('off')figure()hist(im.flatten(),128)show()
结果如图:
图像直方图用来表征该图像像素值的分布情况。用一定数目的小区间(bin)来指定表征像素值的范围,每个小区间会得到落入该小区间表示范围的像素数目。hist函数的第二个参数指定小区间的数目。这里需要注意的是,因为hist只接受一维数组作为输入。所以我们在绘制图像直方图之前,必须先对图像进行压平处理。flatten方法将任意数组按照行优先准则转换成一维数组。
2.2.3 交互式标注
有时用户需要和某些应用交互,例如在一幅图像中标记一些点,或者标注一些训练数据。函数ginput就可以实现交互性标注,下面例子首先绘制一幅图像,然后等待用户在绘图窗口的图像区域点击三次。程序将这些点击点坐标[x,y]自动保存在x列表里。
from PIL import Image
from pylab import *if __name__=='__main__':im = array(Image.open('E:/学习/大三下/计算机视觉/HuTao.jpg'))imshow(im)print('Please click 3 points')x = ginput(3)print('you clicked',x)show()
结果如图:
2.3 Numpy例子练习
2.3.1 图像数组表示
在先前的例子中,当载入图像时,我们通过调用array方法将图像转换为Numpy的数组对象,但当时并没有进行详细的介绍。Numpy中的数组对象是多维的,可以用来表示向量、矩阵和图像。一个数组对象很想一个列表(或者是列表的列表),但是数组中所有元素必须具有相同的数据类型。
对于图像数据,下面的例子阐述了这一点:
from PIL import Image
from pylab import *if __name__=='__main__':im = array(Image.open('E:/学习/大三下/计算机视觉/HuTao.jpg'))print(im.shape, im.dtype)im = array(Image.open('E:/学习/大三下/计算机视觉/HuTao.jpg').convert('L'),'f')print(im.shape, im.dtype)
结果如图:
这里每一行元组表示图像数组的大小(行、列、颜色通道),紧接着的字符串表示数组元素的数据类型。因为图像通常被编码成无符号八位整数(uint8),所以再第一种情况下,载入图像并将其转换到数组中,数组的数据类型为“uint8”。在第二种情况下,对图像进行灰度化处理,并且在穿件数组时使用额外的参数f;该参数将数据类型转换为浮点型。
2.3.2 灰度变换
将图像读入Numpy数组对象后,我们可以对他们执行任意数学操作。一个简单的例子就是图像的灰度变换。
from PIL import Image
from numpy import *
from pylab import *if __name__=='__main__':im = array(Image.open('E:/学习/大三下/计算机视觉/HuTao.jpg').convert('L'))im2 = 255 - im #对图像进行反相处理im3 = (100.0/255) * im + 100 #将图像像素值变换到100-200区间im4 = 255.0 * (im/255.0)**2 #对图像像素值求平方后得到图像figure()gray()subplot(1, 3, 1)imshow(im2)axis('off')title(r'(a) $f(x)=255-x$')subplot(1, 3, 2)imshow(im3)axis('off')title(r'(b) $f(x)=\frac{100}{255}x+100$')subplot(1, 3, 3)imshow(im4)axis('off')title(r'(c) $f(x)=255(\frac{x}{255})^2$')show()
结果如图:
2.3.3 直方图均衡化
图像灰度变换中一个非常有用的例子就是直方图均衡化。直方图均衡化是指将一幅图像的灰度直方图变平,使变换后的图像中每个灰度值的分布概率都相同。在对图像做进一步处理之前,直方图均衡化通常是对图像灰度值进行归一化的一个非常好 的方法,并且可以增强图像的对比度。
在这种情况下,直方图均衡化的变换函数是图像中像素的累积分布函数(简称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 pylab import *
from numpy import *
import imtoolsif __name__=='__main__':im = array(Image.open('E:/学习/大三下/计算机视觉/jimei2.jpg').convert('L'))im2, cdf = imtools.histeq(im)figure()subplot(2, 2, 1)axis('off')gray()title('(a)Original Image')imshow(im)subplot(2, 2, 2)axis('off')title('(b)Image After Histogram Equalization')imshow(im2)subplot(2, 2, 3)axis('off')title('(c)Histogram Of Original Image')hist(im.flatten(), 128, normed=True)subplot(2, 2, 4)axis('off')title('(d)Histogram After Equalization')hist(im2.flatten(), 128, normed=True)show()
结果如图:
2.4Scipy例子练习
2.4.1 图像模糊
图像的高斯模糊是非常经典的图像卷积例子。本质上,图像模糊就是将(灰度)图像I和一个高斯核进行卷积操作:
其中∗表示卷积操作;Gσ是标准差为σ的二维高斯核,定义为:
高斯模糊通常是其他图像处理操作的一部分,比如图像插值操作、兴趣点计算以及其他应用。
from PIL import Image
from numpy import *
from scipy.ndimage import filters
from pylab import *if __name__=='__main__':im = array(Image.open('E:\学习\大三下\计算机视觉\HuTao.jpg').convert('L'))gray()subplot(1,4,1)axis('off')title('Original Image')imshow(im)for bi, blur in enumerate([2, 5, 10]):im2 = zeros(im.shape)im2 = filters.gaussian_filter(im, blur)im2 = np.uint8(im2)imNum = str(blur)subplot(1, 4, 2 + bi)axis('off')title('GaussVar = ' + imNum)imshow(im2)show()
结果如图:
2.4.2 图像导数
上述计算图像导数的方法有一些缺陷:在该方法中,滤波器的尺度需要随着图像分 辨率的变化而变化。为了在图像噪声方面更稳健,以及在任意尺度上计算导数,我 们可以使用高斯导数滤波器:
其中,Gσx 和 Gσy 表示 Gσ 在 x 和 y 方向上的导数,Gσ 为标准差为 σ 的高斯函数。
from PIL import Image
from pylab import *
from scipy.ndimage import filters
import numpydef imx(im, sigma):imgx = zeros(im.shape)filters.gaussian_filter(im, sigma, (0, 1), imgx)return imgxdef imy(im, sigma):imgy = zeros(im.shape)filters.gaussian_filter(im, sigma, (1, 0), imgy)return imgydef mag(im, sigma):imgmag = 255 - numpy.sqrt(imgx ** 2 + imgy ** 2)return imgmagif __name__=='__main__':im = array(Image.open('E:\学习\大三下\计算机视觉\HuTao.jpg').convert('L'))figure()gray()sigma = [2, 5, 10]for i in sigma:subplot(3, 4, 4*(sigma.index(i))+1)axis('off')imshow(im)imgx=imx(im, i)subplot(3, 4, 4*(sigma.index(i))+2)axis('off')imshow(imgx)imgy=imy(im, i)subplot(3, 4, 4*(sigma.index(i))+3)axis('off')imshow(imgy)imgmag=mag(im, i)subplot(3, 4, 4*(sigma.index(i))+4)axis('off')imshow(imgmag)show()
结果如图:
2.4.3 形态学:对象计数
形态学(或数学形态学)是度量和分析基本形状的图像处理方法的基本框架与集合。形态学通常用于处理二值图像,但是也能够用于灰度图像。
计算图像中的对象个数与图像开操作可以通过下面的代码实现:
from PIL import Image
from numpy import *
from scipy.ndimage import measurements, morphology
from pylab import *if __name__=='__main__':im = array(Image.open('E:\学习\大三下\计算机视觉\HuTao.jpg').convert('L'))gray()subplot(221)imshow(im)axis('off')title('(a)Original Image')im = (im > 128)labels, nbr_objects = measurements.label(im)print("Number of objects:", nbr_objects)subplot(222)imshow(labels)axis('off')title('(b)Tag Image')im_open = morphology.binary_opening(im, ones((9, 5)), iterations=2)subplot(223)imshow(im_open)axis('off')title('(c)Original Image After Open Operation')labels_open, nbr_objects_open = measurements.label(im_open)print"Number of objects:", nbr_objects_opensubplot(224)imshow(labels_open)axis('off')title('(d)Tag Image After Open Operation')show()
结果如图:
Python计算机视觉编程第一章 基本的图像操作与处理相关推荐
- Python计算机视觉编程 第一章 基本的图像操作和处理
第一章 基本的图像操作和处理 1.1 PIL:Python图像处理类库 1.1.1转换图像格式 1.1.2创建缩略图 1.1.3复制和粘贴图像区域 1.1.4调整尺寸和旋转 1.2Matplotlib ...
- Python计算机视觉编程 第一章——基本的图像操作和处理
目录 1.1 PIL:Python图像处理类库 1.1.1 转换图像格式 1.1.2 创建缩略图 1.1.3 复制和粘贴图像区域 1.1.4 调整尺寸和旋转 1.2 Matplotlib 1.2.1 ...
- python计算机视觉编程——第一章(基本的图像操作和处理)
第1章 基本的图像操作和处理 1.1 PIL:Python图像处理类库 1.1.1 转换图像格式--save()函数 1.1.2 创建缩略图 1.1.3 复制并粘贴图像区域 1.1.4 调整尺寸和旋转 ...
- Python计算机视觉编程第九章——图像分割
Python计算机视觉编程 (一)图割(Graph Cut) 1.1 从图像创建图 1.2 用户交互式分割 (二)利用聚类进行分割 (三)变分法 (一)图割(Graph Cut) 图论中的图(grap ...
- Python计算机视觉编程第二章——局部图像描述子
Python计算机视觉编程 局部图像描述子 (一)Harris 角点检测器 (二)SIFT(尺度不变特征变换) 2.1 兴趣点 2.2 描述子 2.3 检测兴趣点 2.4 匹配描述子 (三)匹配地理标 ...
- Python计算机视觉:第一章 图像处理基础
第一章 图像处理基础 1.1 PIL-Python图像库 1.1.1 对图片进行格式转换 1.1.2 创建缩略图 1.1.3 拷贝并粘贴区域 1.1.4 调整尺寸及旋转 1.2 Matplotlib库 ...
- Python通用编程 - 第一章:用户交互
本文是Python通用编程系列教程,已全部更新完成,实现的目标是从零基础开始到精通Python编程语言.本教程不是对Python的内容进行泛泛而谈,而是精细化,深入化的讲解,共5个阶段,25章内容.所 ...
- python高性能编程第一章读书笔记
计算机底层组件分为三大基本部分:计算单元.存储单元以及两者之间的连接. 计算单元:具有将接收到的任意输入转换成输出的能力以及改变当前处理状态的能力.CPU是最常见的计算单元.它的主要属性是其每个周期能 ...
- python计算机视觉编程——基本的图像操作和处理
python计算机视觉编程--第一章(基本的图像操作和处理) 第1章 基本的图像操作和处理 1.1 PIL:Python图像处理类库 1.1.1 转换图像格式--save()函数 1.1.2 创建缩略 ...
最新文章
- 五分钟DBA:浅谈伪分布式数据库架构
- Java方法案例--比较两个值是否相等
- typescript 怎么表示当前时间减一个月_TypeScript 入门知识点总结
- jquery 文件预览功能
- Objective-C 反射机制
- 在Python中查找子字符串索引的5种方法
- leetcode1020. 飞地的数量(dfs)
- php 自定义行间距,phpstorm 常见设置
- 京东ajax怎么用,使用Ajax、json实现京东购物车结算界面的数据交互实例
- Net操作Excel(终极方法NPOI)
- nodejs 实践项目_NodeJS:最佳生产实践
- java thread lambda_Java8新特性--Lambda表达式
- mysql - 索引_07
- 基于内容的视频标注——物体层视频标注
- 编程中无穷大常量的设定技巧 2014-08-19 09:22 35人阅读 评论(0) 收藏...
- 脏检查 和 缓存清理机制
- PX4日志读取并转化为.scv文件、MATLAB显示
- 大学新颖的软件测试毕业论文题目50例
- 51单片机实验——模拟三台机器故障检测与指示系统
- 日本福岛核电站事故分析报告