zoukankan      html  css  js  c++  java
  • opencv 验证码 识别

    示例图片 :  

    主要应用原理为:1

    1、先识别出图片中每个像素的数量   例如 红色在200左右

    2、将红色的像素单独提出来  这样起到去除噪点的作用

    3、分割图片并保存  

    4、识别图片

    具体代码如下:

      1 # coding=utf-8
      2 # !/usr/bin/python
      3 """
      4 opencv 验证码识别
      5 Created on: 2018/7/31  16:12
      6 @author: 虫子慢慢爬
      7 Email: 891915210@qq.com
      8 """
      9 # -*- coding=GBK -*-
     10 
     11 from PIL import Image
     12 import hashlib
     13 import time
     14 
     15 im = Image.open("C:/Users/admin/Desktop/image/p.jpg")
     16 
     17 # (将图片转换为8位像素模式)
     18 
     19 im = im.convert("P")
     20 
     21 # 打印颜色直方图
     22 
     23 print(im.histogram())
     24 """颜色直方图的每一位数字都代表了在图片中含有对应位的颜色的像素的数量。
     25    每个像素点可表现256种颜色,你会发现白点是最多
     26    (白色序号255的位置,也就是最后一位,可以看到,有625个白色像素)。
     27    红像素在序号200左右,我们可以通过排序,得到有用的颜色。
     28 """
     29 his = im.histogram()
     30 
     31 values = {}
     32 
     33 for i in range(256):
     34     values[i] = his[i]
     35 
     36 for j, k in sorted(values.items(), key=lambda x: x[1], reverse=True)[:10]:
     37     print(j, k)
     38 """
     39 我们得到了图片中最多的10种颜色,
     40 其中 220 与 227 才是我们需要的红色和灰色,
     41 可以通过这一讯息构造一种黑白二值图片
     42 """
     43 im2 = Image.new("P", im.size, 255)
     44 
     45 for x in range(im.size[1]):
     46 
     47     for y in range(im.size[0]):
     48         pix = im.getpixel((y, x))
     49         if pix == 225:  # these are the numbers to get
     50             im2.putpixel((y, x), 0)
     51 
     52 im2.show()
     53 # time.sleep(3)
     54 """ 接下来的工作是要得到单个字符的像素集合,由于例子比较简单,我们对其进行纵向切割:"""
     55 
     56 inletter = False
     57 
     58 foundletter = False
     59 
     60 start = 0
     61 
     62 end = 0
     63 
     64 letters = []
     65 
     66 for y in range(im2.size[0]):
     67 
     68     for x in range(im2.size[1]):
     69         pix = im2.getpixel((y, x))
     70 
     71         if pix != 255:
     72             inletter = True
     73 
     74     if foundletter == False and inletter == True:
     75         foundletter = True
     76         start = y
     77 
     78     if foundletter == True and inletter == False:
     79         foundletter = False
     80         end = y
     81         letters.append((start, end))
     82 
     83     inletter = False
     84 
     85 print(letters)
     86 
     87 # [(6, 14), (15, 25), (27, 35), (37, 46), (48, 56), (57, 67)]
     88 
     89 """  得到每个字符开始和结束的列序号。"""
     90 
     91 count = 0
     92 
     93 for letter in letters:
     94     m = hashlib.md5()
     95 
     96     im3 = im2.crop((letter[0], 0, letter[1], im2.size[1]))
     97     ss1 = str(time.time()) + str(count)
     98     print(ss1)
     99     m.update(ss1.encode('utf-8'))
    100     # 对图片进行切割,得到每个字符所在的那部分图片。
    101     im3.save("./%s.gif" % (m.hexdigest()))
    102 
    103     count += 1
    104     """
    105 在这里我们使用向量空间搜索引擎来做字符识别,它具有很多优点:
    106 
    107 不需要大量的训练迭代
    108 
    109 不会训练过度
    110 
    111 你可以随时加入/移除错误的数据查看效果
    112 
    113 很容易理解和编写成代码
    114 
    115 提供分级结果,你可以查看最接近的多个匹配
    116 
    117 对于无法识别的东西只要加入到搜索引擎中,马上就能识别了。
    118 
    119   当然它也有缺点,例如分类的速度比神经网络慢很多,它不能找到自己的方法解决问题等等。
    120 
    121   向量空间搜索引擎名字听上去很高大上其实原理很简单。拿文章里的例子来说:
    122 
    123   你有 3 篇文档,我们要怎么计算它们之间的相似度呢?两篇文档所使用的相同的单词越多,那这两篇文章就越相似!但是这单词太多怎么办,就由我们来选择几个关键单词,选择的单词又被称作特征,每一个特征就好比空间中的一个维度(x,y,z 等),一组特征就是一个矢量,每一个文档我们都能得到这么一个矢量,只要计算矢量之间的夹角就能得到文章的相似度了。
    124 
    125   用 Python 类实现向量空间:
    126 """
    127 
    128 import math
    129 
    130 
    131 class VectorCompare:
    132 
    133     # 计算矢量大小
    134 
    135     def magnitude(self, concordance):
    136 
    137         total = 0
    138 
    139         for word, count in concordance.iteritems():
    140             total += count ** 2
    141 
    142         return math.sqrt(total)
    143 
    144     # 计算矢量之间的 cos 值
    145 
    146     def relation(self, concordance1, concordance2):
    147 
    148         relevance = 0
    149 
    150         topvalue = 0
    151 
    152         for word, count in concordance1.iteritems():
    153 
    154             if concordance2.has_key(word):
    155                 topvalue += count * concordance2[word]
    156 
    157         return topvalue / (self.magnitude(concordance1) * self.magnitude(concordance2))
    158 
    159     #   它会比较两个 python 字典类型并输出它们的相似度(用 0~1 的数字表示)
    160 
    161     """
    162     将之前的内容放在一起
    163       还有取大量验证码提取单个字符图片作为训练集合的工作,但只要是有好好读上文的同学就一定知道这些工作要怎么做,在这里就略去了。可以直接使用提供的训练集合来进行下面的操作。
    164     
    165       iconset目录下放的是我们的训练集。
    166     
    167       最后追加的内容:
    168     
    169     """
    170 
    171     # 将图片转换为矢量
    172 
    173     def buildvector(im):
    174 
    175         d1 = {}
    176 
    177         count = 0
    178 
    179         for i in im.getdata():
    180             d1[count] = i
    181 
    182             count += 1
    183 
    184         return d1
    185 
    186 
    187 v = VectorCompare()
    188 
    189 iconset = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
    190            'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
    191 
    192 import os
    193 
    194 # 加载训练集
    195 
    196 imageset = []
    197 
    198 for letter in iconset:
    199 
    200     for img in os.listdir('./iconset/%s/' % (letter)):
    201 
    202         temp = []
    203 
    204         if img != "Thumbs.db" and img != ".DS_Store":
    205             temp.append(v.buildvector(Image.open("./iconset/%s/%s" % (letter, img))))
    206 
    207             imageset.append({letter: temp})
    208 
    209 count = 0
    210 
    211 # 对验证码图片进行切割
    212 
    213 for letter in letters:
    214     m = hashlib.md5()
    215 
    216     im3 = im2.crop((letter[0], 0, letter[1], im2.size[1]))
    217 
    218     guess = []
    219 
    220 # 将切割得到的验证码小片段与每个训练片段进行比较
    221 
    222 for image in imageset:
    223 
    224     for x, y in image.iteritems():
    225 
    226         if len(y) != 0:
    227             guess.append((v.relation(y[0], v.buildvector(im3)), x))
    228 
    229         guess.sort(reverse=True)
    230 
    231     print("", guess[0])
    232 
    233     count += 1

    希望对大家有帮助哦!!

  • 相关阅读:
    pycharm使用
    python上手之环境搭建
    LDA浅析转
    矩阵按列按行归一化到L2范数的原理和最精简Matlab代码(转)
    (转)Low-Mid-High
    菲波纳数列的特性
    劝狼赋
    asp.net mvc Controller 模式下的 aop
    android for vs (三)visual studio android 发布为 apk
    android for vs (二)visual studio android 开发实例
  • 原文地址:https://www.cnblogs.com/bianzhiwei/p/9397136.html
Copyright © 2011-2022 走看看