文章目錄
- 1. 寫在前面
- 2. 讀取驗證碼圖像
- 3. 生成顏色掩碼
- 4. 生成黑白結果圖
- 5. OCR文字識別
- 6. 測試結果
【作者主頁】:吳秋霖
【作者介紹】:Python領域優質創作者、阿里云博客專家、華為云享專家。長期致力于Python與爬蟲領域研究與開發工作!
【作者推薦】:對JS逆向感興趣的朋友可以關注《爬蟲JS逆向實戰》,對分布式爬蟲平臺感興趣的朋友可以關注《分布式爬蟲平臺搭建與開發實戰》
還有未來會持續更新的驗證碼突防、APP逆向、Python領域等一系列文章
1. 寫在前面
??今天給大家帶來一個爬蟲領域過花式驗證碼小技巧,這是最近來源于一位鐵子的分享,驗證碼是下面這樣的(可以看到附帶了某些條件,比如說輸入特定顏色的字符):
在此之前我專門去開源社區找了找一些成熟的解決方案,確實有多種花式處理的方案,相比于自己去收集樣本,訓練一個識別模型,其中數據樣本的標注是比較耗時的,想要保持較高的準確率,這是一件持續的事情,因為你需要讓你的模型有能夠適應更新帶來的對抗。又或者是打碼平臺的低效率,這次分享的方式更加實用:
話不多說,核心代碼其實也就幾十行,輕輕松松識別上面類型的驗證碼,代碼的核心思想就下面四步:
1、顏色空間轉換
2、根據HSV顏色閾值生成掩碼
3、生成黑白結果圖
4、OCR文字內容識別
通俗點講就是剔除與需提取顏色無關的內容,最后識別!
HSV顏色閾值參考如下(具體自己可以調節):
2. 讀取驗證碼圖像
??首先將事先準備好的驗證碼圖片,然后通過程序讀取圖片,代碼如下:
def read_image(image_path):img = cv2.imread(image_path)if img is None:raise ValueError(f"讀取圖片失敗: {image_path}")return img
3. 生成顏色掩碼
??HSV(色調、飽和度、亮度)顏色空間是一種表示顏色空間的模型,類似于 RGB 顏色模型
我們可以根據上面HSV范圍的閾值范圍,使用cv2.inRange函數生成二值掩碼。掩碼中的目標顏色對應的區域被設為白色(255),其他顏色對應的區域被設為黑色(0)
def apply_color_mask(hsv, lower, upper):return cv2.inRange(hsv, np.array(lower), np.array(upper))
4. 生成黑白結果圖
??生成黑白結果圖的目的就是將指定顏色的內容從原始圖像中提取出來,以便進行后續的OCR文字識別。在驗證碼的應用場景中,驗證碼可能包含多個顏色,而我們只對其中某一種顏色感興趣。通過生成黑白結果圖,我們可以將感興趣的顏色保留下來,而將其他顏色置為白色,從而突出需要識別的內容,代碼如下:
def generate_result_image(img, mask, result_path):result = np.zeros_like(img)result[mask == 255] = [0, 0, 0]result[mask != 255] = [255, 255, 255]cv2.imwrite(result_path, result)
這是驗證碼圖片處理完生成黑白圖的效果:
5. OCR文字識別
??最后借助OCR對黑白結果圖進行識別,基本上成功率在90%以上,基本夠用,識別代碼如下:
def ocr_classification(image_path):try:with open(image_path, 'rb') as f:img_bytes = f.read()ocr = ddddocr.DdddOcr(show_ad=False)return ocr.classification(img_bytes)except Exception as e:raise ValueError(f"OCR識別出錯: {e}")def verification_ocr(image_path, tips):"""驗證碼識別主函數Args:image_path: 圖像文件路徑tips: 識別提示, 包括"紅色"、"黃色"、"藍色"、"全部"Returns:result: OCR識別結果"""result_path = "1.png"img = read_image(image_path)hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)color_ranges = {"紅色": ([0, 50, 50], [10, 255, 255], [170, 50, 50], [180, 255, 255]),"黃色": ([17, 45, 50], [34, 255, 255]),"藍色": ([100, 50, 50], [130, 255, 255]),}if tips in color_ranges:ranges = color_ranges[tips]mask = apply_color_mask(hsv, *ranges[:3])if tips == "紅色":mask2 = apply_color_mask(hsv, *ranges[2:])mask = cv2.bitwise_or(mask, mask2)generate_result_image(img, mask, result_path)with open(result_path, 'rb') as f:img_bytes = f.read()ocr = ddddocr.DdddOcr(show_ad=False)res = ocr.classification(img_bytes)#輸出識別內容print(res)
tips參數代表傳入的顏色,并根據顏色去選擇閾值
cv2.cvtColor(img, cv2.COLOR_BGR2HSV)將圖像從BGR色彩空間轉換為HSV色彩空間。HSV(色調、飽和度、明度)通常更適合基于顏色的圖像處理
ddddocr這個庫自然不用多說了,很好用。可以滿足很對場景下的使用需求,開源的力量!
6. 測試結果
如果你只是為了解決這類驗證碼識別為目的,那么這個方案完全是夠用的!最后,其實還是建議大家體驗一下自己訓練樣本的過程,打造一個高質量的model
??好了,到這里又到了跟大家說再見的時候了。創作不易,幫忙點個贊再走吧。你的支持是我創作的動力,希望能帶給大家更多優質的文章