示例圖片 :
主要應用原理為: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
希望對大家有幫助哦!!