验证码识别之二值化

前言

二值化顾名思义就是将数变成两种值,一般非0即1。而在验证码处理中,如果直接使用灰度图,那么每个像素的值会在0-255,这样肯定会增加计算时间,而二值化后每个像素的值只是0和1。

在前面的简单验证码识别中,我的二值化代码是这样写的:a = (a > 180) * 255,至于这里为什么不乘1而乘255,因为我要显示图片看看效果。如果只是用于算法识别的话,乘1会更好。但是,这里的180也就是二值化的阈值是如何得到的,开始是通过一个一个试然后看效果哪个好就选哪个,因为我们一般只识别某个网站的验证码,这样只要测试几次得到结果后便可用于这个网站其他的验证码。

这样测试有点浪费时间,虽然是一次性的,但是你手动测出的验证码不一定是最合适的。所以我们需要算法去自动计算出验证码的阈值,算法有很多,这里我们使用迭代法和最大类间方差法,通过这两个算法计算出来的阈值基本差不多。

迭代法

  1. 求出图像中的最小灰度值和最大灰度值,分别记为Gmin和Gmax,则阈值初值T0=(Gmin+Gmax)/2;
  2. 根据阈值T0将图像分割成前景和背景两部分,求出两部分的平均灰度值m1和m2,平均灰度值=总灰度值/像素个数
  3. 求出新阈值T1=(m1+m2)/2
  4. 如果T0=T1,则结束,否则将T1的值赋予T0,从第2步重新计算。

算法实现如下:

import numpy as np
from PIL import Image

def iteration(img_path):
    img = Image.open(img_path).convert('L')
    a = np.array(img)
    a = a.ravel()
    k = int((int(a.max()) + int(a.min()))/2) # 即初始阈值T0
    m = -1
    while k != m:
        # C1和C2为前景和背景的像素
        C1 = a[a >= k]
        C2 = a[a < k]
        k = m
        m1 = np.sum(C1)/len(C1) if len(C1) else 0
        m2 = np.sum(C2)/len(C2) if len(C2) else 0
        m = int((m1 + m2)/2)
    return k 

最大类间方差法(OTSU)

原理参考:https://blog.csdn.net/weixin_40647819/article/details/90179953

这里我直接复制一遍:

存在阈值T将图像所有像素分为前景和背景,则这两类像素各自的均值就为m1、m2,图像全局均值为mG。同时像素被分为前景和背景的概率分别为p1、p2。因此就有:
p1*m1+p2*m2=mGp1+p2=1 则类间方差表达式为:


使得上式值最大时的阈值T就是最佳的阈值。

算法实现如下:

import numpy as np
from PIL import Image

def otsu(img_path):
    img = Image.open(img_path).convert('L')
    a = np.array(img)
    a = a.ravel()
    L = []
    for k in range(0, 256):
        C1 = a[a >= k]
        C2 = a[a < k]
        if not(len(C1) and  len(C2)):
            L.append(0)
            continue
        m1 = np.sum(C1)/len(C1)
        m2 = np.sum(C2)/len(C2)
        p1 = len(C1)/len(a)
        p2 = len(C2)/len(a)
        x = p1 * p2 * (m1 - m2) * (m1 - m2)
        L.append(x)
    return L.index(max(L))

看一下效果:
原图

迭代法

最大类间方差法

最后,我正在学习一些机器学习的算法,对于一些我需要记录的内容我都会分享到博客和微信公众号(python成长路),欢迎关注。平时的话一般分享一些爬虫或者Python的内容。

原文地址:https://www.cnblogs.com/kanadeblisst/p/12191351.html

时间: 2024-08-17 23:28:21

验证码识别之二值化的相关文章

atitit.验证码识别step4--------图形二值化 灰度化

atitit.验证码识别step4--------图形二值化 灰度化 1. 常见二值化的方法原理总结 1 1.1. 方法一:该方法非常简单,对RGB彩色图像灰度化以后,扫描图像的每个像素值,值小于127的将像素值设为0(黑色),值大于等于127的像素值设为255(白色). 1 1.2. 方法二:最常见的二值处理方法是计算像素的平均值K, 2 1.3. 方法三:使用直方图方法来寻找二值化阈值, 2 1.4. 方法四:使用近似一维Means方法寻找二值化阈值,(推荐) 3 2. 使用类库imagei

机器学习进阶-项目实战-信用卡数字识别 1.cv2.findContour(找出轮廓) 2.cv2.boudingRect(轮廓外接矩阵位置) 3.cv2.threshold(图片二值化操作) 4.cv2.MORPH_TOPHAT(礼帽运算突出线条) 5.cv2.MORPH_CLOSE(闭运算图片内部膨胀) 6. cv2.resize(改变图像大小) 7.cv2.putText(在图片上放上文本)

