计算机视觉实验:边缘提取与特征检测
秋風(fēng)閣——北溪入江流:https://focus-wind.com/
秋風(fēng)閣——計(jì)算機(jī)視覺(jué)實(shí)驗(yàn):邊緣提取與特征檢測(cè)
文章目錄
- 一:實(shí)驗(yàn)內(nèi)容
- 二:實(shí)驗(yàn)過(guò)程
- (一)邊緣提取
- (1)卷積算子
- a:robert交叉算子
- b:prewitt算子
- c:sobel算子
- d:laplacian算子
- (2)實(shí)驗(yàn)代碼
- (二)特征點(diǎn)檢測(cè)
- (1)實(shí)驗(yàn)代碼
- 三:實(shí)驗(yàn)結(jié)果及分析
- (一)邊緣提取
- (1)實(shí)驗(yàn)原圖
- (2)robert算子
- (3)prewitt算子
- (3)sobel算子
- (4)laplacian算子
- (5)綜合對(duì)比
- (二)特征點(diǎn)檢測(cè)
- (1)實(shí)驗(yàn)原圖
- (2)susan特征點(diǎn)檢測(cè)
- (3)harris特征點(diǎn)檢測(cè)
- (4)sift特征點(diǎn)檢測(cè)
- (5)綜合對(duì)比
一:實(shí)驗(yàn)內(nèi)容
二:實(shí)驗(yàn)過(guò)程
(一)邊緣提取
(1)卷積算子
a:robert交叉算子
b:prewitt算子
c:sobel算子
d:laplacian算子
(2)實(shí)驗(yàn)代碼
import cv2 import numpy as npdef _edge_extraction(img: np.ndarray, kernel_method='robert'):"""邊緣提取:param img: 需要進(jìn)行邊緣提取的圖,COLOR:BGR:param kernel_method: 邊緣提取算子名稱,全小寫:return: x方向(0.5x)和y方向(0.5y)邊緣提取的加權(quán)和"""# 轉(zhuǎn)換為灰度圖gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 邊緣提取算子if 'robert' == kernel_method:kernel_x = np.array([[-1, 0], [0, 1]], dtype=int)kernel_y = np.array([[0, -1], [1, 0]], dtype=int)elif 'prewitt' == kernel_method:kernel_x = np.array([[-1, 0, 1], [-1, 0, 1], [-1, 0, 1]], dtype=int)kernel_y = np.array([[1, 1, 1], [0, 0, 0], [1, 1, 1]], dtype=int)elif 'sobel' == kernel_method:kernel_x = np.array([[-1, 0, 1], [-2, 0, -2], [-1, 0, 1]], dtype=int)kernel_y = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]], dtype=int)elif 'laplacian' == kernel_method:kernel_x = np.array([[0, -1, 0], [-1, 4, -1], [0, -1, 0]], dtype=int)kernel_y = np.array([[-1, -1, -1], [-1, 8, -1], [-1, -1, -1]], dtype=int)else:kernel_x = np.array([[-1, 0], [0, 1]], dtype=int)kernel_y = np.array([[0, -1], [1, 0]], dtype=int)# 進(jìn)行邊緣提取filter_x = cv2.filter2D(gray, ddepth=-1, kernel=kernel_x)filter_y = cv2.filter2D(gray, ddepth=-1, kernel=kernel_y)# x方向和y方向加權(quán)img_add_weight = cv2.addWeighted(filter_x, 0.5, filter_y, 0.5, 0)return img_add_weightdef image_show(img: np.ndarray, title='img'):"""顯示圖片:param img::param title::return:"""cv2.namedWindow(title)cv2.imshow(title, img)cv2.waitKey(0)def edge_extraction(path: str, kernel_method='robert'):# 讀取圖片img = cv2.imdecode(np.fromfile(path, dtype=np.uint8), cv2.IMREAD_COLOR)# 邊緣提取img_extraction = _edge_extraction(img, kernel_method=kernel_method)# 顯示圖片image_show(img_extraction, kernel_method)(二)特征點(diǎn)檢測(cè)
(1)實(shí)驗(yàn)代碼
import cv2 import numpy as npdef feature_point_detection_susan(img: np.ndarray):"""susan特征點(diǎn)檢測(cè):param img::return:"""# susan算子susan_operator = np.ones((7, 7))susan_operator[0, 0] = 0susan_operator[0, 1] = 0susan_operator[0, 5] = 0susan_operator[0, 6] = 0susan_operator[1, 0] = 0susan_operator[1, 6] = 0susan_operator[5, 0] = 0susan_operator[5, 6] = 0susan_operator[6, 0] = 0susan_operator[6, 1] = 0susan_operator[6, 5] = 0susan_operator[6, 6] = 0dst = img.astype(np.float64)# 檢測(cè)閾值threshold = 37 / 2# 像素偏差閾值t = 10for i in range(3, dst.shape[0] - 3):for j in range(3, dst.shape[1] - 3):# ir:中心位置像素,ir0周邊位置像素# 獲取矩形區(qū)域ir = np.array(dst[i - 3:i + 4, j - 3:j + 4])# 使用susan算子截取圓形區(qū)域ir = ir[1 == susan_operator]ir0 = dst[i, j]# 平滑曲線相似變換:c = e的[-((ir - ir0)/6))的6次方]的次方,表示相似還是不相似similarity = np.sum(np.exp(-((ir - ir0) / t) ** 6))# 小于閾值,提取特征點(diǎn)if similarity < threshold:img[i, j, 2] = 255return imgdef feature_point_detection_harris(img: np.ndarray):"""harris特征點(diǎn)檢測(cè):param img::return:"""# 轉(zhuǎn)換為灰度圖gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# Harris特征點(diǎn)檢測(cè)# 檢測(cè)窗口大小block_size = 2# Sobel的卷積核k_size = 3# 權(quán)重系數(shù)k = 0.04dst = cv2.cornerHarris(gray, block_size, k_size, k)# 在原圖上繪制關(guān)鍵點(diǎn)img[dst > 0.01 * dst.max()] = [0, 0, 255]return imgdef feature_point_detection_sift(img: np.ndarray):"""sift特征點(diǎn)檢測(cè):param img::return:"""# 轉(zhuǎn)換為灰度圖gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 創(chuàng)建SIFT對(duì)象sift = cv2.SIFT_create()# SIFT關(guān)鍵點(diǎn)檢測(cè)kernel_point = sift.detect(gray, None)# 在原圖繪制關(guān)鍵點(diǎn)cv2.drawKeypoints(gray, kernel_point, img)return imgdef image_show(img: np.ndarray, title='img'):"""顯示圖片:param img::param title::return:"""cv2.namedWindow(title)cv2.imshow(title, img)cv2.waitKey(0)def feature_point(path: str, kernel_method='susan'):# 讀取圖片img = cv2.imdecode(np.fromfile(path, dtype=np.uint8), cv2.IMREAD_COLOR)# 特征檢測(cè)if 'susan' == kernel_method:img_feature_point = feature_point_detection_susan(img)elif 'harris' == kernel_method:img_feature_point = feature_point_detection_harris(img)elif 'sift' == kernel_method:img_feature_point = feature_point_detection_sift(img)else:img_feature_point = feature_point_detection_susan(img)# 顯示圖片image_show(img_feature_point, kernel_method)三:實(shí)驗(yàn)結(jié)果及分析
(一)邊緣提取
(1)實(shí)驗(yàn)原圖
(2)robert算子
提取時(shí)間:0.0020003318786621094
(3)prewitt算子
提取時(shí)間:0.0010013580322265625
(3)sobel算子
提取時(shí)間:0.002001523971557617
(4)laplacian算子
提取時(shí)間:0.001997232437133789
(5)綜合對(duì)比
robert提取時(shí)間:0.0020003318786621094
prewitt提取時(shí)間:0.0010013580322265625
sobel提取時(shí)間:0.002001523971557617
laplacian提取時(shí)間:0.001997232437133789
通過(guò)上圖可以看出,laplacian二階算子的邊緣提取算子的提取效果明顯優(yōu)于robert,prewitt,sobel等一階算子。且一階算子和二階算子在提取的時(shí)間上和算法的復(fù)雜度上相差不大,所以在實(shí)驗(yàn)中,如果有特征提取需求的話,可以盡量多采用二階算子進(jìn)行邊緣提取。
(二)特征點(diǎn)檢測(cè)
(1)實(shí)驗(yàn)原圖
(2)susan特征點(diǎn)檢測(cè)
(3)harris特征點(diǎn)檢測(cè)
(4)sift特征點(diǎn)檢測(cè)
(5)綜合對(duì)比
在實(shí)驗(yàn)中,因?yàn)閛pencv不提供(或本人沒(méi)有找到)有關(guān)susan的特征點(diǎn)檢測(cè)的函數(shù),所以susan特征點(diǎn)檢測(cè)是自己寫的,相比于其他特征點(diǎn)檢測(cè)直接調(diào)用底層庫(kù)較慢。在三個(gè)檢測(cè)圖片中,可以發(fā)現(xiàn)sift特征點(diǎn)檢測(cè)檢測(cè)到的特征點(diǎn)更多,其他檢測(cè)是邊緣特征點(diǎn),二sift不僅檢測(cè)了邊緣特征點(diǎn),也檢測(cè)出了中心特征點(diǎn)。
總結(jié)
以上是生活随笔為你收集整理的计算机视觉实验:边缘提取与特征检测的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 使用 FreeBSD 作为桌面
- 下一篇: EA 显示 toolbox