喻浩,吳豐林
(電子科技大學(xué)成都學(xué)院 智能制造工程系,四川成都, 611731)
在日新月異的當(dāng)代社會,經(jīng)濟和科技的快速發(fā)展使得人們的物質(zhì)文化生活也越來越多元化。為了使得后來者也能見證某一特定的時間節(jié)點或保留某一美好的場景,人們常會通過拍照的方式將場景以圖片的形式進行保留。然而在日常生活中,人們常常會遇到對同一運動的物體進行快速多次拍攝取證后,產(chǎn)生模糊無效圖片的情況。若選擇后期以人工方式挑選時,則需要花費大量時間和精力對相關(guān)圖片進行逐一比對,不利于以人為本的發(fā)展思想的體現(xiàn)和勞動效率的提升。因此,隨著現(xiàn)代科學(xué)技術(shù)的快速發(fā)展,我們也應(yīng)該不斷用探索用新的方式來解決日常生活以及工作應(yīng)用中的此類繁瑣、單一、重復(fù)性的工作,從而提高工作效率和解放生產(chǎn)力。
通過查閱資料可知,當(dāng)前國內(nèi)外針對模糊圖像的識別處理方法主要存在以下缺點:(1)算法僅針對某一特定圖片進行模糊與否的判斷,不能批量識別并處理模糊圖片。當(dāng)需要對其他圖片進行識別處理時,需要更改算法或者手動控制更換圖片;(2)利用圖像分割算法,建立由多尺度輸入的U形網(wǎng)絡(luò)和一組多尺度特征提取器構(gòu)建的模型檢測和判定模糊圖像[1]。該方法識別較為準(zhǔn)確但是構(gòu)建模型過程復(fù)雜且難度較高,不利于推廣;(3)先對模糊圖片進行濾波等清晰化處理,再將處理后的圖片加以利用。該方案也僅能對單一圖像進行處理,不具有批量處理圖片的能力。且在不斷迭代的眾多算法中,哪一種算法更能行之有效地解決實際問題,還需要在更多的實際案例中不斷地進行檢驗,發(fā)現(xiàn)問題并加以優(yōu)化。針對以上問題,本算法設(shè)計采用拉普拉斯算子對圖像進行模糊度判別,通過Python語言編寫批量識別處理模糊圖片的算法邏輯,從而達到本算法的設(shè)計目的。
區(qū)分清晰圖片和模糊圖片的基本思想為:圖像中各線條之間的邊緣不明確,且圖像中邊緣模糊的部分占圖片大部分,有小部分線條模糊的圖片不能判定為模糊圖片。因此,在機器學(xué)習(xí)領(lǐng)域可以通過拉普拉斯算法來檢測圖片是否模糊。即利用拉普拉斯算法在輸入圖片中查找圖像邊緣[2],計算圖像方差和已過濾圖像像素值的最大值。方差值大表明圖像邊緣清晰可見,即可判定為圖像清晰;若圖像方差值小則判定為圖像模糊。批量處理圖像的基本思想為:通過讀取目標(biāo)文件夾預(yù)存圖片信息過程中保留圖片張數(shù)信息,以便算法進行和圖片張數(shù)相同次數(shù)的循環(huán)處理,從而達到遍歷所有圖片的目的。同時,在圖片遍歷過程中調(diào)用拉普拉斯算法計算圖片方差值,用于與閾值進行比較,達到清晰與模糊的判別目的。再通過自主編寫的功能函數(shù)doWork()進行相應(yīng)的標(biāo)記處理,以此達到批量處理的目的。為了給使用者更加直觀便捷地了解處理結(jié)果,特采用matplotlib.pyplot繪制可視化界面[3],將處理后的圖片以cv2.imwrite()函數(shù)另存文件夾的同時以彈窗形式進行集中展示。為了便于調(diào)試和檢驗該算法設(shè)計是否有效,本次驗證過程僅使用對運動的同一物體快速抓拍后的12張圖片進行調(diào)試和驗證處理。后續(xù)實際應(yīng)用過程中若想批量處理更多的圖片,即在目標(biāo)圖像庫添加預(yù)處理目標(biāo)圖像即可。
拉普拉斯算法又稱為拉普拉斯梯度函數(shù)。理解梯度函數(shù)需要理解梯度的作用:梯度表示某一個函數(shù)在某一點的方向?qū)?shù)沿著該點方向的最大值,即函數(shù)在該點沿著該方向變化速度最快,變化率最大。本次設(shè)計過程即調(diào)用 OpenCV庫內(nèi)置的拉普拉斯函數(shù)計算圖片的方差值,再在后續(xù)處理過程中判定圖片是否模糊[4]。該算法的主要思想為:先將圖像轉(zhuǎn)換為灰度圖像,然后單一通道的灰度圖像經(jīng)過剛才計算出來的拉普拉斯 3×3 卷積核計算后會得到一個響應(yīng)圖,最后再計算這個響應(yīng)圖的方差?;谠摲讲詈皖A(yù)先經(jīng)過調(diào)試設(shè)定的閾值進行比較,就可以判斷圖像是否模糊,也即是通過圖像灰度數(shù)據(jù)的方差來衡量圖像的清晰度。對于同一對象的一組圖片,可以采用同一個閾值進行判定;不同的對象、不同環(huán)境下拍攝的圖片可能需要根據(jù)實際情況相應(yīng)的調(diào)整閾值。拉普拉斯梯度函數(shù)與使用Tenengrad梯度方法計算圖像梯度值的使用方式基本一致,Tenengrad梯度方法為利用Sobel算子分別計算水平和垂直方向的梯度,若圖像在同一背景條件下的梯度值越高,表明圖像越清晰。即衡量的指標(biāo)是經(jīng)過Sobel算子處理后的圖像的平均灰度值,值越大代表圖像越清晰。在使用時可直接用拉普拉斯梯度函數(shù)替代Sobel算子[5]。在圖像處理的應(yīng)用方面,因平面圖像可以視為x和y兩個方向的像素點聚集排列而成且是離散分布的,所以需要將拉普拉斯算子方程表示為其在x,y兩個方向的離散形式。
其離散一階微分方程為:
其離散二階微分方程為:
拉普拉斯算子的離散方程為:
轉(zhuǎn)換為卷積核表示如下:
而基于拉普拉斯梯度函數(shù)的圖像清晰度的定義如下所示:
其中G(x,y)是像素點(x,y)處拉普拉斯算法的卷積,T是預(yù)先給定的邊緣檢測閾值。
Matplotlib是Python的一個繪圖庫,是Python語言中最常用的可視化工具之一,可以非常方便地創(chuàng)建2D圖表和一些簡單的3D圖表[6]。且能夠以各種硬復(fù)制格式和跨平臺的交互式環(huán)境生成出版質(zhì)量級別的圖形[7]。在通過Matplotlib進行繪圖操作時,使用者可以僅依靠編寫幾行代碼便可以生成所需要的條形圖、餅圖、功率譜、直方圖、散點圖等。同時,它還提供了一套和Matlab類似的命令A(yù)PI,十分適合交互式地進行制圖,而且也可以方便地將它作為繪圖控件,嵌入GUI應(yīng)用程序中[8]。本次算法設(shè)計即利用Matplotlib中plt工具繪制可視化界面,將處理結(jié)果以彈窗形式展示出來。涉及的函數(shù)簡介如圖1所示。
圖1 plt函數(shù)介紹
圖片的遍歷邏輯通過Python語言構(gòu)建,該過程在自主編寫的功能函數(shù)matplotlib_multi_pic1()中實現(xiàn)。通過cv2.imread()函數(shù)讀取圖片,其形參images的值由(Pathimages+'/'+imgList[i])得 到。Pathimages為 圖 片庫的絕對路徑,通過主動賦值得到。imgList[i]的值通過os.listdir(path)函數(shù)賦值得到。os.listdir(path)函數(shù)作用是得到指定路徑下所有文件和文件夾的名字,并可將其存放于列表中,以此便得到了圖片命名信息。通過len(imgList)即可得到圖片數(shù)量,借助該數(shù)值進行相應(yīng)次數(shù)的For循環(huán),即可完成圖片庫的遍歷過程。
(1)對圖片信息進行采集。該過程是利用os.listdir()函數(shù)讀取圖片相關(guān)路徑信息并賦值給自定義變量imgList。變量imgList其作用是以形參的形式為自定義函數(shù)matplotlib_multi_pic1()提供圖片參數(shù)信息,使該函數(shù)在對圖片進行批量處理過程得到圖片參數(shù)信息,以使得處理后的圖片在另存文件夾時能保留原文件命名方式和利用len(imgList)語句得到圖片數(shù)量,以便于進行相應(yīng)次數(shù)的圖片遍歷。
(2)通過PathImage = r'image/'語句得到目標(biāo)圖片庫的絕對路徑,其作用是為函數(shù)matplotlib_multi_pic1()提供形參的值,以便于doWork()函數(shù)對某一具體圖片進行相應(yīng)處理。
(3)調(diào)用matplotlib_multi_pic1()函數(shù)。其具體流程及作用為:該函數(shù)有形參imgList和PathImage,在該函數(shù)中,imgList提供的值用于得到遍歷次數(shù)和為圖片提供命名信息;PathImage提供圖片絕對路徑,以便于doWork()函數(shù)讀取并處理具體的圖片。同時在該函數(shù)中設(shè)置for循環(huán)對圖片進行遍歷。
(4)調(diào)用自定義的doWork()函數(shù)。該函數(shù)的具體流程及作用為:讀取圖片并將其轉(zhuǎn)換為灰度圖,將灰度圖傳遞至variance_of_laplacian()函數(shù)中,使用OpenCV庫自帶的函數(shù)cv2.Laplacian()進行拉普拉斯方差值計算,得到圖片具體的方差值。將得到的方差值與模糊閾值相比較判斷其是否為模糊圖片,若方差值大于閾值則可判定其清晰并標(biāo)記為“Not Blurry”,小于閾值則可判定為模糊圖片并標(biāo)記為“Blurry”,最后返回處理完成的圖片。其中,標(biāo)記文字的過程利用cv2.FONT_HERSHEY_SIMPLEX命令實現(xiàn),利用cv2.putText()函數(shù)對圖片進行處理結(jié)果展示。
整個算法實現(xiàn)即為各個函數(shù)互相調(diào)用的結(jié)果,程序運行過程如圖2所示。
圖2 程序運行流程圖
當(dāng)用戶在圖像目標(biāo)庫image文件夾中存入需要批量檢測的圖像源文件后,即可直接運行該算法進行模糊圖像批量檢測處理的任務(wù)。目標(biāo)圖像庫預(yù)留文件方式如圖3所示。
圖3 目標(biāo)圖像庫
在該算法運行完成后,即主動彈出可視化彈窗供用戶可在不打開圖像處理后另存文件夾User的條件下,直接對檢測處理完成的結(jié)果進行比對,以便呈現(xiàn)出更加直觀的處理效果。在彈出的效果圖中每一塊小區(qū)域的圖片左上角均標(biāo)記有相應(yīng)圖片通過拉普拉斯算法計算出的圖像方差的具體值,如果該值大于預(yù)先設(shè)定的閾值80就會標(biāo)記 NotBlurry和計算出的,如果小于80 就會顯示 Blurry和圖像具體方差值。這樣就能夠非常直觀地看到所有圖片經(jīng)過拉普拉斯算法計算得到的具體方差值和設(shè)定的比較標(biāo)準(zhǔn)之間的信息,由此方便后續(xù)數(shù)據(jù)的進一步處理和使用??梢暬瘡棿靶Ч鐖D4所示。
圖4 可視化彈窗效果
通過Python編寫語言邏輯,可以使得算法在處理單張圖片過程完成后即主動向User文件夾存放處理完成的圖片的功能循環(huán)。處理完成后的圖片左上角均標(biāo)記有該圖像是否模糊以及圖像方差值具體參數(shù)。根據(jù)實際應(yīng)用需要,也可以通過修改Python語言邏輯實現(xiàn)僅對判別出的模糊圖片進行標(biāo)記處理,清晰圖片僅識別而不標(biāo)記的功能,從而達到保護清晰圖像的目的。修改方法簡單,將清晰圖片對應(yīng)的閾值比較語句下實現(xiàn)標(biāo)記內(nèi)容的文本text和圖像方差值fm屏蔽即可,即不對圖像方差值高于閾值的圖片進行標(biāo)記處理。為了更好地驗證算法處理結(jié)果是否準(zhǔn)確,在本次算法驗證過程中采用全部標(biāo)記處理的方式驗證最終結(jié)果。圖像批量處理后得到的文件夾User如圖5所示。
圖5 圖像批量處理后得到的文件夾
為了更好地展示本算法的圖片分辨及標(biāo)記處理效果,特單獨拿出處理后的模糊圖像和清晰圖像各一張進行對比。通過對比可以發(fā)現(xiàn),清晰的圖像方差值高,模糊的圖像方差值低,且標(biāo)記無誤。圖像對比如圖6所示。
圖6 圖像對比
本文設(shè)計并實現(xiàn)了基于拉普拉斯算子的模糊圖片批量檢測算法。經(jīng)過實際應(yīng)用檢驗,表明該算法設(shè)計在批量處理圖片過程中具有算法運行速度快、模糊與清晰圖片判別準(zhǔn)確且自動另存處理后的圖像命名無誤等特點。不過該算法也還有一定的不足,即還未能實現(xiàn)將標(biāo)記處理完成后的模糊與清晰的圖片自動分類存放[9]的功能。后期若能對該算法進行更進一步的優(yōu)化,則可考慮如何設(shè)計更加優(yōu)良的算法邏輯以實現(xiàn)該功能。不過,就目前該算法批量識別并處理模糊圖片的能力而言,也已具有一定的實際應(yīng)用價值。后期若能在該基礎(chǔ)上更進一步研究,則一定能擁有更廣闊的應(yīng)用前景和發(fā)揮更大的作用。