本文主要内容来源于书籍《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. 向asp.net项目中添加控件AspNetPager

    1.打开项目,把.dll文件放入项目中: 2.在工具栏中添加一个自定义选项卡

  2. UC/OS操作系统 (转)

    1.和其他一些著名的嵌入式操作系统不同,uC/OS-II在单片机系统中的启动过程比较简单,不像有些操作系统那样,需要把内核编译成一个映像文件写入ROM中,上电复位后,再从ROM中把文件加载到RAM中去 ...

  3. 自制单片机之七……RS232串口

    在我的板子上其它的部分都已完成了,现在就剩下RS232串口了.串口对于单片机很重要,有了它就可以和PC通信了,可以用PC来控制你的单片机,也可以将你单片机上采集的数据传到PC上. 留的位置好像有点挤. ...

  4. 给Qt生成的exe执行程序添加版本信息

    Windows下的.exe可执行文件的属性中有版本这个信息,含有版本信息.描述.版权等.对于qt程序,要含有这样的信息,那就请如下操作:新建<工程名>.rc文件,在rc文件填入下的信息: ...

  5. centos下httpd 启动失败的解决办法

    [root@csit yang]# service httpd start Starting httpd:                                            [FA ...

  6. 【转】Android 之 下拉框(Spinner)的使用

    原文网址:http://imshare.iteye.com/blog/770950 下拉列表 Spinner. Spinner的使用,可以极大提高用户的体验性.当需要用户选择的时候,可以提供一个下拉列 ...

  7. 利用linux信号机制调试段错误(Segment fault)

    在实际开发过程中,大家可能会遇到段错误的问题,虽然是个老问题,但是其带来的隐患是极大的,只要出现一次,程序立即崩溃中止.如果程序运行在PC中,segment fault的调试相对比较方便,因为可以通过 ...

  8. POJ1845 数论 二分快速取余

    大致题意: 求A^B的所有约数(即因子)之和,并对其取模 9901再输出. 解题思路: 应用定理主要有三个: (1)   整数的唯一分解定理: 任意正整数都有且只有一种方式写出其素因子的乘积表达式. ...

  9. c语言指针与结构体

    #include <stdio.h> #include <stdlib.h> struct mydata { int num; ]; }; void main1() { /*i ...

  10. Hadoop 2、配置HDFS HA (高可用)

    前提条件 先搭建 http://www.cnblogs.com/raphael5200/p/5152004.html 的环境,然后在其基础上进行修改 一.安装Zookeeper 由于环境有限,所以在仅 ...