python简单验证码识别

利用SVM向量机进行4位数字验证码识别

       主要是思路和步骤如下:

一,素材收集

检查环境是否包含有相应的库:

1.在cmd中,通过 pip list命令查看安装的库

2.再使用pip installRequests 安装Requests库

3.再次使用pip list 命令

python简单验证码识别_第1张图片

4.利用python获取验证码资源

编写代码:_DownloadPic.py

 

#!/usr/bin/nev python3
#利用python从站点下载验证码图片

import requests

## 1.在 http://www.xxx.com
#  获取验证码URL
def Downloads_Pic(strPath, strName):
    #设置url
    url = 'http://www.xxx.com'

    #以二进制方式发送Get请求,
    #将stream = True,
    #数据读取完成前不要断开链接
    rReq = requests.get(url, stream = True)

    #尝试保存图片
    with open(strPath + strName + '.png', 'wb') as fpPic:
        #循环读取1024Byte到byChunk中,读完则跳出
        for byChunk in rReq.iter_content(chunk_size = 1024):
            if byChunk:
                fpPic.write(byChunk)
                fpPic.flush()
        fpPic.close()

for i in range(1, 10 + 1):
    strFileName = "%03d" % i
    Downloads_Pic('D:/1/', strFileName)

二,素材处理

1.二值化处理,增加对比度,锐化,增加亮度,滤镜,转为黑白

2.去除噪点

3.切割图片

python简单验证码识别_第2张图片

编写代码:_PicDealWith.py

 

#!/usr/bin/env python3
import os
import os.path
from PIL import Image, ImageEnhance, ImageFilter
import random

#二值化处理
#strImgPath 图片路径
def BinaryzationImg(strImgPath):
    #打开图片
    imgOriImg = Image.open(strImgPath)

    #增加对比度
    pocEnhance = ImageEnhance.Contrast(imgOriImg)
    #增加255%对比度
    imgOriImg = pocEnhance.enhance(2.55)

    #锐化
    pocEnhance = ImageEnhance.Sharpness(imgOriImg)
    #锐化200%
    imgOriImg = pocEnhance.enhance(2.0)

    #增加亮度
    pocEnhance = ImageEnhance.Brightness(imgOriImg)
    #增加200%
    imgOriImg = pocEnhance.enhance(2.0)

    #添加滤镜效果
    imgGryImg = imgOriImg.convert('L').filter(ImageFilter.DETAIL)

    #二值化处理
    imgBinImg = imgGryImg.convert('1')

    return imgBinImg

#去除噪点
def ClearNoise(imgBinImg):
    for x in range(1, (imgBinImg.size[0]-1)):
        for y in range(1,(imgBinImg.size[1] - 1)):
        #一个点为黑色,周围8个点为白色,则此点为噪点,设置为白色
            if imgBinImg.getpixel((x, y)) == 0 \
                and imgBinImg.getpixel(((x - 1), (y + 1))) == 255 \
                and imgBinImg.getpixel(((x - 1), y)) == 255 \
                and imgBinImg.getpixel(((x - 1), (y - 1))) == 255 \
                and imgBinImg.getpixel(((x + 1), (y + 1))) == 255 \
                and imgBinImg.getpixel(((x + 1), y)) == 255 \
                and imgBinImg.getpixel(((x + 1), (y - 1))) == 255 \
                and imgBinImg.getpixel((x, (y + 1))) == 255 \
                and imgBinImg.getpixel((x, (y - 1))) == 255:
                imgBinImg.putpixel([x, y], 255)

    return imgBinImg

#切割图片
def GetCropImgs(imgClrImg):
    ImgList = []
    for i in range(4):
        x = 6 + i * 13
        y = 3
        SubImg = imgClrImg.crop((x, y, x + 13, y + 15))
        ImgList.append(SubImg)
    return ImgList


#调用部分
def main():
    g_Count = 0
    strStep1Dir = 'D:/1/step1/'
    strStep2Dir = 'D:/1/step2/'
    for ParentPath, DirName, FileNames in os.walk(strStep1Dir):
        for i in FileNames:
            #图片文件路径信息
            strFullPath = os.path.join(ParentPath, i)
            imgBinImg = BinaryzationImg(strFullPath)
            imgClrImg = ClearNoise(imgBinImg)
            ImgList = GetCropImgs(imgClrImg)
            for img in ImgList:
                strImgName = "%04d%04d.png" % (g_Count, random.randint(0, 9999))
                strImgPath = os.path.join(strStep2Dir, strImgName)
                img.save(strImgPath)
                g_Count += 1

    print("OK!")

if __name__ == '__mian__':
    main()



三,手工分类

将第二步切割好的图片进行分类,体力活

python简单验证码识别_第3张图片

四,利用SVM向量机建立模型

1.安装svm库

  下载libsvm库,并解压

  将库中的windows目录的路径添加到path环境变量中

将libsvm下的python文件夹中的svm.py和svmutil.py文件拷贝到你的python的路径中lib文件夹中

from svmutil import *

2.生成模型文件

  2.1.将分好类的图片信息进行提取,生成特征值

  2.2.输出向量数据

python简单验证码识别_第4张图片

  2.3.根据数据输出SVM模型文件

 python简单验证码识别_第5张图片

编写代码:_SVMDemo.py

 

#!/usr/bin/env python3

#SVM,验证码识别

import os
import sys
import random
import os.path
from PIL import Image, ImageEnhance, ImageFilter
from svmutil import *

