一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

第98天:圖像庫(kù) PIL 實(shí)例—驗(yàn)證碼去噪

 Python技術(shù) 2021-06-17

前面我們學(xué)習(xí)了 Python 的圖像處理庫(kù) PIL,學(xué)會(huì)了一些相關(guān)的圖像處理方法,好多人心里會(huì)問(wèn):有什么用呢?這一節(jié)我們就拿實(shí)際的例子來(lái)回答大家。

識(shí)別驗(yàn)證碼的原理

現(xiàn)在大多數(shù)網(wǎng)站登錄不再是簡(jiǎn)單地輸入用戶名密碼了,一般都伴隨著此二者之外的驗(yàn)證手段,目的是阻止一些居心不良的行為。而圖片驗(yàn)證碼是其中一種比較常用的手段。所謂道高一尺魔高一丈,在 IT 行業(yè)中,對(duì)于這種安全防守,肯定會(huì)有針對(duì)性地破解勢(shì)力。對(duì)于圖片驗(yàn)證碼的識(shí)別破解,目前已經(jīng)有了很多成熟的方法。我想大概是從自動(dòng)搶火車票興起之后快速發(fā)展而來(lái)的吧。

首先我們來(lái)看一張未處理的驗(yàn)證碼圖片:

想要識(shí)別驗(yàn)證碼,我們需要有一套圖片識(shí)別算法(這個(gè)目前已經(jīng)有成熟的應(yīng)用,大家可以自行搜索),然后拿到足夠多的樣本去喂養(yǎng)它,讓它不斷地自我學(xué)習(xí),不斷提升識(shí)別準(zhǔn)確率。在喂養(yǎng)算法之前,我們首先要做的就是對(duì)原始圖片進(jìn)行處理,一般包括的步驟是:

  • 將彩色圖片轉(zhuǎn)換成灰度圖
  • 將灰度圖二值化處理
  • 去除圖片噪點(diǎn)

經(jīng)過(guò)這三步處理之后,一般圖片的驗(yàn)證碼數(shù)字或者字母會(huì)比較明顯好辨別了。

下面我們以上面那張簡(jiǎn)單的驗(yàn)證碼圖片為例,來(lái)運(yùn)用 Python 的 PIL 庫(kù)的方法對(duì)圖片進(jìn)行去噪處理。

1. 彩色圖片轉(zhuǎn)換成灰度圖

什么事灰度圖呢?灰度圖,也可以認(rèn)為是黑白圖。我們知道彩色圖片是有不同的顏色的像素組合到一起的,灰度圖可以類似的認(rèn)為是由不同灰度值的像素組合在一起后呈現(xiàn)出來(lái)的。

任何顏色都有紅、綠、藍(lán)三原色組成,假如原來(lái)某點(diǎn)的顏色為 RGB(R,G,B),那么,我們可以通過(guò)下面幾種方法,將其轉(zhuǎn)換為灰度:

  • 1.浮點(diǎn)算法
Gray=R*0.3+G*0.59+B*0.11
  • 2.整數(shù)方法
Gray=(R*30+G*59+B*11)/100
  • 3.移位方法
Gray =(R*76+G*151+B*28)>>8
  • 4.平均值法
Gray=(R+G+B)/3
  • 5.僅取綠色
Gray=G

通過(guò)上述任一種方法求得Gray后,將原來(lái)的RGB(R,G,B)中的R,G,B統(tǒng)一用Gray替換,形成新的顏色RGB(Gray,Gray,Gray),用它替換原來(lái)的RGB(R,G,B)就是灰度圖了。

我們用代碼實(shí)現(xiàn)非常簡(jiǎn)單:

from PIL import Image
# 打開(kāi)原始圖片im = Image.open('vc.png')# 展示原始圖片im.show()
# 將原始圖片灰度化grey_im = im.convert('L')# 展示灰度化圖片grey_im.show()# 保存灰度化圖片grey_im.save('grey.png')

運(yùn)行上面代碼后,我們可以看到轉(zhuǎn)換后的灰度圖了,如下所示:

2. 將灰度圖片二值化

我們已經(jīng)得到了灰度圖,接下來(lái)就是將灰度圖二值化。所謂二值化就是將灰度圖像轉(zhuǎn)換成由黑白二色組成的圖像。思路就是確定一個(gè)閾值,大于閾值的像素表示為白色,小于閾值的像素表示為黑色,以此將圖片的像素(灰度值)劃分為兩部分:0和1,例如0代表黑色,1代表白色,然后我們就可以用一串0和1組成的數(shù)字來(lái)表示一張圖片。

