Python中的图像处理

PIL:Python图像处理类库

  • 读取、灰度、保存:
from PIL import Image
# 打开一个图像,注意是当前路径:
im = Image.open('1.png')
# 灰度化处理
im = Image.open('1.png').convert('L')
# 保存灰度图像:
im.save('2.png')

我们导入Image模块,在python模块学习中我们会知道,这样做会得到名Image的对象,这个模块对象包含了im这样的常量,以及一些其它的方法。我们如果直接访问 im,不加Image这个前缀会发生什么情况呢?

程序抛出了一个名为“NameError”的错误。这个时候我们可以用from这个方法来实现可以直接用im这个方法。from会把变量名复制到另一个作用域,所以它就可以直接在脚本中使用复制后的变量名,而不用通过模块。

  • 批量图片格式转换
from PIL import Image
import os

def get_imlist(path):#获取文件名列表
    return [os.path.join(path,f) for f in os.listdir(path) if f.endswith('.png')]#读取png

filelist=get_imlist('C:/Users/Huawei/Desktop/EXP2/image')#建立一个列表对象
#print(filelist)
for infile in filelist:
  outfile = os.path.splitext(infile)[0] + ".jpg"#保存为jpg
  if infile != outfile:
    try:
      Image.open(infile).save(outfile)
    except IOError:
      print("cannot convert", infile)

注意文件路径的分隔符是/

只有字符串是双引号,文件名和文件路径都是单引号

  • 创建缩略图
from PIL import Image
# 打开一个当前路径的图像:
im = Image.open('1.png')
im.thumbnail((128,128))
# 保存缩略图:
im.save('3.png')
  • 复制粘贴
from PIL import Image
# 打开一个当前路径的图像:
im = Image.open('1.png')
# 裁剪
box = (100,100,400,400)
region = im.crop(box)
# 旋转180度
region = region.transpose(Image.ROTATE_180)
# 粘贴
im.paste(region,box)
# 保存:
im.save('4.png')
  • 调整尺寸及旋转
from PIL import Image
# 打开一个当前路径的图像:
im = Image.open('1.png')
# 调整尺寸
im = im.resize((128,128))
# 旋转
im = im.rotate(45)
# 保存:
im.save('5.png')

Matplotlib

绘制图像、点和线

from PIL import Image
from pylab import *

im = Image.open('1.png')
 
# 绘制图像
imshow(im)#没有imshow(),show()将无法显示原图
axis('off')#不显示坐标轴
 
# x是横坐标,y是纵坐标:(100,200)(100,500)...
x = [100,100,400,400]
y = [200,500,600,800]
 
#绘制点或线
plot(x,y)         # 默认为蓝色实线
plot(x,y,'r*')    # 红色星状标记
plot(x,y,'go-')   # 带有圆圈标记的绿线
plot(x,y,'ks:')   # 带有正方形标记的黑色虚线

 
# 绘制连接前两个点的线
plot(x[:2],y[:2])#what?
 
# 添加标题
title('Plotting: "1.png"')
# 原图及绘制的点、线输出到屏幕
show()

表1-1:用PyLab库绘图的基本颜色格式命令

颜色

'b'

蓝色

'g'

绿色

'r'

红色

'c'

青色

'm'

品红

'y'

黄色

'k'

黑色

'w'

白色

表1-2:用PyLab库绘图的基本线型格式命令

线型

'-'

实线

'--'

虚线

':'

点线

表1-3:用PyLab库绘图的基本绘制标记格式命令

标记

'.'

'o'

圆圈

's'

正方形

'*'

星形

'+'

加号

'x'

叉号

图像轮廓和直方图

from PIL import Image
from pylab import *
 
# 读取图像到数组中,一定要读进数组,array(),否则无法绘制直方图(flatten)
im = array(Image.open('1.png').convert('L'))
 
# 新建一个图像
figure()

# 不使用颜色信息,灰度化
gray()

# 在原点的左上角显示轮廓图像
contour(im, origin='image')

# 坐标
axis('equal')
axis('off')

# 新建一个图像
figure()
# 图像的直方图可以使用 hist() 函数绘制
hist(im.flatten(),128)
show()

