CV小白成长记之一:去除图片背景印记及噪点
-
問題描述(一):
運用圖像處理的方法去除上圖中背景黑色字印記。 -
問題的分析與解決(一):
拿到這個問題,作為一個圖像處理的小白,第一反應(yīng)是能不能像使用PS一樣,把這張RGB的圖片轉(zhuǎn)化為ARGB的圖片。接著,把其中背景的Alpha通道設(shè)置為0,即將背景設(shè)置為全透明,這樣便提取出了前景。然后,新建一個白色的畫布將前景放上去,就處理得到了一張背景純白的圖片。
轉(zhuǎn)念一想,如何將前景和背景區(qū)分出來才是關(guān)鍵,要不然就是對全圖調(diào)整透明度,無法達到預(yù)期效果。
我們知道,在圖像處理中,大多都使用灰度圖。在RGB模型中,假設(shè)R=G=B時,則彩色表示一種灰度顏色,當中R=G=B的值叫灰度值,因此,灰度圖像每一個像素僅僅需一個字節(jié)存放灰度值(又稱強度值、亮度值),灰度范圍為0-255。灰度是指只含亮度信息,不含色彩信息的圖像。黑白照片就是灰度圖,特點是亮度由暗到明,變化是連續(xù)的。要表示灰度圖,就需要把亮度值進行量化。之所以都使用灰度圖,是因為灰度圖有以下好處:
- RGB的值都一樣。
- 圖像數(shù)據(jù)即調(diào)色板索引值,就是實際的RGB值,也就是亮度值。
- 因為是256色調(diào)色板,所以圖像數(shù)據(jù)中一個字節(jié)代表一個像素,很整齊。
于是咱們首先把原圖轉(zhuǎn)化為灰度圖,使用以下代碼將原圖讀入MATLAB程序并進行灰度化:
同時,我們可以看一下灰度圖的直方圖,使用以下代碼輸出灰度圖及其直方圖:
figure,imshow(G) %窗口顯示灰度圖,如果前不加figure,那么后續(xù)只要出現(xiàn)imshow,那么將會覆蓋掉這個顯示灰度圖的窗口 figure,imhist(G) %窗口顯示直方圖灰度圖:
直方圖:
從直方圖中我們可以看出灰度值50至100之間有一個極小的峰值;而灰度值150至200之間有一個極大的峰值,一共有兩個峰值。這兩個分布分別代表前景和背景,我們的目標是找到一個閾值將前景和背景分開,這其實就是二值化的概念。
于是我突然想到可以使用最大類間方差法(Otsu)實現(xiàn)圖像二值化。該方法是圖像二值化處理常見方法之一,在Matlab與OpenCV中均有實現(xiàn)。Otsu Threshing方法是一種基于尋找合適閾值實現(xiàn)二值化的方法,其最重
要的部分是尋找圖像二值化閾值,然后根據(jù)閾值將圖像分為前景(白色,255)或者背景(黑色,0)。在Matlab中可以使用如下代碼利用Otsu法尋找合適閾值進行圖像二值化:
這時得到二值化后的圖像如下:
此時,我們已經(jīng)基本實現(xiàn)問題描述(一)中的要求,已經(jīng)去除了背景黑色字印記。本來可以收工了,但是強迫癥患者表示二值圖中還有黑色的噪點,于是還得繼續(xù)處理啊。
-
問題描述(二):
去除二值圖上的噪點(紅色橢圓圈出)。 -
問題的分析與解決(二):
首先,我們的目標是去除二值圖上的噪點,這些本來相對不明顯的噪點因為二值化而顯現(xiàn)為黑色。為了解決這個問題,我第一時間想到是膨脹、腐蝕這種形態(tài)學的方法。
原圖像進行膨脹和腐蝕運算后的效果為:膨脹運算可使圖像擴展,使其顆粒變大,線條變粗,孔和縫隙減小或消失;腐蝕運算可使圖像收縮,使其顆粒變小,線條變細,孔和縫隙增大。膨脹和腐蝕運算產(chǎn)生的效果為:根據(jù)膨脹運算的特性,膨脹運算可用于圖像暗細節(jié)的消除和亮區(qū)域邊緣的增強;根據(jù)腐蝕運算的特性,腐蝕運算可以用于圖像亮細節(jié)的消除和減弱亮區(qū)域邊緣。
開運算(先腐蝕再膨脹)和閉運算(先膨脹再腐蝕)產(chǎn)生的效果:(1)灰度開運算可消除比結(jié)構(gòu)元素尺寸小的亮細節(jié),(2)閉運算可消除比結(jié)構(gòu)元素小的暗細節(jié)。通常,用開運算來抑制正脈沖噪聲,消除圖像毛刺及孤立斑點,除去“l(fā)”噪聲(要比結(jié)構(gòu)元素小);閉運算則用來抑制負脈沖噪聲,填充圖像漏洞和裂縫,補充“0”噪聲(要比結(jié)構(gòu)元素小)。
由于上述對膨脹、腐蝕、開運算和閉運算能夠產(chǎn)生的效果的描述都是針對灰度值為255的高亮區(qū)域的,即對高亮部分的膨脹就是對黑色部分的腐蝕,對高亮部分的閉運算就是對黑色部分的開運算。于是,我認為對原二值圖像的膨脹或閉運算可能能消除掉這些黑色的噪點,于是使用代碼實驗如下:
對高亮部分進行膨脹(相當于腐蝕黑色部分):
對二值圖像做閉運算:
可以看出,不管是膨脹還是閉運算,黑色噪點得到了一定地消除,不過并不完全,有較大的噪點依舊保留下來,同時對需要保留下來的輪廓產(chǎn)生了一定程度的影響,不能達到理想效果。
正在我冥思苦想之時,我同學點撥了我。不管是膨脹還是腐蝕用來去噪,都只能處理相對較小的噪點。由于二值圖像中某些噪點不只有一個像素,所以不能完全去除干凈。可以使用連通域的方法,把黑色噪點當作一個連通域,通過找到一個閾值,去除低于閾值大小的連通域來去除噪點。于是通過查閱文獻,發(fā)現(xiàn)可以使用Matlab中的bwareaopen函數(shù)來去除連通域。
因為連通域操作,操作的連通域是白色部分,所以如果需要處理的圖中需要做連通域的部分是黑色的,就需要做一個灰色反轉(zhuǎn)。如果是灰度圖像: img = 255 - img; 如果是二值圖像: img = 1 - img。于是我們通過以下代碼把黑色噪點當作小的連通域進行去除。經(jīng)過試驗,我們選取set_noise閾值為24時效果對該二值圖效果最好。
bw = 1-bw; %灰度反轉(zhuǎn) img = bwareaopen(bw,24); %對bw圖像做連通域操作,去除那些像素數(shù)據(jù)小于24(set_noise)數(shù)目的連通域塊 img = 1-img; %灰度再反轉(zhuǎn)回來 figure,imshow(img)通過去除小的連通域(黑色噪點)得到處理后的最終圖片:
代碼如下:
總結(jié)
以上是生活随笔為你收集整理的CV小白成长记之一:去除图片背景印记及噪点的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android11文件管理权限申请
- 下一篇: 4.4.4求解迷宫问题