如何對圖像進行去噪來繞過驗證碼的方法
?通過使用廣度優(yōu)先搜索算法對圖像進行去噪來繞過驗證碼的新方法
驗證碼被廣泛用作確保對系統(tǒng)執(zhí)行的操作是由人類而不是機器人完成的一種方式。然而,這種方法并不是萬無一失的,尤其是在OCR和計算機視覺技術如此發(fā)達的今天。讓我們從用戶的角度來看,每次想要訪問某個網(wǎng)站時都必須解決驗證碼是一件非常痛苦的事情,尤其是當你每天都需要這樣做時!在本文中,將探索我自己的繞過特定類型驗證碼的方法。該方法利用廣度優(yōu)先搜索 (BFS) 和OpenCV在將圖像傳遞給OCR引擎 (Tesseract) 之前對圖像進行去噪。由于有太多不同類型的文本驗證碼具有不同形式的失真/增強,因此我的方法僅適用于我試圖繞過的特定驗證碼源。但也許你會在我的文章中找到一些對你自己解決驗證碼問題有用的細節(jié)!驗證碼
正如我所提到的,有許多不同類型的文本驗證碼。我試圖繞過的驗證碼的變化對單詞應用傾斜失真,同時用雪狀圖案覆蓋圖像。從根本上(并且幸運的是),這種類型的驗證碼并不太難解決。這是因為驗證碼文本本身沒有任何噪音,可以被 OCR 引擎識別。如果文本被進一步扭曲,像 Tesseract 這樣的開源 OCR 庫將無法讀取文本。因此,我們現(xiàn)在需要做的是一系列圖像過濾以去除所有噪聲并僅保留驗證碼文本。方法我將要討論的方法具有概率特性,這意味著它不能保證在每次試驗中都有效。但是,我們可以利用驗證碼和系統(tǒng)的一些先驗知識來確保我們最大化驗證碼的成功概率。但首先,讓我們談談驗證碼圖像的去噪方法。該過程可以概括為以下步驟:轉換為灰度中值濾波器(內(nèi)核大小 3)圖像閾值處理島嶼去除中值濾波器(內(nèi)核大小 3)
圖像首先轉換為灰度,以將通道數(shù)減少到僅 1。然后注意到在現(xiàn)有的隨機雪花噪聲之上放置了一致的明暗像素點圖案。中值濾波器可以有效去除這種密集和重復的噪聲模式。盡管有輕微的模糊,但經(jīng)過中值濾波器后的圖像更加清晰。我們要做的下一步是對圖像進行閾值處理,將所有像素強度推到 1 或 0。閾值通過反復試驗進行微調(diào),以確保保留文本的所有像素。
在此之后,我們留下了驗證碼文本,周圍是點狀噪聲,這是閾值化的殘留物。這些點分散在圖像周圍,但更多地集中在文本周圍。這就是使用 BFS 的地方,因為我們將使用這種我稱之為“島嶼去除”的方法來去除所有的點狀噪聲。該方法訪問了圖像上的所有黑色像素。在每個黑色像素上,它使用 BFS 找到所有也是黑色的鄰居。
本質(zhì)上,該函數(shù)識別圖像上的所有黑色像素簇,如果簇大小小于預定閾值,則將其移除(即轉換為白色像素)。這種“去除島嶼”方法的靈感來自于相當流行的編程問題Number of Islands,你應該使用 BFS 或 DFS 來計算二維數(shù)組(即島嶼)中 1 的簇數(shù)。最后一步是應用另一個內(nèi)核大小為 3 的中值濾波器來平滑圖像的邊緣。然后,它準備好傳遞到 Tesseract OCR 進行文本提取。從上面的步驟圖可以看出,去噪過程產(chǎn)生了相當積極的輸出。最重要的是,Tesseract 能夠識別輸出正確驗證碼文本的單詞就足夠了。下面是去噪的代碼片段。
def bfs(visited, queue, array, node):
# I make BFS itterative instead of recursive
def getNeighboor(array, node):
neighboors = []
if node[0]+1
neighboors.a(chǎn)ppend((node[0]+1,node[1]))
if node[0]-1>0:
if array[node[0]-1,node[1]] == 0:
neighboors.a(chǎn)ppend((node[0]-1,node[1]))
if node[1]+1
neighboors.a(chǎn)ppend((node[0],node[1]+1))
if node[1]-1>0:
if array[node[0],node[1]-1] == 0:
neighboors.a(chǎn)ppend((node[0],node[1]-1))
return neighboors
queue.a(chǎn)ppend(node)
visited.a(chǎn)dd(node)
while queue:
current_node = queue.pop(0)
for neighboor in getNeighboor(array, current_node):
if neighboor not in visited:
# print(neighboor)
visited.a(chǎn)dd(neighboor)
queue.a(chǎn)ppend(neighboor)
def removeIsland(img_arr, threshold):
# !important: the black pixel is 0 and white pixel is 1
while 0 in img_arr:
x,y = np.where(img_arr == 0)
point = (x[0],y[0])
visited = set()
queue = []
bfs(visited, queue, img_arr, point)
if len(visited) <= threshold:
for i in visited:
img_arr[i[0],i[1]] = 1
else:
# if the cluster is larger than threshold (i.e is the text),
# we convert it to a temporary value of 2 to mark that we
# have visited it.
for i in visited:
img_arr[i[0],i[1]] = 2
img_arr = np.where(img_arr==2, 0, img_arr)
return img_arr
img = cv2.imread("temp.png")
# Convert to grayscale
c_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
# Median filter
kernel = np.ones((3,3),np.uint8)
out = cv2.medianBlur(c_gray,3)
# Image thresholding
a = np.where(out>195, 1, out)
out = np.where(a!=1, 0, a)
# Islands removing with threshold = 30
out = removeIsland(out, 30)
# Median filter
out = cv2.medianBlur(out,3)
# Convert to Image type and pass it to tesseract
im = Image.fromarray(out*255)
print(pytesseract.image_to_string(im))
以上是此方法在輸出正確驗證碼之前進行的試驗次數(shù)分布的直方圖。數(shù)據(jù)是我自己記錄的,因為我個人每天都使用這種方法超過 3 個月?梢钥闯,大多數(shù)試驗次數(shù)低于 20,精確平均值為 9.02。結論本文中介紹的方法有一定的優(yōu)缺點。優(yōu)點是該方法不需要任何訓練,因此不需要標記數(shù)據(jù)集。計算速度快,實現(xiàn)簡單。然而,缺點是該方法是概率性的,因此對于在多次錯誤嘗試驗證碼后阻止用戶的系統(tǒng),使用這種方法可能會鎖定你的帳戶。此外,該方法針對非常特定類型的驗證碼,需要微調(diào),甚至可能不適用于其他類型的驗證碼。
請輸入評論內(nèi)容...
請輸入評論/評論長度6~500個字
最新活動更多
-
即日-11.13立即報名>>> 【在線會議】多物理場仿真助跑新能源汽車
-
11月28日立即報名>>> 2024工程師系列—工業(yè)電子技術在線會議
-
12月19日立即報名>> 【線下會議】OFweek 2024(第九屆)物聯(lián)網(wǎng)產(chǎn)業(yè)大會
-
即日-12.26火熱報名中>> OFweek2024中國智造CIO在線峰會
-
即日-2025.8.1立即下載>> 《2024智能制造產(chǎn)業(yè)高端化、智能化、綠色化發(fā)展藍皮書》
-
精彩回顧立即查看>> 【限時免費下載】TE暖通空調(diào)系統(tǒng)高效可靠的組件解決方案
推薦專題
- 高級軟件工程師 廣東省/深圳市
- 自動化高級工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級銷售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結構工程師 廣東省/深圳市