天天看點

圖檔處理(五)robert、prewitt、sobel算子邊界檢測

robert算子其實就是一個22數組,1,-1對角線,是一個卷積核,目的就是用差分法求出邊界,此法比較粗糙,很多人說卷積核是矩陣,其實我的了解是數組,因為運算方式不符合矩陣。

prewitt算子是33卷積核,兩邊1,-1沿中間或對角線對稱

sobel算子考慮了距離權重,不是一味的都是1或-1,而在prewitt的基礎上中間的數字是2或-2,較prewitt更先進

另外cv2.Canny(image,門檻值1一般50,門檻值2一般150,sobel算子大小可選參數)canny算子很複雜,暫時不實作了,直接調用api

robert代碼如下:

import numpy as np
import cv2

path = r'../test.jpg'
image = cv2.imread(path,0)
robert = [[[1,0],[0,-1]],[[0,-1],[1,0]]]
robert = np.asarray(robert)
hight,width = image.shape

#img_map = np.zeros((hight+2,width+2))
#img_map[1:hight+1,1:width+1] = image

result_map = np.zeros((hight,width))

for i in range(1,hight):
	for j in range(1,width):
		for rob in robert:
			result_map[i-1,j-1] = result_map[i-1,j-1]+np.sum(image[i-1:i+1,j-1:j+1]*rob)

print(result_map)
cv2.imshow('test',result_map.astype(np.uint8))
cv2.imwrite('rob.jpg',result_map.astype(np.uint8))
cv2.waitKey(0)
cv2.destroyWindows()
           
圖檔處理(五)robert、prewitt、sobel算子邊界檢測

sobel就直接調用api,如果自制卷積核和上面代碼類似,代碼如下:

import numpy as np
import cv2

path = r'../test.jpg'
image = cv2.imread(path,0)
sobel = cv2.Sobel(image,cv2.CV_64F,1,1,ksize=3)
# robert = [[[1,0],[0,-1]],[[0,-1],[1,0]]]
# robert = np.asarray(robert)
# hight,width = image.shape

#img_map = np.zeros((hight+2,width+2))
#img_map[1:hight+1,1:width+1] = image

# result_map = np.zeros((hight,width))

# for i in range(1,hight):
# 	for j in range(1,width):
# 		for rob in robert:
# 			result_map[i-1,j-1] = result_map[i-1,j-1]+np.sum(image[i-1:i+1,j-1:j+1]*rob)

# print(result_map)
# cv2.imshow('test',result_map.astype(np.uint8))
# cv2.imwrite('rob.jpg',result_map.astype(np.uint8))
cv2.imshow('test',sobel.astype(np.uint8))
cv2.imwrite('sobel.jpg',sobel.astype(np.uint8))
cv2.waitKey(0)
cv2.destroyWindows()
           

效果如下:

圖檔處理(五)robert、prewitt、sobel算子邊界檢測

值得說的事sobel可以再x方向進行檢測, 也可以再y方向進行檢測,這張圖是xy檢測的,隻需調整參數将1變為0對應檢測方向就變了

繼續閱讀