簡單驗證碼的轉灰度、二值化、切割

灰度化:在RGB模型中,如果R=G=B時,則彩色表示一種灰度顏色,其中R=G=B的值叫做灰度值,因此,灰度圖像每個像素值只需一個字節存放灰度值(又稱強度值、亮度值),灰度範圍爲0-255。
二值化:二值化可以把灰度圖片轉換成二值圖像,把大於某個臨界灰度值的像素灰度設置爲灰度極大值,把小於這個值的像素灰度設爲灰度極小值,從而實現二值化。

原始圖
原始圖
灰度圖
灰度圖
二值化後的圖
二值化後的圖
我們可以看到對於這張驗證碼效果還不錯,接下來我們用代碼實現。
首先我們進行圖片轉灰度並二值化

def GrayscaleAndBinarization(image):
    '''
    灰度並二值化圖片,初步二值化後,會存在一些噪聲點,我們使用這樣一個方法進行去除(不能實現完全去除),
    即當圖片中存在一個點灰度值爲0,但其周圍九宮格中像素點的灰度值均爲255時,我們認爲這個點爲孤立點,將其
    灰度改爲255
    :param image: 處理前的圖片
    :return:處理後的圖片
    '''
    threshold = 17  # 需要自己調節閾值

    tmp_image = image.convert('L')  # 灰度化
    new_image = Image.new('L', tmp_image.size, 0)

    # 初步二值化
    for i in range(tmp_image.size[1]):
        for j in range(tmp_image.size[0]):
            if tmp_image.getpixel((j, i)) > threshold:
                new_image.putpixel((j, i), 255)
            else:
                new_image.putpixel((j, i), 0)

    # new_image.show()    # 去噪前

    # 去噪,去除獨立點,將前後左右等九宮格中灰度通道值均爲255的像素點的通道值設爲255
    for i in range(1, new_image.size[1] - 1):
        for j in range(1, new_image.size[0] - 1):
            if new_image.getpixel((j, i)) == 0 and new_image.getpixel((j - 1, i)) == 255 and new_image.getpixel((j + 1, i)) == 255 and \
                    new_image.getpixel((j, i - 1)) == 255 and new_image.getpixel((j - 1, i - 1)) == 255 and new_image.getpixel((j + 1, i - 1)) == 255 and\
                new_image.getpixel((j, i + 1)) == 255 and new_image.getpixel((j - 1, i + 1)) == 255 and new_image.getpixel((j + 1, i + 1)) == 255:
                new_image.putpixel((j, i), 255)
    # new_image.show()    # 去噪後

    return new_image

接下來我們找到圖片切割點並對圖片進行切割,對於這種驗證碼,我們進行簡單的垂直切割。首先,我們找到需要進行切割的位置。

def SplitImage(image):
    '''
    切割圖像並保存,關鍵在於尋找切割位置
    :param image: 待切割的圖片
    :return: 無
    '''
    splitSite = []	# 記錄切割的位置
    splitSite.append(0)
    new_image = image

    tmp_list = [0 for i in range(image.size[0])]
    for i in range(image.size[0]):
        for j in range(image.size[1]):
            if image.getpixel((i, j)) == 0:
                tmp_list[i] = 1
                break

    # print(tmp_list)
    for index in range(0, len(tmp_list) - 1):
        if tmp_list[index] == 1 and tmp_list[index + 1] == 0:
            splitSite.append(index + 1)

    plt.imshow(image)
    for item in splitSite[1:]:
        plt.plot([item for i in range(image.size[1])], [i for i in range(image.size[1])])
    plt.show()	# 使用 matplotlib 模塊進行預覽切割效果
    splitSite.append(image.size[0])

    # 對圖片進行切割
    for index in range(1, len(splitSite) - 1):
        box = (splitSite[index - 1], 0, splitSite[index], image.size[1])	# box中四個參數,分別爲距離圖片左側、上側、右側、下側的像素距離
        new_image = image.crop(box)
        new_image.save('./{}.gif'.format(str(index)))	# 保存切割後的圖片,位置在當前目錄

切割後效果圖

  1. 第一個字母
    原始圖
  2. 第二個字母
    原始圖
  3. 第三個字母
    原始圖
  4. 第四個字母
    原始圖
    源碼:https://github.com/kingdowliu/ImageProcessing
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章