1. 程式人生 > >python opencv 圖片梯度

python opencv 圖片梯度

# 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!"