清晰圖像和模糊圖像之間的差別在哪里呢?
從邏輯上考慮,圖像模糊是因為圖像中物體的輪廓不明顯,輪廓邊緣灰度變化不強烈,層次感不強造成的
反過來考慮,輪廓邊緣灰度變化明顯些,層次感強些是不是圖像就更清晰些呢。
那么,這種灰度變化明顯不明顯怎樣去定義呢?
知道微分就是求函數的變化率,即導數(梯度),那么對於圖像來說,可不可以用微分來表示圖像灰度的變化率呢,當然是可以的,前面我們提到過,圖像就是函數嘛。
因為圖像是一個離散的二維函數,ϵϵ不能無限小,我們的圖像是按照像素來離散的,最小的ϵϵ就是1像素。因此,上面的圖像微分又變成了如下的形式(ϵ=1ϵ=1):
這分別是圖像在(x, y)點處x方向和y方向上的梯度,從上面的表達式可以看出來,圖像的梯度相當於2個相鄰像素之間的差值。
圖片演示梯度過程
我們先考慮下x方向,選取某個像素,假設其像素值是100,沿x方向的相鄰像素分別是90,90,90,則根據上面的計算其x方向梯度分別是10,0,0。這里只取變化率的絕對值,表明變化的大小即可。
我們看到,100和90之間亮度相差10,並不是很明顯,與一大群90的連續灰度值在一起,輪廓必然是模糊的。我們注意到,如果相鄰像素灰度值有變化,那么梯度就有值,如果相鄰像素灰度值沒有變化,那么梯度就為0。如果我們把梯度值與對應的像素相加,那么灰度值沒有變化的,像素值不變,而有梯度值的,灰度值變大了。
我們看到,相加后的新圖像,原圖像像素點100與90亮度只相差10,現在是110與90,亮度相差20了,對比度顯然增強了,尤其是圖像中物體的輪廓和邊緣,與背景大大加強了區別,這就是用梯度來增強圖像的原理。
二 索貝爾算子
代碼
import cv2 as cv #圖像梯度:索貝爾算子 def sobel_image(image): grad_x=cv.Sobel(image,cv.CV_32F,1,0) #x方向導數 grad_y=cv.Sobel(image,cv.CV_32F,0,1) #y方向導數 gradx=cv.convertScaleAbs(grad_x) #顏色變化在水平分層 grady=cv.convertScaleAbs(grad_y) #顏色變化在垂直分層 cv.imshow("X方向", gradx) # 顏色變化在水平分層 cv.imshow("Y方向", grady) # 顏色變化在垂直分層 gradxy=cv.addWeighted(gradx,0.5,grady,0.5,0) cv.imshow('merge',gradxy) src = cv.imread("ying.jpg") cv.imshow("before", src) sobel_image(src) cv.waitKey(0) cv.destroyAllWindows()
效果展示
三 scharr算子
代碼
import cv2 as cv #圖像梯度:scharr算子:增強邊緣 def scharr_image(image): grad_x = cv.Scharr(image, cv.CV_32F, 1, 0)#x方向導數 grad_y = cv.Scharr(image, cv.CV_32F, 0, 1)#y方向導數 gradx = cv.convertScaleAbs(grad_x) grady = cv.convertScaleAbs(grad_y) cv.imshow("X -go", gradx)#顏色變化在水平分層 cv.imshow("Y -go", grady)#顏色變化在垂直分層 gradxy = cv.addWeighted(gradx, 0.5, grady, 0.5, 0) cv.imshow("merge", gradxy) src = cv.imread("ying.jpg") cv.imshow("before", src) scharr_image(src) cv.waitKey(0) cv.destroyAllWindows()
效果展示
四 拉普拉斯算子
代碼
import cv2 as cv #圖像梯度:scharr算子:增強邊緣 def lapalian_image(image): dst=cv.Laplacian(image,cv.CV_32F) lpls=cv.convertScaleAbs(dst) cv.imshow('lpls',lpls) src = cv.imread("ying.jpg") cv.imshow("before", src) lapalian_image(src) cv.waitKey(0) cv.destroyAllWindows()
效果展示