本文主要内容来源于书籍《python计算机视觉编程》
我是一名初学者,如果你发现文中有错误,请留言告诉我,谢谢


PIL模块

PIL模块全程为Python Imaging Library,是python中一个免费的图像处理模块。


打开图像

PIL模块常用到它的Image类,打开图像首先要导入Image类
from PIL import Image
然后调用Imageopen方法。
例如

from PIL import Image

image = Image.open("smallpi.jpg") # 返回一个Image图像对象
print(image)
# 结果
<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=800x450 at 0x4731348>
 

图像的保存及格式转换

图像保存用的是Image对象的save()方法,传入的参数为保存图像文件的名字。
当传入不同的扩展名时,它会根据扩展名自动转换图像的格式。
例如

from PIL import Image

image = Image.open("smallpi.jpg") # 打开jpg图像文件
image.save("smallpi.png") # 保存图像,并转换成png格式
 

 

转化成灰度图像

获得Image对象后,调用其convert()方法,传入参数"L",即可以返回该图像的灰度图像对象。

from PIL import Image

image = Image.open("smallpi.jpg")

image_gray = image.convert("L") # 转化成灰度图像
print(image_gray)
# 结果
<PIL.Image.Image image mode=L size=800x450 at 0x46AD648>

Image对象与图像矩阵相互转化

Image对象转化成图像矩阵

Image对象转化成图像矩阵只要将Image对象作为numpy.array()参数即可。

import numpy as np
from PIL import Image image = Image.open("smallpi.jpg")
image_array = np.array(image)
print(image_array)
# 结果
[[[177 177 177]
[177 177 177]
[176 176 176]
...,
#此处省略
...,
[232 232 232]
[232 232 232]
[232 232 232]]]

图像矩阵转化成Image对象

图像矩阵转化成Image对象通过Image模块的fromarray()方法。

import numpy as np
from PIL import Image image = Image.open("smallpi.jpg")
image_array = np.array(image.convert("L"))
image_array = 255 - image_array # 图像矩阵处理,将灰度图像反相
# 反相指的是,黑变白,白变黑
image2 = Image.fromarray(image_array)
print(image2)
# 结果
<PIL.Image.Image image mode=RGB size=800x450 at 0x4753748>

 

图像的显示

图像的显示需要用到matplotlib模块。
首先需要导入matplotlib.pyplot
import matplotlib.pyplot as plt
然后,调用pyplot的imshow()方法,传入Image对象即可

from PIL import Image
import matplotlib.pyplot as plt image = Image.open("smallpi.jpg")
plt.imshow(image) # 绘制图像image
plt.show() # 需要调用show()方法,不然图像只会在内存中而不显示出来

 

图像显示结果(带坐标轴)

如果想把坐标轴去掉只需要调用pyplot的axis()方法,传入"off"参数

from PIL import Image
import matplotlib.pyplot as plt image = Image.open("smallpi.jpg")
plt.imshow(image) # 绘制图像image
plt.axis("off") # 去掉坐标轴
plt.show() # 需要调用show()方法,不然图像只会在内存中而不显示出来 

图像显示结果(不带坐标轴)

如果要显示灰度图像,需要导入matplotlib的cm模块
import matplotlib.cm as cm
然后在调用pyplot.show()时,传入关键字参数cmap=cm.gray

from PIL import Image
import matplotlib.pyplot as plt
import matplotlib.cm as cm image = Image.open("smallpi.jpg") # 打开图像
image_gray = image.convert("L") # 转化成灰度图像 plt.subplot(2,1,1)
plt.imshow(image_gray) # 没传入关键字参数cmap=cm.gray
plt.axis("off") # 去掉坐标轴 plt.subplot(2,1,2)
plt.imshow(image_gray, cmap=cm.gray) # 指明 cmap=cm.gray
plt.axis("off") # 去掉坐标轴 plt.show() # 显示图像 

显示结果
上:没指定cmap , 下:指定cmap=cm.gray


创建缩略图

创建图像缩略图可以通过Image的thumbnail()方法,参数传入一个元组,指明缩略图的大小,如thumbnail((128,128))
例如

from PIL import Image

image = Image.open("smallpi.jpg")
image_thumbnail = image.thumbnail((128,128)) image.save("thumbnail.jpg") 

结果为


复制和粘贴区域

复制区域是指截取图像中的一部分,并将这一部分作为一个新的Image对象。
复制区域的方法为crop(),参数为一个含4个元素的元组,用来指定截取区域的左上角点和右下角点。

from PIL import Image

image = Image.open("smallpi.jpg") # 打开图像
box = (300,100,500,300) # 截取区域
image_crop = image.crop(box) # 按指定截取区域对图像进行截取复制 image_crop.save("image_crop.jpg") # 保存

保存的截取区域图像为

粘贴区域是指在指定图像中放入另一个图像,其方法为paste()。该方法有两个参数,第一个参数为需要粘贴进去的图像,第二个参数为粘贴区域。

from PIL import Image