from PIL import Image
# 二值處理# 設(shè)定閾值threshold,像素值小于閾值,取值0,像素值大于閾值,取值1# 閾值具體多少需要多次嘗試,不同閾值效果不一樣def get_table(threshold=115): table = [] for i in range(256): if i < threshold: table.append(0) else: table.append(1) return table
# 打開(kāi)灰度化圖片并進(jìn)行二值處理binary_im = Image.open('grey.png').point(get_table(120), "1")# 展示二值化圖片binary_im.show()# 保存二值化圖片binary_im.save('binary.png')

我們首先定義了一個(gè)二值處理的方法,該方法就是根據(jù)傳入的一個(gè)閾值,將0到256之間的數(shù)進(jìn)行分類,大于這個(gè)閾值取1,小于閾值取0。然后我們使用 Image 的 point 方法,該方法針對(duì)傳入的函數(shù)對(duì)每一個(gè)像素點(diǎn)進(jìn)行操作。我們傳入二值處理方法,對(duì)每個(gè)像素點(diǎn)進(jìn)行二值化處理,將圖片轉(zhuǎn)換成二值圖片。

這里的閾值是需要大家嘗試之后才能確定的,不同的圖片,在閾值不同時(shí)會(huì)出現(xiàn)不同的處理效果,大家需要用不同的閾值去處理,查看處理之后的效果圖,找到比較合理的閾值。本例中使用的是120。

經(jīng)過(guò)二值化處理之后,我們的圖片變成了下面這樣:

3. 對(duì)圖片進(jìn)行降噪處理

我們看二值化后的圖片,可以看到還有一些干擾線,這些線條也會(huì)影響算法的識(shí)別準(zhǔn)確率,所以我們需要想辦法去掉這些干擾線。

降噪的方法有很多,主要難點(diǎn)是判斷哪些點(diǎn)是噪點(diǎn)。由于我們這張驗(yàn)證碼圖片上的數(shù)字和字母的線條比干擾線的線條粗,因此我們認(rèn)為字母和數(shù)字線條上的點(diǎn)周圍8個(gè)點(diǎn)范圍內(nèi)黑色點(diǎn)的個(gè)數(shù)應(yīng)該比干擾線上的點(diǎn)要多。因此我們這里采用的思路是:

根據(jù)一個(gè)點(diǎn) A 的 RGB 值,與周圍的8個(gè)點(diǎn)的 RBG 值比較,設(shè)定一個(gè)值 N(0 <N <8),當(dāng) A 的 RGB 值與周圍8個(gè)點(diǎn)的 RGB 相等數(shù)小于 N 時(shí),此點(diǎn)為噪點(diǎn)。

對(duì)應(yīng)的程序代碼為:

from PIL import Image, ImageDraw

# 判斷噪點(diǎn),如果確認(rèn)是噪點(diǎn),用該點(diǎn)的上面一個(gè)點(diǎn)的灰度進(jìn)行替換# 根據(jù)一個(gè)點(diǎn)A的RGB值,與周圍的8個(gè)點(diǎn)的RBG值比較,設(shè)定一個(gè)值 N(0 <N <8),當(dāng)A的RGB值與周圍8個(gè)點(diǎn)的RGB相等數(shù)小于N時(shí),此點(diǎn)為噪點(diǎn)# x, y: 像素點(diǎn)坐標(biāo)# G: 圖像二值化閥值# N: 降噪率 0 < N <8def get_pixel(image, x, y, G, N): # 獲取像素值 L = image.getpixel((x, y))
# 與閾值比較 if L > G: L = True else: L = False
nearDots = 0
if L == (image.getpixel((x - 1, y - 1)) > G): nearDots += 1 if L == (image.getpixel((x - 1, y)) > G): nearDots += 1 if L == (image.getpixel((x - 1, y + 1)) > G): nearDots += 1 if L == (image.getpixel((x, y - 1)) > G): nearDots += 1 if L == (image.getpixel((x, y + 1)) > G): nearDots += 1 if L == (image.getpixel((x + 1, y - 1)) > G): nearDots += 1 if L == (image.getpixel((x + 1, y)) > G): nearDots += 1 if L == (image.getpixel((x + 1, y + 1)) > G): nearDots += 1
if nearDots < N: return image.getpixel((x, y - 1)) else: return None

