NumPy(http://www.scipy.org/NumPy/) 是非常有名的Python 科学计算工具包,其中
包含了大量有用的思想,比如数组对象(用来表示向量、矩阵、图像等)以及线性
代数函数。数组对象可以帮助你实现数组中重要的操作,比如矩阵乘积、转置、
解方程系统、向量乘积和归一化,这为图像变形、对变化进行建模、图像分类、
图像聚类等提供了基础。
一。 图像数组表示:
将图片转化为数组矩阵,这样才能进行各种变换,使用数学的方法去完成各种问题
(1. 使用pylab中的array()
arrayIm = array(img)
(2.位于坐标i、j,以及颜色通道k 的像素值可以像下面这样访问:
value = arrayIm[i,j,k]
(3. python矩阵相关操作
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]) # 倒数第二行
二. 图片简单像素变换
python 中对于矩阵数组的操作比较有技巧,太符合python的风格了,简单优雅
例如:
im = array(Image.open('empire.jpg').convert('L'))
# 对图像进行反相处理(黑变白白变黑)
im2 = 255 - im
# 将图像像素值变换到100...200 区间(对比度比较弱)
im3 = (100.0/255) * im + 100
# 对图像像素值求平方后得到的图像(比源灰度图要对比度更强)
im4 = 255.0 * (im/255.0)**2
三. 图像缩放(貌似前面几篇有)
Image类中的resize()方法即可完成图像的缩放
pil_im.resize(size)
四. 直方图均衡化
图像灰度变换中一个非常有用的例子就是直方图均衡化。直方图均衡化是指将一幅
图像的灰度直方图变平,使变换后的图像中每个灰度值的分布概率都相同。在对图
像做进一步处理之前,直方图均衡化通常是对图像灰度值进行归一化的一个非常好
的方法,并且可以增强图像的对比度。
函数实现:
# 对一幅灰度图像进行直方图均衡化
def histeq(im,nbr_bins=256):
# 计算图像的直方图
imhist,bins = histogram(im.flatten(),nbr_bins,normed=True)
cdf = imhist.cumsum() # cumulative distribution function
cdf = 255 * cdf / cdf[-1] # 归一化
# 使用累积分布函数的线性插值,计算新的像素值
im2 = interp(im.flatten(),bins[:-1],cdf)
return im2.reshape(im.shape)
五. 图像平均:
图像平均操作是减少图像噪声的一种简单方式,通常用于艺术特效。我们可以简单
地从图像列表中计算出一幅平均图像。假设所有的图像具有相同的大小,我们可以
将这些图像简单地相加,然后除以图像的数目,来计算平均图像。
函数实现:
#计算图像列表的平均图像
def compute_average(img):
# 打开第一幅图像,将其存储在浮点型数组中
averageim = array(img[0], 'f')
for im in img:
averageim += array(im)
averageim /= len(img)
# 返回uint8 类型的平均图像
return array(averageim, 'uint8')
综合小案例:
#coding=utf-8
#
# NumPy小案例
#输出六张图,分别是
# 原图的灰度图,反相处理结果,像素求平方处理结果
# 原图缩放一倍,图片直方图均衡化,图像平均
# 对一幅灰度图像进行直方图均衡化
def histeq(im,nbr_bins=256):
# 计算图像的直方图
imhist,bins = histogram(im.flatten(),nbr_bins,normed=True)
cdf = imhist.cumsum() # cumulative distribution function
cdf = 255 * cdf / cdf[-1] # 归一化
# 使用累积分布函数的线性插值,计算新的像素值
im2 = interp(im.flatten(),bins[:-1],cdf)
return im2.reshape(im.shape)
#计算图像列表的平均图像
def compute_average(img):
# 打开第一幅图像,将其存储在浮点型数组中
averageim = array(img[0], 'f')
for im in img:
averageim += array(im)
averageim /= len(img)
# 返回uint8 类型的平均图像
return array(averageim, 'uint8')
from PIL import Image
from numpy import *
import pylab as plb
import matplotlib.pyplot as plt
#求平均的图片必须大小相同
img1 = array(Image.open('test1.jpg'))
img1.resize((300,300))
img2 = array(Image.open('test2.jpg'))
img2.resize((300,300))
img3 = array(Image.open('test3.jpg'))
img3.resize((300,300))
im = array(Image.open('test1.jpg').convert('L'),'f')
# 对图像进行反相处理
im2 = 255 - im
# 对图像像素值求平方后得到的图像
im4 = 255.0 * (im/255.0)**2
#im = Image.fromarray(im)
plb.gray()
plt.subplot(231)
plt.imshow(im) #显示灰度图
plt.subplot(232)
plt.imshow(im2) #显示反相图
plt.subplot(233)
plt.imshow(im4) #显示平方后的图像
plt.subplot(235)
img5 = Image.fromarray(histeq(im))
plt.imshow(img5) #显示均衡化的图像
plt.subplot(236)
img = (img1,img2,img3)
img6 = Image.fromarray(compute_average(img))
plt.imshow(img6) #显示求平均后的图像
im = Image.fromarray(im)
plt.subplot(234)
#resize()需要图片对象进行调用
#显示缩小的图片
plt.imshow(im.resize((im.size[0]/2,im.size[1]/2)))
plb.show()#暂停程序