【python】image库使用以及验证码识别

一、image库基础使用

#coding:utf-8

#典型应用:
>>> from PIL import Image
>>> im = Image.open('/Users/Ezy/Documents/Test/image/test.jpg')
>>> print im.format, im.size, im.mode
JPEG (440, 330) RGB
#size元组表示宽和高,mode表示RGB(true color image),此外还有,L(luminance),CMTK(pre-press image)
>>> im = im.convert('L')    #转为灰度模式
>>> im.show()
>>> pix = im.load()
>>> pix[0,1]
255


#新建一个空白的图片
>>> from PIL import Image
>>> im = Image.new('1', (100, 100), 'white')
#或者
>>> im = Image.new('1', (100, 100), 255)        #255表示白色,1表示黑色
>>> im.show()
>>> im = Image.new('L', (100, 100), 128)
>>> im.show()
>>> im = Image.new('RGBA', (100, 100), (12,34,23,1))
>>> im.show()               #将图片展现出来
"""
new方法可以创建图片对象,new参数说明:
第一个参数:指定模式:
L:灰度模式,每个像素的颜色使用 0-255 的整数表示。
1:表示单色模式
RGBA:三元色加透明度的表示方式,每个像素的颜色使用类似 (12,34,23,1) 的 tuple 表示。
第二个参数:指定图片大小
第三个参数:指定背景色
"""


#新建一个带文字的图片
from PIL import Image
from PIL import ImageDraw
>>> im = Image.new('1', (100, 100), 'white')
>>> draw = ImageDraw.Draw(im)
>>> draw.text((0, 0), 'hello world!')
#两个参数,第一个是字母开始的位置,第二个为输入的内容,可以新增第三个参数,font=FONT,来指定字体
>>> draw.text((wdraw, hdraw), msgNum, font=fron, fill=(255, 33, 33))
#定义图像格式
    #(wdraw, hdraw):坐标
    #msgNum: 随机数
    # font: 自定义字体及大小
    # fill:定义颜色,可以为数字格式也可以直接指定英文如:fill="red"
>>> im.show()


#图片处理
>>> im = Image.open('test.jpg')
>>> box = (100, 100, 200, 200)
>>> region = im.crop(box)               #将图片扣出来一块内容
>>> region.show()                       #展示抠出来的图片
>>> region = region.transpose(Image.ROTATE_180)     #将抠出来的图片旋转180度
>>> region.show()                       #展示旋转后的图片
>>> im.paste(region, box)               #将旋转后的图片放回原来的区域中
>>> im.show()                       #展示图片
#crop() : 从图像中提取出某个矩形大小的图像。它接收一个四元素的元组作为参数,各元素为(left, upper, right, lower),坐标系统的原点(0, 0)是左上角。


#图片的其他操作:
>>> out = im.resize((128, 128))                     #压缩原图片
>>> out = im.rotate(45)                             #逆时针旋转 45 度角。
>>> out = im.transpose(Image.FLIP_LEFT_RIGHT)       #左右对换。
>>> out = im.transpose(Image.FLIP_TOP_BOTTOM)       #上下对换。
>>> out = im.transpose(Image.ROTATE_90)             #旋转 90 度角。
>>> out = im.transpose(Image.ROTATE_180)            #旋转 180 度角。
>>> out = im.transpose(Image.ROTATE_270)            #旋转 270 度角。
>>> out.show()                                      #展示处理后的图片


#图像增强
>>> import ImageFilter
>>> imfilter = im.filter(ImageFilter.DETAIL)
>>> imfilter.show()


#取出某个图像中某个点的RGB值:
>>> im = Image.open('/Users/Ezy/Documents/Test/image/test.jpg')
>>> pix = im.load()
>>> print pix[1,2]
0
>>> print pix[1,3]
8


#更改某个图像中某个点的RGB值:
>>> from PIL import Image
>>> im = Image.open('/Users/Ezy/Documents/Test/image/test.jpg')
>>> im = im.convert('L')
>>> pix = im.load()
>>> pix[0,1]
23
>>> im.putpixel((0,1), 0)
>>> pix[0,1]
0
#注意,此时改变还只是对im对象的改变,要想生效就需要保存图片,如下所示
>>> im.save('/Users/Ezy/Documents/Test/image/test2.jpg')

补充图片几种色彩模式

  • 灰度(黑白)
  • RGB(三色)
  • CMYK(印刷色)
  • Lab(肉眼识别色)

二、验证码识别

首先需要安装Tesseract-OCR软件,参考:

Windows安装Tesseract-OCR 4.00并配置环境变量,下载一下安装包,安装一下然后配置下一环境变量

然后需要安装python库

pip install pytesseract
pip install pillow

然后就开始验证码识别啦,先来一个简单的验证码识别,没有干扰
在这里插入图片描述

