zoukankan      html  css  js  c++  java
  • Python操作图像

    安装Pillow

    pip install Pillow

    打开图像

    from PIL import Image
    img = Image.open("./lena.tiff")

    保存图像

    打开图像之后,可以将其保存,也就是另存为。
    img对象.save(保存路径)

    save方法不仅能够保存图像,还能够转换格式,取决于保存路径的最终文件后缀名。

    img.save("./lena.jpg")
    img.save("./lena.png")

    查看属性

    img = Image.open("./lena.tiff")
    print('图像格式:{}'.format(img.format))
    print('图像尺寸:{}'.format(img.size))
    print('色彩模式:{}'.format(img.mode))

    打印结果:

    图像格式:TIFF
    图像尺寸:(512, 512)
    色彩模式:RGB

    显示图像

    from PIL import Image
    import matplotlib.pyplot as plt
    img = Image.open("./lena.tiff")
    plt.imshow(img)
    plt.show()

    运行结果:

    这是在数字图像处理中 被广泛用来做示例的一张图像  Lena

    imshow函数是对图像进行载入,传入的参数可以是img对象,也可以是Numpy数组,最后由show函数负责将载入的图片进行显示。

    默认是会带上像素坐标轴的,如果不显示坐标轴,可以在plt.show()之前加一句plt.axis("off"),以下会演示效果。

    我们还可以同时显示多张图像,

    from PIL import Image
    import matplotlib.pyplot as plt
    
    #打开三张图片
    img1 = Image.open('./lena.tiff')
    img2 = Image.open('./lena.png')
    img3 = Image.open('./lena.jpg')
    
    #设置画布尺寸
    plt.figure(figsize=(10,5))
    
    plt.subplot(131) #划分子图 本张为1行3列的第一张图
    plt.title(img1.format)  #图片标题
    plt.axis('off') #关闭坐标轴
    plt.imshow(img1) #载入图片
    
    plt.subplot(132)
    plt.title(img2.format)
    plt.axis('off')
    plt.imshow(img2)
    
    plt.subplot(133)
    plt.title(img3.format)
    plt.axis('off')
    plt.imshow(img3)
    
    plt.show() #显示图片

    运行结果:

    色彩模式

    我们可以使用img对象的convert方法将图像转换色彩模式

    img对象.convert(色彩模式)

    色彩模式的取值有如下几种:

    1:二值图像
    L:灰度图像
    P:8位彩色图像
    RGB:24位彩色图像
    RGBA:32位彩色图像
    CMYK:CMYK彩色图像
    YCbCr:YCbCr彩色图像
    I:32位整型灰度图像
    F:32位浮点灰度图像

    用法示例:

    from PIL import Image
    import matplotlib.pyplot as plt
    
    img1 = Image.open('./lena.tiff')
    img_gray = img1.convert("L")
    plt.figure(figsize=(10,10))
    plt.imshow(img_gray,cmap='gray')
    plt.show()

    转成灰度图之后  就是这样子:

    颜色通道

    用img对象的split()方法将图像按照RGB三个通道分离成三个图像。

    也可以用Image库的merge函数将多个通道合并成一个图像。

    from PIL import Image
    import matplotlib.pyplot as plt
    
    plt.rcParams['font.sans-serif']=['SimHei']
    
    img = Image.open('./lena.tiff')
    img_r,img_g,img_b = img.split()
    plt.figure(figsize=(10,10))
    
    plt.subplot(221)
    plt.title('R通道',fontsize=18)
    plt.axis('off')
    plt.imshow(img_r,cmap='gray')
    
    plt.subplot(222)
    plt.title('G通道',fontsize=18)
    plt.axis('off')
    plt.imshow(img_g,cmap='gray')
    
    plt.subplot(223)
    plt.title('B通道',fontsize=18)
    plt.axis('off')
    plt.imshow(img_b,cmap='gray')
    
    img_rgb = Image.merge('RGB',[img_r,img_g,img_b])
    plt.subplot(224)
    plt.title('合并通道',fontsize=18)
    plt.axis('off')
    plt.imshow(img_rgb)
    
    plt.show()

    运行结果:

    按灰度图显示对应通道,比如第一张图中,颜色越亮,表示红色越多,颜色越暗,表示红色越少。

    图像转数组

    在人工智能处理图像的时候,都是先将图像转成数组,数组中的元素对应图像中的各个像素点。

    将图像转为数组需要用到numpy的array函数。

    from PIL import Image
    import numpy as ny
    img = Image.open('./lena.tiff')
    arr = ny.array(img)
    print('形状:{}'.format(arr.shape))
    print(arr)

    打印结果(数组很长,默认中间以省略号代替):

    形状:(512, 512, 3)
    [[[226 137 125]
    [226 137 125]
    [223 137 133]
    ...
    [230 148 122]
    [221 130 110]
    [200 99 90]]

    [[226 137 125]
    [226 137 125]
    [223 137 133]
    ...
    [230 148 122]
    [221 130 110]
    [200 99 90]]]

    图像数组是一个三维数组,前两维对应图像的尺寸,第三维对应图像的三个通道,也就是说前两维是一个512行乘以512列的矩阵,因为整张图像大小就是512像素*512像素,第三维是每个像素点的RGB三个通道的颜色值。 

    接下来我们看一下将一张灰度图转为数组是什么样子的,使用上文转换色彩模式时保存下来的灰度图:

    from PIL import Image
    import numpy as ny
    img = Image.open('./003.jpg')
    arr = ny.array(img)
    print('形状:{}'.format(arr.shape))
    print(arr)

    打印结果:

    形状:(512, 512)
    [[162 161 160 ... 171 154 129]
    [162 162 161 ... 173 158 133]
    [163 162 161 ... 171 155 128]
    ...
    [ 42 45 49 ... 102 103 103]
    [ 41 45 50 ... 105 107 109]
    [ 41 45 51 ... 102 105 107]]

    此时的形状是一个512*512的二维数组,其中每个元素对应一个像素点的灰度值。

    那我们可以将这张灰度图做一个反色处理,将每个像素的颜色值都用255来减一下,也就是黑色变成白色,白色变成黑色。

    import matplotlib.pyplot as plt
    from PIL import Image
    import numpy as ny
    img = Image.open('./003.jpg')
    arr = ny.array(img)
    
    plt.figure(figsize=(10,5))
    
    plt.subplot(121)
    plt.title('old')
    plt.imshow(arr,cmap='gray')
    plt.axis('off')
    
    new_arr = 255 - arr
    plt.subplot(122)
    plt.title('new')
    plt.imshow(new_arr,cmap='gray')
    plt.axis('off')
    
    plt.show()

    运行结果:

    图像缩放

    使用img对象的resize方法可以对图像进行缩放

    import matplotlib.pyplot as plt
    from PIL import Image
    
    img = Image.open('./lena.tiff')
    
    plt.figure(figsize=(10,5))
    
    plt.subplot(121)
    plt.title('old')
    plt.imshow(img)
    
    new_img = img.resize((64,64))
    plt.subplot(122)
    plt.title('new')
    plt.imshow(new_img)
    
    plt.show()

    运行结果:

    通过坐标轴可以看到 原图是512*512尺寸大小,进行缩放成64*64之后,图像的质量下降,出现了类似马赛克的效果,这个操作是一个降采样的过程。

    缩放还可以使用img的thumbnail方法,但不同的是thumbnail方法是对图像的原地操作,不会有返回值,使用示例:

    import matplotlib.pyplot as plt
    from PIL import Image
    
    img = Image.open('./lena.tiff')
    
    plt.figure(figsize=(10,5))
    
    plt.subplot(121)
    plt.title('old')
    plt.imshow(img)
    
    img.thumbnail((64,64))
    plt.subplot(122)
    plt.title('new')
    plt.imshow(img)
    
    plt.show()

    运行结果和之前一模一样。

    图像旋转

    img对象.transpose()方法对图像进行旋转。

    参数中指定旋转方式,有如下几种:

    Image.FLIP_LEFT_RIGHT = 0 水平翻转
    Image.FLIP_TOP_BOTTOM = 1 上下翻转
    Image.ROTATE_90 = 2 逆时针旋转90度
    Image.ROTATE_180 = 3 逆时针旋转180度
    Image.ROTATE_270 = 4 逆时针旋转270度
    Image.TRANSPOSE = 5 将图像转置
    Image.TRANSVERSE = 6 将图像进行转置,再水平翻转

    可以传常量属性,也可以直接传数字,源码中常量是直接映射成数字处理的。

    import matplotlib.pyplot as plt
    from PIL import Image
    
    img = Image.open('./lena.tiff')
    
    plt.rcParams['font.sans-serif']=['SimHei']
    
    plt.figure(figsize=(10,20))
    
    plt.subplot(421)
    plt.axis('off')
    plt.title('原图',fontsize=18)
    plt.imshow(img)
    
    img2 = img.transpose(Image.FLIP_LEFT_RIGHT)
    plt.subplot(422)
    plt.axis('off')
    plt.title('水平翻转',fontsize=18)
    plt.imshow(img2)
    
    img3 = img.transpose(Image.FLIP_TOP_BOTTOM)
    plt.subplot(423)
    plt.axis('off')
    plt.title('上下翻转',fontsize=18)
    plt.imshow(img3)
    
    img4 = img.transpose(Image.ROTATE_90)
    plt.subplot(424)
    plt.axis('off')
    plt.title('逆时针旋转90度',fontsize=18)
    plt.imshow(img4)
    
    img5 = img.transpose(Image.ROTATE_180)
    plt.subplot(425)
    plt.axis('off')
    plt.title('逆时针旋转180度',fontsize=18)
    plt.imshow(img5)
    
    img6 = img.transpose(Image.ROTATE_270)
    plt.subplot(426)
    plt.axis('off')
    plt.title('逆时针旋转270度',fontsize=18)
    plt.imshow(img6)
    
    img7 = img.transpose(Image.TRANSPOSE)
    plt.subplot(427)
    plt.axis('off')
    plt.title('将图像转置',fontsize=18)
    plt.imshow(img7)
    
    img8 = img.transpose(Image.TRANSVERSE)
    plt.subplot(428)
    plt.axis('off')
    plt.title('转置+翻转',fontsize=18)
    plt.imshow(img8)
    
    plt.show()

    运行结果:

    图像裁剪

    img对象.crop((x0,y0,x1,y1))

    参数中的x0,y0代表裁剪内容的左上角坐标,x1,y1代表裁剪内容的右下角坐标,两个坐标即可确定出裁剪的矩形区域。

    import matplotlib.pyplot as plt
    from PIL import Image
    
    img = Image.open('./lena.tiff')
    
    plt.rcParams['font.sans-serif']=['SimHei']
    
    plt.figure(figsize=(10,5))
    
    plt.subplot(121)
    plt.axis('off')
    plt.title('原图',fontsize=18)
    plt.imshow(img)
    
    area = (200,200,400,400)
    img2 = img.crop(area)
    plt.subplot(122)
    plt.axis('off')
    plt.title('裁剪结果',fontsize=18)
    plt.imshow(img2)
    
    plt.show()

    运行结果:

  • 相关阅读:
    Eclipse 远程调试
    大数据处理方法bloom filter
    sicily 1259 Sum of Consecutive Primes
    sicily 1240. Faulty Odometer
    sicily 1152 简单马周游 深度优先搜索及回溯算法
    sicily 1050 深度优先搜索解题
    sicily 1024 邻接矩阵与深度优先搜索解题
    sicily 1156 二叉树的遍历 前序遍历,递归,集合操作
    sicily 1443 队列基本操作
    sicily 1006 team rankings 枚举解题
  • 原文地址:https://www.cnblogs.com/fengyumeng/p/13803223.html
Copyright © 2011-2022 走看看