python opencv 圖片梯度
阿新 • • 發佈:2018-11-27
# OpenCV提供了三種類型的梯度過濾器或者高通濾波器,Sobel,Scharr和Laplacian
cv2.CV_16S
# Sobel運算元
# Sobel運算元依然是一種過濾器,只是其是帶有方向的。在OpenCV-Python中,
# 使用Sobel的運算元的函式原型如下:
# dst = cv2.Sobel(src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]])
# ksize是Sobel運算元的大小,必須為1、3、5、7。
# scale是縮放導數的比例常數,預設情況下沒有伸縮係數;
# delta是一個可選的增量,將會加到最終的dst中,同樣,預設情況下沒有額外的值加到dst中;
# borderType是判斷影象邊界的模式。這個引數預設值為cv2.BORDER_DEFAULT
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('black_white2.jpg',0)
'''
在Sobel函式的第二個引數這裡使用了cv2.CV_16S。因為OpenCV文件中對Sobel運算元的介紹
中有這麼一句:Sobel函式求完導數後會有負值,還有會大於255的值。而原影象是uint8,
即8位無符號數,所以Sobel建立的影象位數不夠,會有截斷。
因此要使用16位有符號的資料型別,即cv2.CV_16S。
'''
x=cv2.Sobel(img,cv2.CV_16S,1,0,ksize=3)#對x求導
y=cv2.Sobel(img,cv2.CV_16S,0,1,ksize=3)#對y求導
'''
在經過處理後,別忘了用convertScaleAbs()函式將其轉回原來的uint8形式。
否則將無法顯示影象,而只是一副灰色的視窗。
dst = cv2.convertScaleAbs(src[, dst[, alpha[, beta]]])
其中可選引數alpha是伸縮係數,beta是加到結果上的一個值。結果返回uint8型別的圖片。
'''
absX=cv2.convertScaleAbs( x) # 轉回uint8
absY=cv2.convertScaleAbs(y)
'''''
由於Sobel運算元是在兩個方向計算的,最後還需要用cv2.addWeighted(...)函式將其組合起來
。其函式原型為:
dst = cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]])
其中alpha是第一幅圖片中元素的權重,beta是第二個的權重,
gamma是加到最後結果上的一個值。
'''
dst = cv2.addWeighted(absX,0.5,absY,0.5,0)
cv2.imshow('absX',absX)
cv2.imshow('absY',absY)
cv2.imshow('Result',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
'''''
Laplacian運算元
影象中的邊緣區域,畫素值會發生“跳躍”,對這些畫素求導,在其一階導數在邊緣
位置為極值,這就是Sobel運算元使用的原理——極值處就是邊緣。如果對畫素值求二階導數,
會發現邊緣處的導數值為0
Laplace函式實現的方法是先用Sobel 運算元計算二階x和y導數,再求和:
在OpenCV-Python中,Laplace運算元的函式原型如下:
dst = cv2.Laplacian(src, ddepth[, dst[, ksize[, scale[, delta[, borderType]]]]])
第一個引數是需要處理的影象;
第二個引數是影象的深度,-1表示採用的是與原影象相同的深度。目標影象的深度必須大於等於原影象的深度;
dst不用解釋了;
ksize是運算元的大小,必須為1、3、5、7。預設為1。
scale是縮放導數的比例常數,預設情況下沒有伸縮係數;
delta是一個可選的增量,將會加到最終的dst中,同樣,預設情況下沒有額外的值加到dst中;
borderType是判斷影象邊界的模式。這個引數預設值為cv2.BORDER_DEFAULT。
'''
import cv2
import numpy as np
img=cv2.imread('black_white2.jpg',0)
blur = cv2.bilateralFilter(img,9,75,75)
dst2=cv2.Laplacian(blur,cv2.CV_64F,ksize=1)
print(dst2.dtype)
cv2.imshow('laplacian',dst2)
cv2.waitKey(0)
cv2.destroyAllWindows()
float64
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('black_white2.jpg',0)
# Output dtype = cv2.CV_8U
sobelx8u = cv2.Sobel(img,cv2.CV_8U,1,0,ksize=7)
# Output dtype = cv2.CV_64F. Then take its absolute and convert to cv2.CV_8U
# 影象格式轉換
sobelx64f = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=5)
abs_sobel64f = np.absolute(sobelx64f)
sobel_8u = np.uint8(abs_sobel64f)
# 利用Laplacian變換進行影象模糊檢測
import cv2
image = "test.jpg"
frame = cv2.imread(image)
img2gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 將圖片壓縮為單通道的灰度圖
# img_resize = cv2.resize(img2gray, (112, 112)) # 為方便與其他圖片比較可以將圖片resize到同一個大小
score = cv2.Laplacian(img2gray, cv2.CV_64F).var()
print "Laplacian score of given image is ", score
if score > 100: # 這個值可以根據需要自己調節,在我的測試集中100可以滿足我的需求。
print "Good image!"
else:
print "Bad image!"