image = Image.open("smallpi.jpg")
box = (300,100,500,300) # 先截取一部分
image_crop = image.crop(box) # 为了看到粘贴效果,现将截取部分转180度
image_crop = image_crop.transpose(Image.ROTATE_180) # 转180度
image.paste(image_crop,box) # 将转180度后的图像粘贴到原图像 image.save("image_paste.jpg")
粘贴后原图像变成 


图像的尺寸调整和旋转

尺寸调整方法为resize(),参数为一元组,指定调整后的大小,如resize((128,128))。
图像旋转的方法为
rotate(),参数为旋转角度(数值,单位为度),逆时针方向,如rotate(45)`

from PIL import Image

image = Image.open("smallpi.jpg")

image_resize = image.resize((200,200)) # 尺寸调整
image_rotate = image.rotate(45) # 图像旋转
# image.transpose()也可以旋转图像,但只能旋转90度的整数倍
# 参数为 Image.ROTATE_90 旋转90度
# 180度,270度可类推 image_resize.save("image_resize.jpg")
image_rotate.save("image_rotate.jpg")

尺寸调整为200*200

图像逆时针旋转45度


图像直方图

图像直方图用来统计图像中像素值的分布情况,即统计不同像素值出现的次数。方法为调用matplotlib.pyplothist方法,参数传入图像像素序列和统计区间个数。

from PIL import Image
import matplotlib.pyplot as plt
import matplotlib.cm as cm #打开图像,并转化成灰度图像
image = Image.open("smallpi.jpg").convert("L")
image_array = np.array(image) plt.subplot(2,1,1)
plt.imshow(image,cmap=cm.gray)
plt.axis("off")
plt.subplot(2,1,2)
plt.hist(image_array.flatten(),256) #flatten可以将矩阵转化成一维序列
plt.show()

结果为


灰度变换

对于一张灰度图像,其每个像素点都用一个0-255之间的值表示,0表示黑色,越接近0越黑;255表示白色,越接近255越白。
灰度变换就是通过一个特定的函数,使灰度值从一个值转换成另外一个值。
这里列出3种灰度变换

1. 【反相】变换后的灰度值= 255−原灰度值

2.【转换到100-200】变换后的灰度值 =(原灰度值/255)*100+100

3. 【像素平方】变换后的灰度值 = 255*(原灰度值/255)2

2

from PIL import Image
import matplotlib.pyplot as plt
import matplotlib.cm as cm image = Image.open("smallpi.jpg").convert("L")
image_array = np.array(image) x = np.arange(255) # 反相
plt.subplot(3,2,1)
plt.plot(x,255-x) # 画出变换函数图像
plt.subplot(3,2,2)
plt.imshow(Image.fromarray(255-image_array),cmap=cm.gray)
plt.axis("off") # 转换到 100-200
plt.subplot(3,2,3)
plt.plot(x,(x/255.0)*100+100) # 画出变换函数图像
plt.subplot(3,2,4)
plt.imshow( Image.fromarray((image_array/255.0)*100+100), cmap=cm.gray )
plt.axis("off") # 像素平方
plt.subplot(3,2,5)
plt.plot(x,255*(x/255.0)**2) # 画出变换函数图像
plt.subplot(3,2,6)
plt.imshow( Image.fromarray(255*(image_array/255.0)**2), cmap=cm.gray )
plt.axis("off") plt.show()

 

`结果如下,(左边是变换函数,右边是图像变换结果)


直方图均衡化

由上面图像的直方图可以看出,一般情况下,图像上某些灰度值较多,有些灰度值较少,直方图均衡化为的是使灰度值较为均衡。

直方图均衡化是利用直方图的累积函数作为灰度变换函数,对图像进行转换。直方图均衡化可以增强图像的对比度。

累积函数和概率论中的累积分布函数类似。例如对于还有5个数的序列[1,2,3,4,5],其累积函数含有5个数,第一个数是1,第二个是1+2=3,……,第五个数是1+2+3+4+5=15,所以其累积函数是[1,3,6,10,15]。

我们把直方图均衡化的过程封装在一个函数里面,函数名字叫做histeq,输入原图像矩阵和直方图分块数,输出均衡化后的图像矩阵和累积函数。

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib.cm as cm def histeq(image_array,image_bins=256): # 将图像矩阵转化成直方图数据,返回元组(频数,直方图区间坐标)
image_array2,bins = np.histogram(image_array.flatten(),image_bins) # 计算直方图的累积函数
cdf = image_array2.cumsum() # 将累积函数转化到区间[0,255]
cdf = (255.0/cdf[-1])*cdf # 原图像矩阵利用累积函数进行转化,插值过程
image2_array = np.interp(image_array.flatten(),bins[:-1],cdf) # 返回均衡化后的图像矩阵和累积函数
return image2_array.reshape(image_array.shape),cdf image = Image.open("pika.jpg").convert("L")
image_array = np.array(image)
plt.subplot(2,2,1)
plt.hist(image_array.flatten(),256)
plt.subplot(2,2,2)
plt.imshow(image,cmap=cm.gray)
plt.axis("off") a = histeq(image_array) # 利用刚定义的直方图均衡化函数对图像进行均衡化处理
plt.subplot(2,2,3)
plt.hist(a[0].flatten(),256)
plt.subplot(2,2,4)
plt.imshow(Image.fromarray(a[0]),cmap=cm.gray)
plt.axis("off") plt.show()

