驗證碼識別之圖片處理(一些細節處理)

上一篇我們聊到了圖片驗證碼處理的基本流程,已經可以應付絕大多數圖片驗證碼了。

驗證碼識別之圖片處理(基礎流程)------ 鏈接戳這裏

我們來看一下成果:

可以看到應付我們的學習算法需求已經足夠。

今天我們來看看一些特殊圖片的處理方法:

1、帶邊框驗證碼:

例如:

這種處理方式比較顯而易見,循環遍歷時直接將

i<2 or i>rows-3 or j<2 or j>cols-3

的點置爲白色即可,代碼我就不上了。

 

2、背景色爲深色的驗證碼:

例如:

背景顏色比字母顏色深一些,閾值不好定。

這時我們需要獲取圖片背景色,處理依據:

一般背景色都爲圖片中顏色佔比最多,我們只要獲取出現最多的顏色,然後全部置爲白色即可。

即將其變爲:

後續就都一樣了:

python代碼如下:

# 獲取圖片中像素點數量最多的像素並置爲白色
def get_threshold(image):
    pixel_dict = defaultdict(int)

    # 像素及該像素出現次數的字典
    rows, cols = image.size
    for i in range(rows):
        for j in range(cols):
            pixel = image.getpixel((i, j))
            pixel_dict[pixel] += 1

    count_max = max(pixel_dict.values()) # 獲取像素出現出多的次數
    pixel_dict_reverse = {v:k for k,v in pixel_dict.items()}
    threshold = pixel_dict_reverse[count_max] # 獲取出現次數最多的像素點

    for i in range(rows):
        for j in range(cols):
            #剔除邊框
            if image.getpixel((i, j)) == threshold or i<2 or i>rows-3 or j<2 or j>cols-3:
                image.putpixel((i, j), (255, 255, 255, 255))
    return image

 

3、驗證碼中帶有粗粗的干擾線:

我們之前的干擾線處理方式依據爲:

干擾線一般相比較於字母來說比較細,在去除噪點的時候就將其一起去除了。

比如這種:

或者是這種(紅線是我自己畫的。。):

可以看出,我們可以分爲兩種類型:

        ①顏色和字母同色

        ②顏色不和字母同色

1、先看第一種,既然顏色,粗細都和字母差不多,也就是說我們無法從外形上直接區分出來,就算是人工來看,區分的依據也是和我們腦海中的字母一個個匹配,這時候我們只能寄希望於我們的學習算法了,這時候我們圖片處理能做的只能是提高圖片切割時候的閾值,來保證圖片的正確切割:

2、再看第二種,粗細和字母差不多,但是顏色則可以有明顯的區分,這時候我們明顯第一感覺就可以將其過濾掉,那同樣,我們的代碼中也是可以實現的。

我們看看干擾線的特點:

    ①顏色有明顯區分度;

    ②跨X軸很長;

所以我們的處理依據就出來了:

除背景色外,在X軸上投影上出現次數最多的即爲干擾線,將該顏色轉爲白色即可。

注意,這裏是在X軸投影上出現過的次數,而不是總次數。(統計X=N的線上出現的顏色,不管在這條線上出現了多少個,都算1次)

python代碼如下:

def clear_node_rgb(image):
    pixel_list = []
    rows, cols = image.size
    for i in range(rows):
        pixel_rgb = []
        for j in range(cols):
            rgb = image.getpixel((i, j))
            if rgb != (255,255,255) and rgb not in pixel_rgb:
                pixel_list.append(rgb)
                pixel_rgb.append(rgb)
    max_rgb = Counter(pixel_list).most_common(1)[0][0]

    for i in range(rows):
        for j in range(cols):
            pixel = image.getpixel((i, j))
            if pixel == max_rgb:
                image.putpixel((i, j), (255, 255, 255, 255))
    return image

這裏我們處理後的圖片都有一個很明顯的問題:被分割線擋住的部分斷掉了。

那追求完美的我們就需要想辦法去彌補一下了。

在opencv中有一對圖片處理的方法,叫做腐蝕和膨脹

腐蝕的意思爲將圖片上的內容邊界消除;

膨脹的意思爲將圖片上的內容邊界加粗。

舉個例子:

原圖:

膨脹後:

腐蝕後:

所以,先膨脹後腐蝕,就能消除圖片中的白點,斷層等等。

我們來看看效果:

先膨脹,消除斷層:

再腐蝕,回到原來的比例即可:

python代碼:

import cv2
import numpy as np


def ercode_dilate(img, threshold):
    #腐蝕參數, (threshold, threshold)爲腐蝕矩陣大小
    kernel = np.ones((threshold, threshold), np.uint8)

    # 膨脹圖片
    erosion = cv2.erode(img, kernel, iterations=1)

    # 腐蝕圖片
    eroded = cv2.dilate(erosion, kernel, iterations=1)

    return eroded

img = cv2.imread('test.png', 0)
ercode_dilate(img, 6)

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章