# 降噪# Z: 降噪次數(shù)def clear_noise(image, G, N, Z): draw = ImageDraw.Draw(image)
for i in range(0, Z): for x in range(1, image.size[0] - 1): for y in range(1, image.size[1] - 1): color = get_pixel(image, x, y, G, N) if color is not None: draw.point((x, y), color)
# 打開(kāi)二值化圖片b_im = Image.open('binary.png')# 將二值化圖片降噪clear_noise(b_im, 50, 4, 4)# 展示降噪后的圖片b_im.show()# 保存降噪后的圖片b_im.save('result.png')

在本例中,我們?cè)O(shè)置的二值化閾值為50,降噪率為4,降噪次數(shù)為4.這幾個(gè)參數(shù)也是不同的圖片會(huì)有不同的值,大家需要根據(jù)不同的圖片自行設(shè)定。

降噪后的圖片效果如下:

我們可以看到,經(jīng)過(guò)上面的處理之后,圖片上的字母和數(shù)字已經(jīng)很清晰了,再使用圖片識(shí)別算法,準(zhǔn)確率應(yīng)該會(huì)很高。

除了上面的步驟,我們還可以通過(guò) PIL 庫(kù)的 ImageEnhance 和 ImageFilter 對(duì)圖片做其他處理,例如增加對(duì)比度、亮度、銳化等,最終的目的都是去除圖片的噪點(diǎn),是圖片更容易辨別。大家如果感興趣的話可以試試看。

總結(jié)

本節(jié)我們通過(guò)使用 PIL 庫(kù)的一些簡(jiǎn)單方法,對(duì)驗(yàn)證碼圖片進(jìn)行一系列的處理,從而達(dá)到降噪的目標(biāo)。通過(guò)本節(jié)的學(xué)習(xí),大家應(yīng)該要學(xué)會(huì)學(xué)以致用,運(yùn)用我們學(xué)習(xí)的一些理論知識(shí)去解決工作或生活中遇到的實(shí)際問(wèn)題。PIL 庫(kù)還有很多其他的方法都可以用來(lái)對(duì)圖片進(jìn)行不同的處理,大家可以自己去探索。

文中示例代碼:https://github.com/JustDoPython/python-100-day/tree/master/day-098

參考

https://www./pillow/reference/

系列文章

第97天:圖像庫(kù) PIL(二)
第96天:圖像庫(kù) PIL(一)
第95天:StringIO & BytesIO
第94天:數(shù)據(jù)分析之 pandas 初步
第93天:文件讀寫
第92天:Python Matplotlib 進(jìn)階操作
第91天:Python matplotlib introduction
從 0 學(xué)習(xí) Python 0 - 90 大合集總結(jié)

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    亚洲一区二区三区在线中文字幕 | 精品欧美国产一二三区| 精品少妇一区二区视频| 高清不卡一卡二卡区在线| 国产又粗又长又爽又猛的视频| 欧美黑人在线一区二区| 日本午夜一本久久久综合| 美国黑人一级黄色大片| 亚洲精品福利视频在线观看| 欧美国产精品区一区二区三区| 成人精品亚洲欧美日韩| 欧美亚洲另类久久久精品| 一区二区在线激情视频| 中文久久乱码一区二区| 亚洲男人的天堂久久a| 少妇肥臀一区二区三区| 日韩欧美精品一区二区三区| 亚洲高清中文字幕一区二三区| 色哟哟哟在线观看视频| 国产精品涩涩成人一区二区三区| 加勒比系列一区二区在线观看| 国内九一激情白浆发布| 国产精品白丝久久av| 日本精品理论在线观看| 麻豆视传媒短视频在线看| 亚洲国产精品久久综合网| 最好看的人妻中文字幕| 99亚洲综合精品成人网色播| 一区二区三区日韩中文| 国产成人免费高潮激情电| 老司机精品国产在线视频| 欧美国产极品一区二区| 国产精品亚洲二区三区| 五月天婷亚洲天婷综合网| 亚洲人妻av中文字幕| 男女一进一出午夜视频| 欧美黑人在线一区二区| 福利新区一区二区人口| 亚洲在线观看福利视频| 国产一区二区三区丝袜不卡| 国内自拍偷拍福利视频|