##记录像素点的值,描述特征,采用遍历每个像素点统计黑色点的数量
def GetFeature(imgCropImg, nImgHeight, nImgWidth):
    PixelCountList = []
    for y in range(nImgHeight):
        CountX = 0
        for x in range(nImgWidth):
            if imgCropImg.getpixel((x, y)) == 0:
                CountX += 1
        PixelCountList.append(CountX)
    for x in range(nImgWidth):
        CountY = 0
        for y in range(nImgHeight):
            if imgCropImg.getpixel((x, y)) == 0:
                CountY += 1
        PixelCountList.append(CountY)
    return PixelCountList

##输出向量数据
def OutPutVectorData(strID, strMaterialDir, strOutPath):
    for ParentPath, DirNames, FileNames in os.walk(strMaterialDir):
        with open(strOutPath, 'a') as fpFea:
            for fp in FileNames:
                #图片文件路径信息
                strFullPath = os.path.join(ParentPath, fp)

                #打开图片
                imgOriImg = Image.open(strFullPath)

                #生成特征值
                FeatureList = GetFeature(imgOriImg, 15, 13)

                strFeature = strID + ' '
                nCount = 1
                for i in FeatureList:
                    strFeature = '%s%d:%d ' % (strFeature, nCount, i)
                    nCount += 1
                fpFea.write(strFeature + '\n')
                fpFea.flush()
        fpFea.close()

#训练SVM模型
def TrainSvmModel(strProblemPath, strModelPath):
    Y, X = svm_read_problem(strProblemPath)
    Model = svm_train(Y, X)
    svm_save_model(strModelPath, Model)

#SVM模型测试
def SvmModelTest(strProblemPath, strModelPath):
    TestY, TestX = svm_read_problem(strProblemPath)
    Model = svm_load_model(strModelPath)
    #返回识别结果
    pLabel, pAcc, pVal = svm_predict(TestY, TestX, Model)
    return pLabel


##输出测试向量数据
def OutPutTestVectorData(strID, strDir, strOutPath):
    fileList = []
    for parentPath, strDir, fileName in os.walk(strDir):
        fileList = fileName
    with open(strOutPath, 'a') as fpFea:
        for fp in fileList:
            #图片文件路径信息
            strFullPath = os.path.join(parentPath, fp)

            #打开图片
            imgOriImg = Image.open(strFullPath)

            #生成特征值
            FeatureList = GetFeature(imgOriImg, 15, 13)

            strFeature = strID + ' '
            nCount = 1
            for i in FeatureList:
                strFeature = '%s%d:%d ' % (strFeature, nCount, i)
                nCount += 1
            fpFea.write(strFeature + '\n')
            fpFea.flush()
        fpFea.close()


def main():
# 1.循环输出向量文件
    for i in range(0, 10):
        strID = '%d' % i
        OutPutVectorData(strID, 'D:/1/step3/' + strID, 'D:/1/step4/Vector.txt')

# 2.调用函数训练SVM模型
    TrainSvmModel('D:/1/step4/Vector.txt', 'D:/1/step5/Model.txt')
# 3.调用函数识别结果
    pLabel = SvmModelTest('D:/1/step6/Vector.txt', 'D:/1/step5/Model.txt')
    for i in pLabel:
        print('%d' % i)



if __name__ == '__main__':
    main()


五,测试

1.利用模型文件和向量文件进行测试验证码识别

    ##1.获取一张验证码图片

    ##2.对图片进行处理

    ##  2.1.二值化处理,增加对比度,锐化,增加亮度,滤镜,转为黑白,

    ##  2.2.去除噪点

    ##  2.3.切割图片

    ##3.生成向量文件

    ##4.再利用之前的模型文件进行识别测试

编写代码:_SVMTest.py

#!/usr/bin/env python3
#对一张验证码图片进行识别测试

##1.获取一张验证码图片
##2.对图片进行处理
##  2.1.二值化处理,增加对比度,锐化,增加亮度,滤镜,转为黑白,
##  2.2.去除噪点
##  2.3.切割图片
##3.生成向量文件
##4.再利用之前的模型文件进行识别测试

################
import _PicDealWith
import os
import random
import _SVMDemo


##测试
g_Count = 0
strDirPath = 'D:/1/test/'
strFileName = '001.png'
#1.图片文件路径信息
strFullPath = os.path.join(strDirPath, strFileName)
#2.对图片进行处理
#2.1二值化处理
imgBinImg = _PicDealWith.BinaryzationImg(strFullPath)
#2.2去除噪点
imgClrImg = _PicDealWith.ClearNoise(imgBinImg)
#2.3切割图片
ImgList = _PicDealWith.GetCropImgs(imgClrImg)
#2.3循环写入文件
for img in ImgList:
    strImgName = "%04d%04d.png" % (g_Count, random.randint(0, 9999))
    strImgPath = os.path.join(strDirPath, strImgName)
    img.save(strImgPath)
    g_Count += 1

print("OK")

os.remove(strFullPath)

#3.生成向量文件
_SVMDemo.OutPutTestVectorData('0', 'D:/1/test/', 'D:/1/test/Vector.txt')

#4.利用之前的模型文件进行识别测试
pLabel = _SVMDemo.SvmModelTest('D:/1/test/Vector.txt', 'D:/1/step5/Model.txt')
for i in pLabel:
    print('%d' % i, end = '')

效果图:

python简单验证码识别_第6张图片

 

 

  


你可能感兴趣的:(python自学笔记)