结果如下图所示,第一行为原图像直方图和原图像,第二行为均衡化后的直方图和图像。可以看出均衡化后图像对比度增强了,原先灰色区域的细节变得清晰。

python计算机视觉1:基本操作与直方图的更多相关文章

  1. 《Python计算机视觉编程》

    <Python计算机视觉编程> 基本信息 作者: (美)Jan Erik Solem 译者: 朱文涛 袁勇 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:978711535 ...

  2. Python计算机视觉3:模糊,平滑,去噪

    我是一名初学者,如果你发现文中有错误,请留言告诉我,谢谢 图像的模糊和平滑是同一个层面的意思,平滑的过程就是一个模糊的过程. 而图像的去噪可以通过图像的模糊.平滑来实现(图像去噪还有其他的方法) 那么 ...

  3. python计算机视觉2:图像边缘检测

    我是一名初学者,如果你发现文中有错误,请留言告诉我,谢谢 如果需要检测到图像里面的边缘,首先我们需要知道边缘处具有什么特征. 对于一幅灰度图像来说,边缘两边的灰度值肯定不相同,这样我们才能分辨出哪里是 ...

  4. OpenCV Python教程(3、直方图的计算与显示)

    转载请详细注明原作者及出处,谢谢! 本篇文章介绍如何用OpenCV Python来计算直方图,并简略介绍用NumPy和Matplotlib计算和绘制直方图 直方图的背景知识.用途什么的就直接略过去了. ...

  5. python简介与基本操作

    一.python的历史 python的创始人Guido van Rossum,现就职于Dropbox公司. 1989年12月份诞生了python1.0 2000年10月16日发布了python2.0 ...

  6. Python初识文本基本操作

    初识文本的基本操作 怎么在文件里面写内容和都内容 文件操作过程 1,找到文件 文件路径 2,打开文件 file_obj=file(文件路径,模式) 3,文件操作,读写文件 file_obj.read( ...

  7. 推荐一个计算机视觉图书:python计算机视觉编程

    编辑部的主页:好像没啥用 http://shop.oreilly.com/product/0636920022923.do 每章的代码,github上面的:中文版 https://github.com ...

  8. python计算机视觉项目实践

    这是一个贝叶斯模型的计算机视觉小项目.希望大家通过这个简单的项目知道一般的计算机视觉项目是怎样操作的. 我先讲题目放在这里希望有兴趣的童鞋花一周的时间思考并用python实现.一周以后我来发布我的详细 ...

  9. Python: 字典的基本操作

    字典是Python里唯一的映射类型.字典是可变的.无序的.大小可变的键值映射,有时候也称为散列表或关联数组. 例子在下面: dic = {"apple":2, "oran ...

随机推荐

  1. Qt浅谈之四十五QSplitter实现自由伸缩滑动窗口

    一.简介 最近看到一篇Qt实现伸缩滑动的窗口的文章,但其代码不完整.便在此重新书写了完整的代码,并开源出来.窗口的中央有滑动条可以动态改变子窗口的大小,隐藏的按钮可以快速伸缩子窗口.其效果图如下: 二 ...

  2. IEqualityComparer<T>接口

    IEqualityComparer<T>接口的对象的主要作用在于自定义判断两个对象是否相等. 其中最常用的方法: bool Equals(T x, T y); 实现该方法用于比较两个对象是 ...

  3. mysql创建utf-8字符集数据库

    CREATE DATABASE db_name DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; CREATE DATABASE 的语法:CREA ...

  4. 关于API的设计和需求抽象

    一,先来谈抽象吧,因为抽象跟后面的API的设计是息息相关的 有句话说的好(不知道谁说的了):计算机科学中的任何问题都可以抽象出一个中间层就解决了. 抽象是指在思维中对同类事物去除其现象的.次要的方面, ...

  5. hdu2795--Billboard

    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=2795 摘要:有一块尺寸为h*w的矩形长板,要在上面贴1*wi的海报n张,选择贴海报的位置是:尽量高,同一 ...

  6. Hash Map (Hash Table)

    Reference: Wiki  PrincetonAlgorithm What is Hash Table Hash table (hash map) is a data structure use ...

  7. php 实现购物车

    <?php class Cart{     public function Cart() {         if(!isset($_SESSION['cart'])){             ...

  8. WebService-调用第三方提供的webService服务

    互联网上面有很多的免费webService服务,我们可以调用这些免费的WebService服务,将一些其他网站的内容信息集成到我们的Web应用中显示,下面就以获取天气预报数据和查询国内手机号码归属地为 ...

  9. [RxJS] Handling Multiple Streams with Merge

    You often need to handle multiple user interactions set to different streams. This lesson shows hows ...

  10. [Unit Testing] Based on input value, spyOn function

    describe( 'Forgot Password: with username', ()=> { let dirElementInput; beforeEach( ()=> { // ...