import pytesseract
from PIL import Image

image = Image.open("./1.png")
code = pytesseract.image_to_string(image)
print(code)

效果如下
在这里插入图片描述

但是像这种有干扰的就不行了,识别不出来
在这里插入图片描述

我们需要进行去噪,代码如下

#coding:utf-8
#auther:Ezy
#statement:使用image函数来自定义去除干扰线


"""
选择验证码颜色
1、颜色数目太少
2、范围太大,61>x2-x1>9, y2-y1 <11
3、若干扰线也在范围内,选择像素点数目多的
"""


from PIL import Image
from pytesseract import *           #若要正常使用需要首先安装好tesseract-ocr,否则会报错
import requests



def scan(im, xx, yy):
    pix = im.load()
    dic = {}            #{23:{'count':1, 'left':0, 'right':0, 'up':1, 'down':1}, ……}
    for x in range(xx):
        for y in range(yy):
            if pix[x,y] in dic.keys():
                dic[pix[x,y]]['count'] = dic[pix[x,y]]['count'] + 1
                if x > dic[pix[x,y]]['right']:
                    dic[pix[x,y]]['right'] = x
                if x < dic[pix[x,y]]['left']:
                    dic[pix[x,y]]['left'] = x
                if y > dic[pix[x,y]]['up']:
                    dic[pix[x,y]]['up'] = y
                if y < dic[pix[x,y]]['down']:
                    dic[pix[x,y]]['down'] = y
            else:
                dic[pix[x,y]] = {'count':1, 'left':x, 'right':x, 'up':y, 'down':y}
    return dic



def geticode(dic):
    l = []
    for i in dic.keys():
        if 9 < abs(dic[i]['right']-dic[i]['left']) < 61 and abs(dic[i]['up']-dic[i]['down']) < 11:
            l.append(i)
    tmp = 0         #验证码颜色
    for i in l:
        # print(str(i) + '\t' + str(dic[i]))
        if dic[i]['count'] > tmp:
            tmp = i
    # print(str(tmp) + '\t' + str(dic[tmp]))
    return tmp



def clean(im, xx, yy, icode):
    pix = im.load()
    for x in range(xx):
        for y in range(yy):
            if pix[x,y] != icode:
                im.putpixel((x,y), 255)
    return im



def main(file):
    im = Image.open(file)
    im = im.convert('L')
    xx, yy = im.size
    icode = geticode(scan(im, xx, yy))
    im = clean(im, xx, yy, icode)
    # im.show()
    test = image_to_string(im)
    print(test)


if __name__ == "__main__":
    file = "./2.gif"
    main(file)

效果如下
在这里插入图片描述

具体步骤:
先将图片转换为灰度模式

im = im.convert('L')

转换后就像下面这种
在这里插入图片描述
然后遍历每个像素,把颜色相同的放在一起,并计算出这个颜色的范围

    for x in range(xx):
        for y in range(yy):
            if pix[x, y] in dic.keys():
                dic[pix[x, y]]['count'] = dic[pix[x, y]]['count'] + 1
                if x > dic[pix[x, y]]['right']:
                    dic[pix[x, y]]['right'] = x
                if x < dic[pix[x, y]]['left']:
                    dic[pix[x, y]]['left'] = x
                if y > dic[pix[x, y]]['up']:
                    dic[pix[x, y]]['up'] = y
                if y < dic[pix[x, y]]['down']:
                    dic[pix[x, y]]['down'] = y
            else:
                dic[pix[x, y]] = {'count': 1, 'left': x, 'right': x, 'up': y, 'down': y}

运行出来就类似于这种

在这里插入图片描述
比如,第一个86,这个颜色的像素范围在x轴上为0到9,y轴范围为1到35,而我们图片的范围为x轴91个像素,y轴36个像素

目测一下验证码左右像素为20到85,上下像素为0到12,那么第一个肯定不满足

    for i in dic.keys():
        if 20 < abs(dic[i]['right'] - dic[i]['left']) < 85 and 1< abs(dic[i]['up'] - dic[i]['down']) < 12:
            l.append(i)
            print(dic[i])

我们把满足值的颜色提取出来,然后像素数量最多的多半就是验证码的颜色了

    for i in l:
        # print(str(i) + '\t' + str(dic[i]))
        if dic[i]['count'] > tmp:
            tmp = i

遍历所有像素,不是验证码颜色的直接改成白色

def clean(im, xx, yy, icode):
    pix = im.load()
    for x in range(xx):
        for y in range(yy):
            if pix[x, y] != icode:
                im.putpixel((x, y), 255)
    return im

最后去噪效果如下:
在这里插入图片描述

再用pytesseract.image_to_string识别一下即可

    test = image_to_string(im)
    print(test)

成功识别!
在这里插入图片描述

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值