资讯专栏INFORMATION COLUMN

Python图像处理之图片验证码识别

kk_miles / 1009人阅读

摘要:在上一篇博客图像处理之图片文字识别中我们介绍了在中如何利用软件来识别图片中的英文与中文,本文将具体介绍如何在中利用软件来识别验证码数字加字母。

  在上一篇博客Python图像处理之图片文字识别(OCR)中我们介绍了在Python中如何利用Tesseract软件来识别图片中的英文与中文,本文将具体介绍如何在Python中利用Tesseract软件来识别验证码(数字加字母)。
  我们在网上浏览网页或注册账号时,会经常遇到验证码(CAPTCHA),如下图:

本文将具体介绍如何利用Python的图像处理模块pillow和OCR模块pytesseract来识别上述验证码(数字加字母)。
  我们识别上述验证码的算法过程如下:

将原图像进行灰度处理,转化为灰度图像;

获取图片中像素点数量最多的像素(此为图片背景),将该像素作为阈值进行二值化处理,将灰度图像转化为黑白图像(用来提高识别的准确率);

去掉黑白图像中的噪声,噪声定义为:以该点为中心的九宫格的黑点的数量小于等于4;

利用pytesseract模块识别,去掉识别结果中的特殊字符,获得识别结果。

  我们的图片如下(共66张图片):

  完整的Python代码如下:

import os
import pytesseract
from PIL import Image
from collections import defaultdict

# tesseract.exe所在的文件路径
pytesseract.pytesseract.tesseract_cmd = "C://Program Files (x86)/Tesseract-OCR/tesseract.exe"

# 获取图片中像素点数量最多的像素
def get_threshold(image):
    pixel_dict = defaultdict(int)

    # 像素及该像素出现次数的字典
    rows, cols = image.size
    for i in range(rows):
        for j in range(cols):
            pixel = image.getpixel((i, j))
            pixel_dict[pixel] += 1

    count_max = max(pixel_dict.values()) # 获取像素出现出多的次数
    pixel_dict_reverse = {v:k for k,v in pixel_dict.items()}
    threshold = pixel_dict_reverse[count_max] # 获取出现次数最多的像素点

    return threshold

# 按照阈值进行二值化处理
# threshold: 像素阈值
def get_bin_table(threshold):
    # 获取灰度转二值的映射table
    table = []
    for i in range(256):
        rate = 0.1 # 在threshold的适当范围内进行处理
        if threshold*(1-rate)<= i <= threshold*(1+rate):
            table.append(1)
        else:
            table.append(0)
    return table

# 去掉二值化处理后的图片中的噪声点
def cut_noise(image):

    rows, cols = image.size # 图片的宽度和高度
    change_pos = [] # 记录噪声点位置

    # 遍历图片中的每个点,除掉边缘
    for i in range(1, rows-1):
        for j in range(1, cols-1):
            # pixel_set用来记录该店附近的黑色像素的数量
            pixel_set = []
            # 取该点的邻域为以该点为中心的九宫格
            for m in range(i-1, i+2):
                for n in range(j-1, j+2):
                    if image.getpixel((m, n)) != 1: # 1为白色,0位黑色
                        pixel_set.append(image.getpixel((m, n)))

            # 如果该位置的九宫内的黑色数量小于等于4,则判断为噪声
            if len(pixel_set) <= 4:
                change_pos.append((i,j))

    # 对相应位置进行像素修改,将噪声处的像素置为1(白色)
    for pos in change_pos:
        image.putpixel(pos, 1)

    return image # 返回修改后的图片

# 识别图片中的数字加字母
# 传入参数为图片路径,返回结果为:识别结果
def OCR_lmj(img_path):

    image = Image.open(img_path) # 打开图片文件
    imgry = image.convert("L")  # 转化为灰度图

    # 获取图片中的出现次数最多的像素,即为该图片的背景
    max_pixel = get_threshold(imgry)

    # 将图片进行二值化处理
    table = get_bin_table(threshold=max_pixel)
    out = imgry.point(table, "1")

    # 去掉图片中的噪声(孤立点)
    out = cut_noise(out)

    #保存图片
    # out.save("E://figures/img_gray.jpg")

    # 仅识别图片中的数字
    #text = pytesseract.image_to_string(out, config="digits")
    # 识别图片中的数字和字母
    text = pytesseract.image_to_string(out)

    # 去掉识别结果中的特殊字符
    exclude_char_list = " .:|""?![],()~@#$%^&*_+-={};<>/¥"
    text = "".join([x for x in text if x not in exclude_char_list])
    #print(text)

    return text

def main():
    
    # 识别指定文件目录下的图片
    # 图片存放目录figures
    dir = "E://figures"

    correct_count = 0  # 图片总数
    total_count = 0    # 识别正确的图片数量

    # 遍历figures下的png,jpg文件
    for file in os.listdir(dir):
        if file.endswith(".png") or file.endswith(".jpg"):
            # print(file)
            image_path = "%s/%s"%(dir,file) # 图片路径

            answer = file.split(".")[0]  # 图片名称,即图片中的正确文字
            recognizition = OCR_lmj(image_path) # 图片识别的文字结果

            print((answer, recognizition))
            if recognizition == answer: # 如果识别结果正确,则total_count加1
                correct_count += 1

            total_count += 1

    print("Total count: %d, correct: %d."%(total_count, correct_count))
    """
    # 单张图片识别
    image_path = "E://figures/code (1).jpg"
    OCR_lmj(image_path)
    """