hist() 只接受一维数组作为输入,所以我们在绘制图像直方图之前,必须先对图像进行压平处理。

flatten() 方法将任意数组按照行优先准则转换成一维数组。

 交互式标注

from PIL import Image
from pylab import *
 
im = Image.open('1.png')
#显示图片到屏幕
imshow(im)
print('Please click 3 points')
x = ginput(3)
print('you clicked:',x) 
show()#这个show()貌似没有用

图像数组表示

当载入图像时,我们通过调用 array() 方法将图像转换成 NumPy 的数组对象

from PIL import Image
from pylab import *

im = array(Image.open('1.png'))
print (im.shape, im.dtype)
 
im = array(Image.open('1.png').convert('L'),'f')
print (im.shape, im.dtype)

每行的第一个元组表示图像数组的大小(行、列、颜色通道),紧接着的字符串表示数组元素的数据类型。因为图像通常被编码成无符号八位整数(uint8),所以在第一种情况下,载入图像并将其转换到数组中,数组的数据类型为“uint8”。在第二种情况下,对图像进行灰度化处理,并且在创建数组时使用额外的参数“f”;该参数将数据类型转换为浮点型。

多个数组元素可以使用数组切片方式访问。切片方式返回的是以指定间隔下标访问该数组的元素值。下面是有关灰度图像的一些例子:

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]) # 倒数第二行

灰度变换

将图像读入 NumPy 数组对象后,我们可以对它们执行任意数学操作。

from PIL import Image
from pylab import *#imshow()show()
from numpy import *
 
im = array(Image.open('1.png').convert('L'))
 
im2 = 255 - im # 对图像进行反相处理
 
im3 = (100.0/255) * im + 100 # 将图像像素值变换到100...200 区间
 
im4 = 255.0 * (im/255.0)**2 # 对图像像素值求平方后得到的图像

imshow(im)
show()
imshow(im2)
show()
imshow(im3)
show()
imshow(im4)
show()

print (int(im.min()), int(im.max()))查看最小/最大 灰度值

直方图均衡化

from PIL import Image
from pylab import *

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), cdf


im = array(Image.open('1.png').convert('L'))  # 打开图像,并转成灰度图像
im2, cdf = histeq(im)
 
figure()
subplot(2, 2, 1)
axis('off')
gray()
title(u'Origin')
imshow(im)
 
subplot(2, 2, 2)
axis('off')
title(u'Processed')
imshow(im2)
 
subplot(2, 2, 3)
axis('off')
title(u'Origin Graph')
hist(im.flatten(), 128, normed=True)
 
subplot(2, 2, 4)
axis('off')
title(u'Processed Graph')
hist(im2.flatten(), 128, normed=True)
 
show()

# 添加中文字体支持
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)

title(u'原始图像', fontproperties=font)

图像平均

from PIL import Image
from pylab import *#imshow()show()
from numpy import *
import os


def get_imlist(path):#获取文件名列表
    return [os.path.join(path,f) for f in os.listdir(path) if f.endswith('.png')]#读取png

def compute_average(imlist):
  """ 计算图像列表的平均图像"""
 
  # 打开第一幅图像,将其存储在浮点型数组中
  averageim = array(Image.open(imlist[0]), 'f')
 
  for imname in imlist[1:]:
    try:
      averageim += array(Image.open(imname))
    except:
      print (imname + '...skipped')
  averageim /= len(imlist)
 
  # 返回uint8 类型的平均图像
  return array(averageim, 'uint8')

filelist = get_imlist('C:/Users/Huawei/Desktop/EXP2/image')
avg = compute_average(filelist)

for impath in filelist:
        im1 = array(Image.open(impath))
        subplot(2, 2, filelist.index(impath)+1)
        imshow(im1)
        imNum=str(filelist.index(impath)+1)
        title(u'Origin'+imNum)
        axis('off')
subplot(2, 2, 4)
imshow(avg)
title(u'Processed')
axis('off')
 
show()

有Warning未解决

发布了115 篇原创文章 · 获赞 9 · 访问量 8118

猜你喜欢

转载自blog.csdn.net/weixin_43673589/article/details/104722225
今日推荐