OpenCV入門之獲取驗證碼的單個字符(字符切割)


介紹

  在我們日常上網注冊賬號以及制作網絡爬蟲時,經常會遇到奇奇怪怪的驗證碼,有些容易,有些連人眼都無法辨識。於是,大牛們想到了用深度學習的方法來破解驗證碼,對於一般的驗證碼往往能出奇制勝,取得不俗的識別效果。對於利用深度學習方法識別驗證碼,其預處理就是獲取驗證碼中的單個字符,即字符切割。
  本文將通過一個簡單的驗證碼例子,來展示如何利用OpenCV來獲取單個字符。

手把手教學

  我們所使用的示例驗證碼如下:

驗證碼例子
驗證碼例子

  首先我們在OpenCV中以灰度模式讀取圖片(imagepath為圖片所在的絕對路徑),

    gray = cv2.imread(imagepath, 0)

處理后的圖片如下:

灰度模式
灰度模式

  接着我們把該驗證碼的邊緣設置為白色(255代表白色),

    # 將圖片的邊緣變為白色
    height, width = gray.shape
    for i in range(width):
        gray[0, i] = 255
        gray[height-1, i] = 255
    for j in range(height):
        gray[j, 0] = 255
        gray[j, width-1] = 255

處理后的圖片效果如下:

去掉邊緣
去掉邊緣

可以看到,處理后的圖片的邊緣部分已經置為白色了。
  接着我們需要對圖像進行濾波處理,圖像濾波的主要目的是為了在保留圖像細節的情況下盡量的對圖像的噪聲進行消除,從而是后來的圖像處理變得更加的方便。我們在這里采用中值濾波(median blur)的方法來實現,取孔徑大小為3,

    blur = cv2.medianBlur(gray, 3#模板大小3*3

處理后的圖片效果如下:

中值濾波后的圖片
中值濾波后的圖片

  接着我們需要對圖像進行二值化處理,即將圖像由灰度模式轉化至黑白模式,當然閾值的選擇很重要,在這里我們選擇二值化的閾值為200,

    ret,thresh1 = cv2.threshold(blur, 200255, cv2.THRESH_BINARY)

二值化的圖片效果如下:

圖片二值化處理
圖片二值化處理

  最后我們需要在二值化處理后的圖片中提取單個字符,主要利用OpenCV中的最小外接矩形函數來提取,代碼如下:

    image, contours, hierarchy = cv2.findContours(thresh1, 22)

    flag = 1
    for cnt in contours:
        # 最小的外接矩形
        x, y, w, h = cv2.boundingRect(cnt)
        if x != 0 and y != 0 and w*h >= 100:
            print((x,y,w,h))
            # 顯示圖片
            cv2.imwrite('E://char%s.jpg'%flag, thresh1[y:y+h, x:x+w])
            flag += 1

需要注意的是,對提取后的字符圖片有一定要求,比如x,y的值不能為0以及圖片的大小要超過100,不然我們會得到其他的不想要的圖片。提取單個字符后的圖片如下:

提取的單個字符
提取的單個字符

提取的效果還是不錯的。

總結

  本文主要通過一個簡單的驗證碼例子,逐步展示了如何利用OpenCV來獲取單個字符,這些都是圖像處理的基本技巧。怎么樣,這個技能你是否get了呢?
  歡迎大家交流,也祝大家中秋節快樂~~

  最后附上本次操作的Python代碼,供大家參考。

import cv2

def split_picture(imagepath):

    # 以灰度模式讀取圖片
    gray = cv2.imread(imagepath, 0)

    # 將圖片的邊緣變為白色
    height, width = gray.shape
    for i in range(width):
        gray[0, i] = 255
        gray[height-1, i] = 255
    for j in range(height):
        gray[j, 0] = 255
        gray[j, width-1] = 255

    # 中值濾波
    blur = cv2.medianBlur(gray, 3#模板大小3*3
    #print(blur)

    # 二值化
    ret,thresh1 = cv2.threshold(blur, 200255, cv2.THRESH_BINARY)
    #print(thresh1)

    image, contours, hierarchy = cv2.findContours(thresh1, 22)

    flag = 1
    for cnt in contours:
        # 最小的外接矩形
        x, y, w, h = cv2.boundingRect(cnt)
        if x != 0 and y != 0 and w*h >= 100:
            print((x,y,w,h))
            # 顯示圖片
            cv2.imwrite('E://char%s.jpg'%flag, thresh1[y:y+h, x:x+w])
            flag += 1

def main():
    imagepath = 'E://VerifyCode.jpg'
    split_picture(imagepath)

main()

注意:本人現已開通微信公眾號: 輕松學會Python爬蟲(微信號為:easy_web_scrape), 歡迎大家關注哦~~


免責聲明!

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



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