main()

运行结果如下:

("101659", "101659")
("111073", "111073")
("114510", "114510")
("118235", "118235")
("124677", "124677")
("147291", "147291")
("169147", "169147")
("185302", "185302")
("23YB", "23YB")
("262051", "262051")
("2HED", "2MED")
("315386", "315386")
("3D7K", "3D7K")
("3DYH", "3DYH")
("3QG8", "30G8")
("3XNR", "EXNR")
("44G5", "44G5")
("470259", "470259")
("515413", "515413")
("522351", "522351")
("539824", "539824")
("5CVL", "SCVL")
("642689", "642689")
("671991", "671991")
("672838", "672838")
("6F5Y", "6F5Y")
("6USB", "GUSB")
("703167", "703167")
("765120", "765120")
("779931", "779931")
("8UEF", "8SUEF")
("905857", "905857")
("9H4H", "9H4H")
("9SK1", "OSK1")
("BDP4", "BDP4")
("DXV3", "DXV3")
("E78Y", "E78Y")
("EAHR", "EAHR")
("F585", "Fss§")
("FBV8", "FBV8")
("FJKK", "FJKK")
("GXKQ", "GXKQ")
("H7Y9", "H7Y9")
("J4LJ", "J4LJ")
("J8YH", "J8YH")
("JCDL", "JCDL")
("JTX2", "JTX2")
("JYLH", "JYLH")
("KFYA", "KFYA")
("L3VZ", "L3VZ")
("LCGV", "LCGV")
("LKEK", "LKEK")
("N3FJ", "N3FJ")
("PJZN", "PJZN")
("PNDQ", "PNDQ")
("Q7HP", "Q7HP")
("QSHU", "QSHU")
("R1RN", "RLRN")
("RPNX", "RPNX")
("TUKG", "TUKG")
("U9G3", "U9G3")
("UZAH", "UZAH")
("V6P9", "very")
("Y18D", "18D")
("Y237", "Y237")
("ZZT5", "2215")
Total count: 66, correct: 54.

我们可以看到图片识别的正确率为80%以上,其中数字类图片的识别正确率为100%.
  我们可以在图片识别方面的算法再加改进,以提高图片识别的正确率。当然,以上算法并不是对所有验证码都适用,不同的验证码需要用不同的图片处理算法。

注意:本人现已开通两个微信公众号: 因为Python(微信号为:python_math)以及轻松学会Python爬虫(微信号为:easy_web_scrape), 欢迎大家关注哦~~

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/41835.html

相关文章

  • 首次公开,整理12年积累的博客收藏夹,零距离展示《收藏夹吃灰》系列博客

    摘要:时间永远都过得那么快,一晃从年注册,到现在已经过去了年那些被我藏在收藏夹吃灰的文章,已经太多了,是时候把他们整理一下了。那是因为收藏夹太乱,橡皮擦给设置私密了,不收拾不好看呀。 ...

    Harriet666 评论0 收藏0
  • Python入门网络爬虫精华版

    摘要:学习网络爬虫主要分个大的版块抓取,分析,存储另外,比较常用的爬虫框架,这里最后也详细介绍一下。网络爬虫要做的,简单来说,就是实现浏览器的功能。 Python学习网络爬虫主要分3个大的版块:抓取,分析,存储 另外,比较常用的爬虫框架Scrapy,这里最后也详细介绍一下。 首先列举一下本人总结的相关文章,这些覆盖了入门网络爬虫需要的基本概念和技巧:宁哥的小站-网络爬虫,当我们在浏览器中输入...

    Bmob 评论0 收藏0
  • python自动化测试破解滑动验证

      python作为一门比较常见的编程语言,在工作当中的应用还是比较的广泛的,比如可以对此进行相关的自动化测试,比如自动化测试相关的代码,另外还有破解滑动验证码。那么,具体的操作手法是怎样的呢?下面就给大家详细解答下。  在Web自动化测试的过程中,经常会被登录的验证码给卡住,不知道如何去通过验证码的验证。  一般的情况下遇到验证码我们可以都可以找开发去帮忙解决,关闭验证码,或者给一个万能的验证码...

    89542767 评论0 收藏0
  • python自动化测试破解图文验证

      小编写这篇文章的主要目的,主要是用来给大家介绍关于python自动化测试的一些事情,涉及到的内容主要有包括破解图文验证码等相关的一些事宜,具体怎么才能够破解图文验证码呢?下面就给大家详细解答下。  对于web应用程序来讲,处于安全性考虑,在登录的时候,都会设置验证码,  验证码的类型种类繁多,有图片中辨别数字字母的,有点击图片中指定的文字的,也有算术计算结果的,再复杂一点就是滑动验证的。  诸...

    89542767 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<