python计算机视觉1:基本操作与直方图
本文主要内容来源于书籍《python计算机视觉编程》
我是一名初学者,如果你发现文中有错误,请留言告诉我,谢谢
PIL模块
PIL模块全程为Python Imaging Library,是python中一个免费的图像处理模块。
打开图像
PIL模块常用到它的Image类,打开图像首先要导入Image类
from PIL import Image,
然后调用Image的open方法。
例如
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.pyplot的hist方法,参数传入图像像素序列和统计区间个数。
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:基本操作与直方图的更多相关文章
- 《Python计算机视觉编程》
<Python计算机视觉编程> 基本信息 作者: (美)Jan Erik Solem 译者: 朱文涛 袁勇 丛书名: 图灵程序设计丛书 出版社:人民邮电出版社 ISBN:978711535 ...
- Python计算机视觉3:模糊,平滑,去噪
我是一名初学者,如果你发现文中有错误,请留言告诉我,谢谢 图像的模糊和平滑是同一个层面的意思,平滑的过程就是一个模糊的过程. 而图像的去噪可以通过图像的模糊.平滑来实现(图像去噪还有其他的方法) 那么 ...
- python计算机视觉2:图像边缘检测
我是一名初学者,如果你发现文中有错误,请留言告诉我,谢谢 如果需要检测到图像里面的边缘,首先我们需要知道边缘处具有什么特征. 对于一幅灰度图像来说,边缘两边的灰度值肯定不相同,这样我们才能分辨出哪里是 ...
- OpenCV Python教程(3、直方图的计算与显示)
转载请详细注明原作者及出处,谢谢! 本篇文章介绍如何用OpenCV Python来计算直方图,并简略介绍用NumPy和Matplotlib计算和绘制直方图 直方图的背景知识.用途什么的就直接略过去了. ...
- python简介与基本操作
一.python的历史 python的创始人Guido van Rossum,现就职于Dropbox公司. 1989年12月份诞生了python1.0 2000年10月16日发布了python2.0 ...
- Python初识文本基本操作
初识文本的基本操作 怎么在文件里面写内容和都内容 文件操作过程 1,找到文件 文件路径 2,打开文件 file_obj=file(文件路径,模式) 3,文件操作,读写文件 file_obj.read( ...
- 推荐一个计算机视觉图书:python计算机视觉编程
编辑部的主页:好像没啥用 http://shop.oreilly.com/product/0636920022923.do 每章的代码,github上面的:中文版 https://github.com ...
- python计算机视觉项目实践
这是一个贝叶斯模型的计算机视觉小项目.希望大家通过这个简单的项目知道一般的计算机视觉项目是怎样操作的. 我先讲题目放在这里希望有兴趣的童鞋花一周的时间思考并用python实现.一周以后我来发布我的详细 ...
- Python: 字典的基本操作
字典是Python里唯一的映射类型.字典是可变的.无序的.大小可变的键值映射,有时候也称为散列表或关联数组. 例子在下面: dic = {"apple":2, "oran ...
随机推荐
- pubwin数据云备份
由于pubwin自带的异地备份一直不好用,并且pubwin自带的37分钟备份也不方便手动备份,考虑用python 与写一个基于酷盘的pubwin数据备份工具(本来想基于百度云的,发现百度云用的人太多, ...
- C语言初学 俩数相除问题
#include<stdio.h> #include<stdlib.h> main() { double a,b; scanf(&q ...
- Activiti工作流学习-----基于5.19.0版本(5)
五.与Spring集成 实际项目中一般都有Spring的身影,与Spring集成使得Activiti的实用性得到提高.activiti和Spring整合需要activiti-spring的jar在类路 ...
- resumable.js —— 基于 HTML 5 File API 的文件上传组件 支持续传后台c#实现
在git上提供了java.nodejs.c#后台服务方式:在这里我要用c#作为后台服务:地址请见:https://github.com/23/resumable.js 我现在visual studio ...
- Codeforces 545C Woodcutters
http://codeforces.com/contest/545/problem/C 题目大意: 给n棵树的在一维数轴上的坐标,以及它们的高度.现在要你砍倒这些树,树可以向左倒也可以向右倒,砍倒的树 ...
- hdu4641-K-string(后缀自动机)
Problem Description Given a string S. K-string is the sub-string of S and it appear in the S at leas ...
- Java中的ThreadLocal深入理解
提到ThreadLocal,有些Android或者Java程序员可能有所陌生,可能会提出种种问题,它是做什么的,是不是和线程有关,怎么使用呢?等等问题,本文将总结一下我对ThreadLocal的理解和 ...
- Mybatis 开发中遇见的异常及处理
1 异常信息: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.Bin ...
- pkill killall kill pidof
http://blog.csdn.net/whycold/article/details/11771841 http://www.cnblogs.com/rsky/p/4886043.html ht ...
- 解决selenium 启动ie浏览器报错:Unexpected error launching Internet Explorer. Protected Mode settings are not the same for all zones
启动ie代码: System.setProperty("webdriver.ie.driver", "bin/IEDriverServer.exe"); Web ...