7. cv2.putText(img, text, loc, text_font, font_scale, color, linestick) # 参数说明:img表示输入图片,text表示需要填写的文本str格式,loc表示文本在图中的位置,font_size可以使用cv2.FONT_HERSHEY_SIMPLEX, font_scale表示文本的规格,color表示文本颜色,linestick表示线条大小 信用卡数字识别: 信用卡      数字模板涉及到的内容:主要是采用模板匹配的思想 思

python图片二值化提高识别率

import cv2from PIL import Imagefrom pytesseract import pytesseractfrom PIL import ImageEnhanceimport reimport string def createFile(filePath,newFilePath): img = Image.open(filePath) # 模式L”为灰色图像,它的每个像素用8个bit表示,0表示黑,255表示白,其他数字表示不同的灰度. Img = img.conver

验证码图片二值化问题 BitmapData 怎么解决

对不起,这算是一篇求助啦,先上图,防止不清楚,放大了一点,下面是图片,上面是没有二值化的,下面是二值化之后的,我其实不懂什么是二值化啦,就是一定范围变黑,变白 问题: 为什么我的结果上面还是有很多彩色的小点点呢?原来都是没有的-- 谁能帮我看看代码怎么改!谢谢大牛们帮忙!! Bitmap bit1 = new Bitmap(bit); Rectangle rect1 = new Rectangle(0, 0, bit1.Width, bit1.Height); BitmapData bitd =

Java 对二值化图片识别连通域

用Java 对 已经 二值化了的图片 标记连通域 每块的连通域都标记不一样的数字 1 public static void main(String [] args) throws IOException { 2 //二值化 3 BufferedImage image = ImageIO.read(new File("F:/MyCode/LianTongYu/specialGray.jpg")); 4 int w = image.getWidth(); 5 int h = image.g

集美大学教务处验证码识别(二)

[原创,转载请标明作者:森狗] 本文对第二种验证码,即管理员登入后台地址的验证码进行识别. 1.采集一些验证码,0~9都要有 2.观察验证码,用画图工具即可. 观察可发现,噪点即阴影,此处的阴影就是颜色比主体验证码略淡,以此为突破口. 3.去除噪点 color.getGreen() 获取绿色的值int,绿色值(0~255 从深到浅),大于200的就是浅色的噪点 public static int isWhite(int colorInt) { Color color = new Color(co

基于Java对图片进行二值化处理

一直以来对Java的图形处理能力表无力,但好像又不是那么一回事,之前用PHP做过一些应用,涉及到验证码的识别,其中有个图片二值化的步骤,今天换成Java来实现下 在java的扩展包javax.imageio中为我们提供了一个类叫ImageIO,这个类提供了一些执行简单编码和解码的静态便捷方法,具体说明大家可以翻下API看看 下面来说下关于图片二值化的原理: 1.首先要获取每个像素点的灰度值. 2.定义一个阀值. 3.将每个像素点的灰度值和它周围的8个像素点的灰度值相叠加再除以9,然后和阀值进行比

[转载+原创]Emgu CV on C# (四) —— Emgu CV on 二值化

重点介绍了二值化原理及数学实现,并利用emgucv方法编程实现. 一.理论概述(转载,如果懂图像处理,可以略过,仅用作科普,或者写文章凑字数)  1.概述 图像二值化是图像处理中的一项基本技术,也是很多图像处理技术的预处理过程. 图像的预处理在进行图像二值化操作前要对图像进行预处理,包括彩色图像灰化和增强.由于选取阈值需要参照直方图,因此在图像进行处理后,我们再获取图像的直方图以帮助选取阈值.整个流程如下所示: 读取图像→灰度图像→图像增强→图像直方图→二值化处理 2.数学原理(转载,基本可以不

数字图像处理_图像二值化_jzcjedu

皮卡丘:“师兄! ” 师兄:“干嘛…?” 皮卡丘:“你帮我看看这个,这是我打车的发票,看起来有点不太清晰,老板说不给我报销…” 师兄:“你仿佛在特意逗我笑,这不是很清楚嘛!!! ” 皮卡丘:“我老板有强迫症,他说这个扫描之后不清楚,让我弄清晰点再给他,不然就不给我钱.师兄,你一定要帮我呀,不然以后都不能打车了.” 师兄:“不急,我先看看,我记得当初张康老师教过我对于这种信噪比很高的图像你要提取出想要的信息的话用二值化处理又简单又方便.“ 皮卡丘:“这样啊,快弄给我看看.“ 稍等,我开一下MATL