關鍵字:blur detection
Function:圖像的清晰度檢測英文表達為 image blue detection; 以此為關鍵字可以找到很多有關清晰度檢測的demo和算法。
圖像的清晰度檢測方法主要分為兩種情況:
- 一種是根據已有的圖像,來判斷現在的圖像是否模糊;
- 另一種是在無參考圖像的情況下,判斷圖像是否模糊;
我們目前解決的問題屬於 無參考圖像的質量評價
根據參考文獻[8,9]可以得知在無參考圖像下的,比較好的方法有:Brenner 梯度函數、Tenengrad 梯度函數、Laplacian 梯度函數等;相關代碼實現在github,詳情參見GitHub。
實驗環境
Python3
OpenCV3.2
Window 10
算法描述
注意:在實際的操作中,還需要對圖片進行預處理操作(檢測出人臉區域、設置相同大小的圖片、圖片灰度化等等)
只有這樣才不會受到圖像大小以及除去人臉以外的因素的影響。
在此假設人臉區域已經識別
本文初步對以上幾種方法進行了實現。
(1)拉普拉斯算子
這個方法最簡便,根據參考文獻[3]可以,opencv中提供了對laplace的封裝方法,直接調用即可,得到拉普拉斯算子邊緣檢測的圖片:
def lapulase(dir,name): """ :param dir: 操作目錄 :param name: 操作的文件名稱 :return: 分數 """ filePath=dir+name # img = filePath # Laplace梯度法 frame = cv2.imread(img) #cv2.imshow("原始圖", frame); resImg = cv2.resize(frame, (800, 900),interpolation=cv2.INTER_CUBIC) img2gray = cv2.cvtColor(resImg, cv2.COLOR_BGR2GRAY) # 將圖片壓縮為單通道的灰度圖 #img_resize = cv2.resize(img2gray, (112, 112)) # 為方便與其他圖片比較可以將圖片resize到同一個大小 res = cv2.Laplacian(img2gray, cv2.CV_64F) score = res.var() font = cv2.FONT_HERSHEY_SIMPLEX fontSize=5 # 照片 添加的文字 /左上角坐標 字體 字體大小 顏色 字體粗細 cv2.putText(resImg, str(score), (0, 200), font, fontSize, (0, 255, 0),6) newDir=dir+"/_Laplace_/" if not os.path.exists(newDir): os.makedirs(newDir) newName=newDir+name cv2.imwrite(newName, resImg) cv2.imshow('image', resImg) cv2.waitKey(0) #print("Laplacian score of given image is ", score) #cv2.imshow(r"gray效果圖", img2gray); #cv2.imshow(r"laplace效果圖", resImg); return score
(2)Brenner 檢測
Brenner梯度函數最簡單的梯度評價函數指標,他只是簡單的計算相鄰兩個像素灰度差的平方,該函數定義如下:
其中f(x,y)f(x,y)表示圖像ff所對應的像素點(x,y)(x,y)的灰度值,D(f)D(f)為圖像清晰度計算的結果。
代碼實現:
########################################### def ImageToMatrix(dir,name): # 讀取圖片 im = Image.open(dir+name) # 顯示圖片 #im.show() width,height = im.size im = im.convert("L") data = im.getdata() data = np.matrix(data,dtype='float')/255.0 new_data = np.reshape(data,(height,width)) return new_data def Brenner(img): x, y = img.shape D = 0 for i in range(x-2): for j in range(y-2): D += (img[i+2, j] - img[i, j])**2 return D def TestBrener(): dir = "D:/document/ZKBH/bug/face/" imgList = getAllImg(dir) for i in range(len(imgList)): frame = ImageToMatrix(dir , imgList[i]) score = Brenner(frame) print(str(imgList[i]) + " is " + str(score)) ########################################### def ImageToMatrix(dir,name): # 讀取圖片 im = Image.open(dir+name) # 顯示圖片 #im.show() width,height = im.size im = im.convert("L") data = im.getdata() data = np.matrix(data,dtype='float')/255.0 new_data = np.reshape(data,(height,width)) return new_data def Brenner(img): x, y = img.shape D = 0 for i in range(x-2): for j in range(y-2): D += (img[i+2, j] - img[i, j])**2 return D def TestBrener(): dir = "D:/document/ZKBH/bug/face/" imgList = getAllImg(dir) for i in range(len(imgList)): frame = ImageToMatrix(dir , imgList[i]) score = Brenner(frame) print(str(imgList[i]) + " is " + str(score)) ################################
(3)Tenengrad梯度函數
Tenengrad梯度函數采用Sobel算子分別提取水平和垂直方向的梯度,基於Tenengrad的圖像清晰度定義如下:
G(x,y)的形式如下:
其中,T是給定的邊緣檢測閾值,Gx和Gy分別是像素點(x,y)處Sobel水平和垂直方向邊緣檢測算子的卷積。(參見參考文檔[12,17])其余的方式都是一個這種類似的方式計算的額,
還有很多其他的模糊檢測方法,再此不再一一贅述,詳情參見GitHub。
參考文獻
1. opencv將圖像轉換成二維數組再將數組數據傳給新圖像
3. 用 Opencv 和 Python 對汪星人做模糊檢測(英文原版)(***)
4. 圖像清晰度的評價及分析(****)
6. 利用Laplacian變換進行圖像模糊檢測(****)
8. 圖像清晰度的評價指標
9. 圖像清晰度的評價及分析
10. Atitit 圖像清晰度 模糊度 檢測 識別 評價算法 原理
11. 【OpenCV】圖像模糊檢測
12. 無參考圖像的清晰度評價方法(****)
15. OpenCV with Laplacian formula to detect image is blur or not in iOS
16. 有沒有一種方法來檢測某個影像是模糊的?
17. python skimage圖像處理(一)
19. OpenCV——圖片的加載、顯示、保存(python)
===========以下還沒有仔細看===========
21. https://github.com/whdcumt/BlurDetection
22. Face recognition with OpenCV, Python, and deep learning
23. https://www.pyimagesearch.com/author/adrian/
24. Is there a way to detect if an image is blurry?(***)
25. http://www.doc88.com/p-6951865955255.html
26. https://github.com/WillBrennan/BlurDetection2
27. https://github.com/xLinkOut/blur-detection
28. https://github.com/xBazilio/cv_blurdetect/blob/master/main.cpp