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

 

希望對大家有幫助哦!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM