zoukankan      html  css  js  c++  java
  • 潭州课堂25班:Ph201805201 爬虫基础 第九课 图像处理- PIL (课堂笔记)

    Python图像处理-Pillow

    简介

    Python传统的图像处理库PIL(Python Imaging Library ),可以说基本上是Python处理图像的标准库,功能强大,使用简单。

    但是由于PIL不支持Python3,而且更新缓慢。所以有志愿者在PIL的基础上创建了一个分支版本,命名为PillowPillow目前最新支持到python3.6,更新活跃,并且增添了许多新的特性。所以我们安装Pillow即可。

    安装

    Pillow的安装比较的简单,直接pip安装即可:

    pip install Pillow
    

    但是要注意的一点是,PillowPIL不能共存在同一个环境中,所以如果安装的有PIL的话,那么安装Pillow之前应该删除PIL

    由于是继承自PIL的分支,所以Pillow的导入是这样的:

    import PIL 
    # 或者
    from PIl import Image
    

    使用手册

    Image

    Image是Pillow中最为重要的类,实现了Pillow中大部分的功能。要创建这个类的实例主要有三个方式:

    1. 从文件加载图像

    2. 处理其他图像获得

    3. 创建一个新的图像

    读取图像

    一般来说,我们都是都过从文件加载图像来实例化这个类,如下所示:

    from PIL import Image
    picture = Image.open('happy.png')
    

    如果没有指定图片格式的话,那么Pillow会自动识别文件内容为文件格式。

    新建图像

    Pillow新建空白图像使用new()方法, 第一个参数是mode即颜色空间模式,第二个参数指定了图像的分辨率(宽x高),第三个参数是颜色。

    • 可以直接填入常用颜色的名称。如'red'。

    • 也可以填入十六进制表示的颜色,如#FF0000表示红色。

    • 还能传入元组,比如(255, 0, 0, 255)或者(255, 0, 0)表示红色。

    picture = Image.new('RGB', (200, 100), 'red')
    

    保存图像

    保存图片的话需要使用save()方法:

    picture.save('happy.png')
    

    保存的时候,如果没有指定图片格式的话,那么Pillow会根据输入的后缀名决定保存的文件格式。

    图像的坐标表示

    在Pillow中,用的是图像的左上角为坐标的原点(0,0),所以这意味着,x轴的数值是从左到右增长的,y轴的数值是从上到下增长的。

    我们处理图像时,常常需要去表示一个矩形的图像区域。Pillow中很多方法都需要传入一个表示矩形区域的元祖参数。

    这个元组参数包含四个值,分别代表矩形四条边的距离X轴或者Y轴的距离。顺序是(左,顶,右,底)。其实就相当于,矩形的左上顶点坐标为(左,顶),矩形的右下顶点坐标为(右,底),两个顶点就可以确定一个矩形的位置。

    右和底坐标稍微特殊,跟python列表索引规则一样,是左闭又开的。可以理解为[左, 右)[顶, 底)这样左闭右开的区间。比如(3, 2, 8, 9)就表示了横坐标范围[3, 7];纵坐标范围[2, 8]的矩形区域。

    常用属性

    • PIL.Image.filename

      图像源文件的文件名或者路径,只有使用open()方法创建的对象有这个属性。

      类型:字符串

    • PIL.Image.format

      图像源文件的文件格式。

    • PIL.Image.mode

      图像的模式,一般来说是“1”, “L”, “RGB”, 或者“CMYK” 。

    • PIL.Image.size

      图像的大小

    • PIL.Image.width

      图像的宽度

    • PIL.Image.height

      图像的高度

    • PIL.Image.info

      图像的一些信息,为字典格式

    常用方法

    裁剪图片

    Image使用crop()方法来裁剪图像,此方法需要传入一个矩形元祖参数,返回一个新的Image对象,对原图没有影响。

    croped_im = im.crop((100, 100, 200, 200))
    

    复制与粘贴图像

    复制图像使用copy()方法:

    copyed_im = im.copy()
    

    粘贴图像使用paste()方法:

    croped_im = im.crop((100, 100, 200, 200))
    im.paste(croped_im, (0, 0))
    

    im对象调用了paste()方法,第一个参数是被裁剪下来用来粘贴的图像,第二个参数是一个位置参数元祖,这个位置参数是粘贴的图像的左顶点。

    调整图像的大小

    调整图像大小使用resize()方法:

    resized_im = im.resize((width, height))
    

    resize()方法会返回一个重设了大小的Image对象。

    旋转图像和翻转图像

    旋转图像使用rotate()方法,此方法按逆时针旋转,并返回一个新的Image对象:

    # 逆时针旋转90度
    im.rotate(90)
    im.rotate(180)
    im.rotate(20, expand=True)
    

    旋转的时候,会将图片超出边界的边角裁剪掉。如果加入expand=True参数,就可以将图片边角保存住。

    翻转图像使用transpose()

    # 水平翻转
    im.transpose(Image.FLIP_LEFT_RIGHT)
    # 垂直翻转
    im.transpose(Image.FLIP_TOP_BOTTOM)
    

    获取单个像素的值

    使用getpixel(xy)方法可以获取单个像素位置的值:

    im.getpixel((100, 100))
    

    传入的xy需要是一个元祖形式的坐标。

    如果图片是多通道的,那么返回的是一个元祖。

    通过通道分割图片

    split()

    split()可以将多通道图片按通道分割为单通道图片:

    R, G, B = im.split()
    

    split()方法返回的是一个元祖,元祖中的元素则是分割后的单个通道的值。

    getchannel(channel)

    getchannel()可以获取单个通道的数据:

    R = im.getchannel("R")
    

    加载图片全部数据

    我们可以使用load()方法加载图片所有的数据,并比较方便的修改像素的值:

    pixdata = im.load()
    pixdata[100,200] = 255
    

    此方法返回的是一个PIL.PyAccess,可以通过这个类的索引来对指定坐标的像素点进行修改。

    关闭图片并释放内存

    此方法会删除图片对象并释放内存

    im.close()






    把图片转为高对比度的图片
    # -*- coding:utf-8 -*-
    # 斌彬电脑
    # @Time :   2018/9/11 0011    下午 2:50
    
    from PIL import Image
    im = Image.open('ss.png')
    im = im.convert('L')            #  灰度图片
    data = im.load()
    h,w = im.size                   #  读出图片大小,
    #  不是黑的就是白的,
    for i in range(h):
        for j in range(w):
            if  data[i,j] > 128:        #  根据坐标读出像素的值
                data[i,j] = 255
            else: data[i,j] = 0
    
    #  得到一个高对比度的图片
    im.show()
    

      

    验证码简单处理

    # -*- coding: utf-8 -*-
    # 斌彬电脑
    # @Time : 2018/9/12 0012 5:34
    
    from PIL import Image
    
    im = Image.open('aaaaaaa.png')
    im = im.convert('L')  # 灰度图片
    data = im.load()
    h, w = im.size  # 读出图片大小,
    #  不是黑的就是白的,
    for i in range(h):
        for j in range(w):
            if data[i, j] > 20:  # 根据坐标读出像素的值
                data[i, j] = 255
            else:
                data[i, j] = 0
    
    # 降嗓
    for x in range(1,h - 1):
        for y in range(1,w - 1):
            count = 0
            if data[x - 1, y - 1] == 255:
                count += 1
            if data[x + 1, y + 1] == 255:
                count += 1
            if data[x - 1, y - 1] == 255:
                count += 1
            if data[x + 1, y + 1] == 255:
                count += 1
    
            # if data[x, y - 1] == 255:
            #     count += 1
            # if data[x, y + 1] == 255:
            #     count += 1
            # if data[x - 1, y] == 255:
            #     count += 1
            # if data[x + 1, y] == 255:
            #     count += 1
    
            if count > 2:
                data[x, y] = 255
    
    
    im.save('123.png')
    #  得到一个高对比度的图片
    im.show()
    

      

     


    非黑即白的后处理
    # -*- coding:utf-8 -*-
    # 斌彬电脑
    # @Time :   2018/9/12 0012    上午 8:37
    
    from PIL import Image
    import json, re
    
    im = Image.open('aaaaaaa.png')
    im = im.convert('L')  # 灰度图片
    data = im.load()
    h, w = im.size  # 读出图片大小,
    #  不是黑的就是白的,
    for i in range(h):
        for j in range(w):
            if data[i, j] > 20:  # 根据坐标读出像素的值
                data[i, j] = 255
            else:
                data[i, j] = 0
    
    # 降嗓
    for x in range(1,h - 1):
        for y in range(1,w - 1):
            count = 0
            if data[x - 1, y - 1] == 255:
                count += 1
            if data[x + 1, y + 1] == 255:
                count += 1
            if data[x - 1, y - 1] == 255:
                count += 1
            if data[x + 1, y + 1] == 255:
                count += 1
    
            if count > 2:
                data[x, y] = 255
    
    itm = {}
    file = open('itm.json', 'a', encoding='utf8')
    for x in range(1,h - 1):
        itm = {}
        y = 1
        file.write('
    ')
        while (w-y)!=0:
            if  data[x, y] == 0:
                itm[x] = y
                item1 = json.dumps(itm, ensure_ascii=False )
                file.write(item1)
            y += 1
    
    
    
    
    bb=''
    with open("itm.json", "r") as f:
        for i in f:
            if  len(i.strip()) < 50:
                # print(i.strip())
                bb = bb+i.strip()
    # print(bb)
    
    a,b = re.findall(r"{'(.*?)':(.*?)}", bb)
    print(a,b)
    
    
    # im.save('123.png')
    #  得到一个高对比度的图
    # im.show()
    

     

    验证码黑白处理

    # -*- coding:utf-8 -*-
    # 斌彬电脑
    # @Time :   2018/9/12 0012    上午 8:37
    
    from PIL import Image
    import json, re
    
    im = Image.open('9.png')
    im = im.convert('L')  # 灰度图片
    data = im.load()
    h, w = im.size  # 读出图片大小,
    #  不是黑的就是白的,
    for i in range(h):
        for j in range(w):
            if data[i, j] > 50:  # 根据坐标读出像素的值
                data[i, j] = 255
            else:
                data[i, j] = 0
    
    # 降嗓
    for x in range(1, h - 1):
        for y in range(1, w - 1):
            count = 0
            if data[x - 1, y - 1] == 255:
                count += 1
            if data[x + 1, y + 1] == 255:
                count += 1
            if data[x - 1, y - 1] == 255:
                count += 1
            if data[x + 1, y + 1] == 255:
                count += 1
    
            if count > 2:
                data[x, y] = 255
    
    
    
    itm = {}
    file1 = open('itm.json', 'a', encoding='utf8')
    for x in range(1, h - 1):
        itm = {}
        y = 1
        file1.write('
    ')
        while (w - y) != 0:
            if data[x, y] == 0:
                itm[x] = y
                item1 = json.dumps(itm, ensure_ascii=False)
                file1.write(item1)
            y += 1
    file1.close()
    
    bb = ''
    with open("itm.json", "r") as f:
        for i in f:
            if len(i.strip()) < 30:         #  杂点大小
                # print(i.strip())
                bb = bb + i.strip()
    # print(bb)
    # {"4": 40}
    a = re.findall(r'{"(.*?)":.*?}', bb)
    b = re.findall(r'{".*?":(.*?)}', bb)
    # print(a)
    # print(b)
    print(len(a),len(b))
    for i in range(len(a)):
        data[int(a[i]), int(b[i])] = 255
    
    
    # im2 = im
    # data2 = im.load()
    # h2, w2 = im2.size  # 读出图片大小,
    # # print(h2,w2,'00000')
    #
    # atm = {}
    # file2 = open('atm.json', 'a', encoding='utf8')
    # for n in range(1, w2 - 1):
    #     atm = {}
    #     m = 1
    #     file2.write('
    ')
    #     while (h2 - m) != 0:
    #         if data2[n, m] == 0:
    #             atm[n] = m
    #             stem1 = json.dumps(atm, ensure_ascii=False)
    #             file2.write(stem1)
    #         n += 1
    # file2.close()
    #
    # cc = ''
    # with open("atm.json", "r") as f:
    #     for i in f:
    #         if len(i.strip()) < 30:  # 杂点大小
    #             # print(i.strip())
    #             cc = cc + i.strip()
    # # print(bb)
    # # {"4": 40}
    # c = re.findall(r'{"(.*?)":.*?}', cc)
    # d = re.findall(r'{".*?":(.*?)}', cc)
    # # print(c)
    # # print(d)
    # print(len(c), len(d))
    # for i in range(len(c)):
    #     data2[int(c[i]), int(d[i])] = 255
    
    # im.save('123.png')
    #  得到一个高对比度的图
    # im2 = im2.rotate(270)
    im.show()
    

      

     
  • 相关阅读:
    [Objective-c 基础
    [Objective-c 基础
    [Objective-c 基础
    [Objective-c 基础
    [Objective-c 基础
    [Objective-c 基础
    [Objective-c 基础
    [Objective-c 基础
    [Objective-c 基础
    39. Combination Sum(dfs)
  • 原文地址:https://www.cnblogs.com/gdwz922/p/9602382.html
Copyright © 2011-2022 走看看