點擊上方“3D視覺工坊”,選擇“星標”
干貨第一時間送達
來源:Opencv視覺實踐
本文翻譯自光頭哥哥的博客:【Blur detection with OpenCV】。
本文僅作學習分享,原文鏈接:
https://www.pyimagesearch.com/2015/09/07/blur-detection-with-opencv/
這只超可愛、超活躍家養小獵犬可能是有史以來拍照次數最多的狗。從8周大我們得到它的時候,到現在,不到3年的時間,我們已經收集了6000多張狗狗的照片。
在剛剛過去的這個周末,我坐下來,試圖整理手機里大量的照片。這是一項艱巨的任務,而且我很快就注意到一個問題——有很多照片模糊程度過高。
現在,對於一般人來說,我認為他們會刪除這些模糊的照片(或者至少將它們移到一個單獨的文件夾中)——但作為一個計算機視覺科學家,這是不可能發生的。
相反,我編寫了一個快速的Python腳本,用OpenCV執行模糊檢測。
接下來,我將向你展示如何使用OpenCV、Python和Laplacian算子計算圖像中的模糊量。在這篇文章的結尾,你將能夠應用Laplacian方法到你自己的照片來檢測模糊的程度。
拉普拉斯變換的方差
圖1:用Laplacian算子卷積輸入圖像
在研究如何檢測圖像中的模糊程度時,我的第一步是閱讀優秀的綜述論文,即【形狀-聚焦測量算子分析[2013 Pertuz等]】。在Pertuz等人的論文中,回顧了近36種估計圖像焦距程度的不同方法。
https://www.semanticscholar.org/paper/Analysis-of-focus-measure-operators-for-Pertuz-Puig/8c675bf5b542b98bf81dcf70bd869ab52ab8aae9?p2df
如果你有信號處理方面的背景,首先要考慮的方法是計算圖像的快速傅里葉變換,然后檢查低頻和高頻的分布:如果圖像只有有少量的高頻,那么圖像就會被認為是模糊的。然而,定義什么算低數量的高頻或者什么是高數量的高頻是相當困難的。
相反,如果我們可以計算一個單一的浮點值來表示一個給定圖像的模糊程度,不是很好嗎?
Pertuz等人回顧了許多計算這種“模糊度度量”的方法,其中一些方法簡單而直接,僅使用基本的灰度像素強度統計,另一些更先進和基於特征的方法,評估圖像的局部二值模式。
快速瀏覽完這篇論文后,我找到了我一直在尋找的理想算法:pecch - pacheco等人在他們2000年ICPR論文《亮場顯微鏡中的硅藻自動聚焦:比較研究》中提出的Laplacian的變化。
方法很簡單。簡單。有良好的推理。並且只需要一行代碼就可以實現:
cv2.Laplacian(image, cv2.CV_64F).var()
你只需采取一個圖像的單一通道(大概灰度)和卷積它與以下3 x 3的內核:
然后取響應的方差(即標准差的平方)。
如果方差低於預先定義的閾值,則認為圖像模糊;否則,圖像不會模糊。
這種方法有效的原因是由於Laplacian算子本身的定義,它用於測量圖像的二階導數。拉普拉斯算子突出顯示圖像中包含快速梯度變化的區域,很像Sobel和Scharr算子。和這些算子一樣,Laplacian也經常用於邊緣檢測。這里的假設是,如果一幅圖像的方差較高,那么就說明圖像有廣泛的響應,包括類邊和非類邊,這是一幅正常的聚焦圖像的代表。但如果方差很低,那么就會有很小的響應擴散,這表明圖像中幾乎沒有邊緣。而圖像越模糊,邊緣就越少。所以可以用來檢測是否模糊。
顯然,這里的關鍵是設置正確的閾值,而閾值的設置與應用到的圖像集相關。如果閾值過低,你就會錯誤地將原本不模糊的圖像標記為模糊。如果閾值過高,那么實際上模糊的圖像將不會被標記為模糊。這種方法只有在非常穩定的圖像集(同一類型)中應用良好。
檢測圖像中模糊的數量
所以現在我們已經明確了將要使用的方法:計算一個單一的度量來表示一個給定的圖像是多么“模糊”,讓我們看看我們的數據集以下12張圖像:
圖3:我們的圖像集。有些模糊,有些則不然。我們的目標是使用OpenCV進行模糊檢測並將圖像標記為模糊。
正如你所看到的,有些圖像是模糊的,有些則不是。我們的目標是正確地標記每個圖像模糊或非模糊。
有了這些,打開一個新文件,命名為detect_blur.py,讓我們打開代碼:
# import the necessary packages
from imutils import paths
import argparse
import cv2
def variance_of_laplacian(image):
# compute the Laplacian of the image and then return the focus
# measure, which is simply the variance of the Laplacian
return cv2.Laplacian(image, cv2.CV_64F).var()
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--images", required=True,
help="path to input directory of images")
ap.add_argument("-t", "--threshold", type=float, default=100.0,
help="focus measures that fall below this value will be considered 'blurry'")
args = vars(ap.parse_args())
我們從在第2-4行上導入必要的包開始。如果你還沒有我的imutils包在你的機器上,你會想現在安裝:
從這里開始,我們將在第6行定義variance_of_laplacian函數。這個方法將我們想要計算焦距的圖像(假設為單個通道,例如灰度圖像)作為參數。第9行簡單地用3 x 3 Laplacian運算符對圖像進行卷積,並返回方差。
第12-17行解析命令行參數。我們需要的第一個命令是——images,它是指向包含我們想要測試是否模糊的圖像數據集的目錄的路徑。
我們還將定義一個可選參數——thresh,它是我們將用於模糊測試的閾值。如果一個給定圖像的焦距測量低於這個閾值,我們將標記圖像為模糊。需要注意的是,您可能需要為自己的圖像數據集調優這個值。100的值對於我的數據集似乎工作得很好,但是這個值對於圖像的內容是非常主觀的,所以您需要自己使用這個值來獲得最優結果。
不管你信不信,最難的部分已經完成了!我們只需要寫一點代碼從磁盤加載圖像,計算Laplacian的方差,然后將圖像標記為模糊或非模糊:
# loop over the input images
for imagePath in paths.list_images(args["images"]):
# load the image, convert it to grayscale, and compute the
# focus measure of the image using the Variance of Laplacian
# method
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
fm = variance_of_laplacian(gray)
text = "Not Blurry"
# if the focus measure is less than the supplied threshold,
# then the image should be considered "blurry"
if fm < args["threshold"]:
text = "Blurry"
# show the image
cv2.putText(image, "{}: {:.2f}".format(text, fm), (10, 30),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 3)
cv2.imshow("Image", image)
key = cv2.waitKey(0)
我們從第2行開始對圖像目錄進行循環。對於這些圖像,我們將從磁盤加載,將其轉換為灰度,然后使用OpenCV應用模糊檢測(第6-9行)。
在焦點測量超過命令行參數提供的閾值的情況下,我們將把圖像標記為“模糊”。
最后,第3517-20行將文本和計算結果寫到圖像上,並將結果顯示在我們的屏幕上。
使用OpenCV進行模糊檢測
現在我們已經編寫了detect_blur.py腳本,讓我們嘗試一下。打開一個shell並發出以下命令:
這張照片的計算值是83.17,低於我們的閾值100;因此,我們正確地將該圖像標記為模糊。
這幅圖像的計算值為64.25,這也使得我們將其標記為“模糊”。
圖6的計算值很高,為1004.14—比前兩幅圖高了幾個數量級。這幅圖像顯然是非常清晰的。
總結
在這篇博文中,我們學習了如何使用OpenCV和Python執行模糊檢測。
我們實現了計算Laplacian方法的方差,得到一個浮點值來表示圖像的“模糊”程度。這種方法快速、簡單、易於應用——我們只需用Laplacian算子對輸入圖像進行卷積並計算方差。如果方差低於預先定義的閾值,我們將圖像標記為“模糊”。
需要注意的是,閾值是正確調優的一個關鍵參數,您經常需要根據每個數據集對其進行調優。
本文僅做學術分享,如有侵權,請聯系刪文。下載1在「3D視覺工坊」公眾號后台回復:3D視覺,即可下載 3D視覺相關資料干貨,涉及相機標定、三維重建、立體視覺、SLAM、深度學習、點雲后處理、多視圖幾何等方向。
下載2在「3D視覺工坊」公眾號后台回復:3D視覺github資源匯總,即可下載包括結構光、標定源碼、缺陷檢測源碼、深度估計與深度補全源碼、點雲處理相關源碼、立體匹配源碼、單目、雙目3D檢測、基於點雲的3D檢測、6D姿態估計源碼匯總等。
下載3在「3D視覺工坊」公眾號后台回復:相機標定,即可下載獨家相機標定學習課件與視頻網址;后台回復:立體匹配,即可下載獨家立體匹配學習課件與視頻網址。
重磅!3DCVer-學術論文寫作投稿 交流群已成立
掃碼添加小助手微信,可申請加入3D視覺工坊-學術論文寫作與投稿 微信交流群,旨在交流頂會、頂刊、SCI、EI等寫作與投稿事宜。
同時也可申請加入我們的細分方向交流群,目前主要有3D視覺、CV&深度學習、SLAM、三維重建、點雲后處理、自動駕駛、CV入門、三維測量、VR/AR、3D人臉識別、醫療影像、缺陷檢測、行人重識別、目標跟蹤、視覺產品落地、視覺競賽、車牌識別、硬件選型、學術交流、求職交流等微信群。
一定要備注:研究方向+學校/公司+昵稱,例如:”3D視覺 + 上海交大 + 靜靜“。請按照格式備注,可快速被通過且邀請進群。原創投稿也請聯系。
▲長按加微信群或投稿
▲長按關注公眾號
3D視覺從入門到精通知識星球:針對3D視覺領域的知識點匯總、入門進階學習路線、最新paper分享、疑問解答四個方面進行深耕,更有各類大廠的算法工程人員進行技術指導。與此同時,星球將聯合知名企業發布3D視覺相關算法開發崗位以及項目對接信息,打造成集技術與就業為一體的鐵桿粉絲聚集區,近2000星球成員為創造更好的AI世界共同進步,知識星球入口: