廢話
滑塊驗證碼破解是一直都想搞的項目,畢竟多數網站都會採用滑塊驗證碼,因而最近在修改論文的閒暇之餘把這事兒給解決了。要搞如今的滑塊驗證碼繞不開圖像處理,圖像處理固然是首推OpenCV-Python
啦!固然個人OpenCV很是菜(P.S.兩天速成不敢保證代碼質量
),發現問題就直接指出嘛,不用走流程啦!python
環境
首先須要一個python,而後安裝opencv的python庫,以下:pip install opencv-python
而後測試一下是否可用,以下:算法
import cv2 as cv import numpy as np if __name__ == '__main__': img = np.ones((200, 200, 3), np.uint8) * 255 cv.rectangle(img, (50, 50), (150, 150), (0, 0, 255), 2) cv.imshow('test', img) cv.waitKey(0) cv.destroyAllWindows()
正常的話就會以下顯示:測試
OpenCV的使用
相關的API我也是邊用邊查的,用得也是至關生疏!具體的經常使用方法你們只好自行百度了,我就不獻醜了!網站
騰訊滑塊驗證
此次搞得目標就是騰訊滑塊驗證碼,調用騰訊滑塊這個接口的網站仍是挺多的,好比很是好用的在線畫圖網站ProcessOn
,其中滑塊驗證部分相似這樣子的:ui
抓個包發現只有滑塊圖和帶缺口的圖,以下:
破解滑塊驗證碼最爲關鍵的地方在於找到滑塊缺口的位置
,找到缺口位置後就能夠利用Selenium
模擬拖動滑塊到指定位置實現破解,以前的老辦法就是將完整圖的像素點和帶缺口圖的像素點進行比較從而獲得缺口位置
,可是如今通常不會將完整圖暴露給咱們,因此只有在帶有缺口的圖上進行處理。我這裏一共有兩種方案進行缺口位置識別,一種是基於模板匹配
的,另外一種是基於輪廓檢測
的,下面會細講兩種方案的實現方法。spa
模板匹配識別缺口
具體是實現過程以下:
1.處理滑塊的圖片code
運行結果以下所示(左側爲原始滑塊,右側爲處理後的滑塊):cdn
2.處理帶缺口的圖片blog
運行結果以下所示(左側爲原始圖,右側爲處理後的圖):接口
3.進行模板匹配
調用模板匹配API並圈出匹配上的區域,結果以下所示:
警告警告警告
這種方法的缺口識別率在50%
左右,很大一部分緣由是滑塊圖的背景爲純白色,這在匹配時會產生很大的干擾,要是能將滑塊圖的背景變爲透明
,正確的匹配率能夠達到90%以上
若是你們有任何將滑塊圖的背景變爲透明的辦法,能夠留言到評論區,我真的萬分感謝!!!
下面是現階段的實現代碼:
# encoding:utf-8 import cv2 as cv import numpy as np # 對滑塊進行二值化處理 def handle_img1(image): kernel = np.ones((8, 8), np.uint8) # 去滑塊的前景噪聲內核 gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) width, heigth = gray.shape for h in range(heigth): for w in range(width): if gray[w, h] == 0: gray[w, h] = 96 # cv.imshow('gray', gray) binary = cv.inRange(gray, 96, 96) res = cv.morphologyEx(binary, cv.MORPH_OPEN, kernel) # 開運算去除白色噪點 # cv.imshow('res', res) return res # 模板匹配(用於尋找缺口有點偏差) def template_match(img_target, img_template): tpl = handle_img1(img_template) # 偏差來源就在於滑塊的背景圖爲白色 blurred = cv.GaussianBlur(img_target, (3, 3), 0) # 目標圖高斯濾波 gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY) ret, target = cv.threshold(gray, 127, 255, cv.THRESH_BINARY) # 目標圖二值化 # cv.imshow("template", tpl) # cv.imshow("target", target) method = cv.TM_CCOEFF_NORMED width, height = tpl.shape[:2] result = cv.matchTemplate(target, tpl, method) min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result) left_up = max_loc right_down = (left_up[0] + height, left_up[1] + width) cv.rectangle(img_target, left_up, right_down, (0, 0, 255), 2) cv.imshow('res', img_target) if __name__ == '__main__': img0 = cv.imread('./demo/3/hycdn_3.jpg') img1 = cv.imread('./demo/3/hycdn_3_2.png') template_match(img0, img1) cv.waitKey(0) cv.destroyAllWindows()
輪廓檢測識別缺口
基於輪廓檢測缺口的思路簡單不少,加上合理的條件識別率在95%
以上,實現過程以下:
(200,400)
的閾值作Canny邊緣檢測多個匹配結果以下:
實現代碼以下:
# encoding:utf-8 import cv2 as cv def get_pos(image): blurred = cv.GaussianBlur(image, (5, 5), 0) canny = cv.Canny(blurred, 200, 400) contours, hierarchy = cv.findContours(canny, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE) for i, contour in enumerate(contours): M = cv.moments(contour) if M['m00'] == 0: cx = cy = 0 else: cx, cy = M['m10'] / M['m00'], M['m01'] / M['m00'] if 6000 < cv.contourArea(contour) < 8000 and 370 < cv.arcLength(contour, True) < 390: if cx < 400: continue x, y, w, h = cv.boundingRect(contour) # 外接矩形 cv.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2) cv.imshow('image', image) return x return 0 if __name__ == '__main__': img0 = cv.imread('./demo/4/hycdn_4.jpg') get_pos(img0) cv.waitKey(0) cv.destroyAllWindows()
問題1
如何將滑塊圖的純白背景變爲透明背景?
問題2
使用Selenium
和軌跡算法拖動滑塊時將滑塊拖出左側的範圍以外,軌跡算法是先加速後減速總體是向前移動的,按道理來講不可能往回走,可是模擬拖動的時候會出現滑塊向後拖動且拖出範圍的現象,這問題如何解決?
有知道上述問題如何解決的小夥伴,期待你的留言或評論!!!