此篇文章主要介紹了Sobel算子的底層運算規律,和cv Harris的相關介紹
'''測驗'''
import numpy as np
mm = np.array([1,2,3])
pow(mm,2)
array([1, 4, 9], dtype=int32)
Harris opencv 的對應代碼
cv2.cornerHarris(src, blockSize, ksize, k[, dst[, borderType]])
引數型別
src - 輸入灰度影像,float32型別
blockSize - 用于角點檢測的鄰域大小,就是上面提到的視窗的尺寸
ksize - 用于計算梯度圖的Sobel算子的尺寸
k - 用于計算角點回應函式的引數k,取值范圍常在0.04~0.06之間
注:Sobel算子是濾波算子的形式,利用快速卷積函式, 簡單有效,因此應用廣泛
優點:方法簡單、處理速度快,并且所得的邊緣光滑
缺點:Sobel算子并沒有將影像的主體與背景嚴格地區分開來,換言之就是Sobel算子沒有基于影像灰度進行處理
原理:
sobel算子的horizon水平檢測Sob_x:
[[-1,0,1],
[-2,0,2],
[-1,0,1]]
sobel算子的vertical垂直檢測 Sob_y:
[[1,2,1],
[0,0,0],
[-1,-2,-1]]
矩陣公式:
Gx = Sob_x *img.data Gy = Sob_y * img.data
G的運算采用L2 范數,節約時間可用L1范數
L2:G = np.sqrt(pow(Gx,2)+pow(Gy,2)
L1:G = |Gx|+|Gy|
得到梯度值,若G大于閾值threshold,則說明有角點
再由 theta = 1/tan(Gy/Gx)得到梯度的方向
若theta 角度為0 代表影像有縱向邊緣
'''sobel算子的實作'''
import numpy as np
import matplotlib.pyplot as plt
import cv2
%matplotlib inline
'''Sober算子,初始化'''
sob_x ,sob_y= [[-1,0,1],[-2,0,2],[-1,0,1]], \
[[1,2,1],[0,0,0],[-1,-2,-1]]
'''圖片讀取并灰度化'''
img1 = cv2.imread('figures/image1.jpeg') #讀取通道為BGR
img1_gray = cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY) #BGR通道轉為Gray,
# 型別type(img1_gray) numpy.ndarray,shape (390, 700)
plt.imshow(img1_gray,cmap='gray')
plt.show()

'''這里舍棄最外圍的一圈像素點 實際sobel算子卷積了 388x698圖片'''
# 切片操作,取第一個需要卷積的矩陣,其核心位置為【1,1】
d10 = img1_gray[0:10,0:10]
d1 = img1_gray[0:3,0:3]
sob_d1 = np.abs(np.sum(sob_x*d1)) +np.abs(np.sum(sob_y * d1))
d10,d1,f'最開始的卷積之后的值 = {sob_d1}'
(array([[135, 139, 143, 146, 148, 152, 156, 159, 161, 162],
[135, 138, 142, 145, 148, 151, 155, 158, 161, 162],
[134, 137, 142, 145, 147, 150, 154, 158, 161, 162],
[134, 137, 141, 144, 147, 150, 154, 157, 161, 162],
[134, 138, 142, 145, 147, 150, 155, 158, 161, 162],
[136, 139, 143, 146, 148, 152, 156, 159, 161, 162],
[137, 140, 144, 148, 150, 153, 157, 160, 161, 162],
[138, 141, 145, 148, 151, 154, 158, 161, 161, 162],
[144, 145, 146, 148, 150, 152, 154, 155, 160, 160],
[144, 144, 145, 147, 148, 150, 152, 153, 160, 160]], dtype=uint8),
array([[135, 139, 143],
[135, 138, 142],
[134, 137, 142]], dtype=uint8),
'最開始的卷積之后的值 = 36')
'''定義一個卷積函式'''
def convolution_ndarray(kernal, data_gray):
n, m = data_gray.shape # (390, 700)
img_new = np.zeros((n-2, m-2))
for i in range(n-2 ): # [0,387)
temp_row = np.zeros(m-2) # 700
for j in range(m -2): # [ 0,697)
temp = data_gray[i:i + 3, j:j + 3]
temp_row[j] = np.sum(np.multiply(kernal, temp))
img_new[i] = temp_row
return img_new
Gx = convolution_ndarray(sob_x,img1_gray)
Gy = convolution_ndarray(sob_y,img1_gray)
# L1范數
G_L1 = np.absolute(Gx) +np.absolute(Gy)
# L2范數
G_L2 = np.sqrt(pow(Gx,2)+pow(Gy,2))
# 255矩陣
ones = np.ones(G_L1.shape)*255 #ones.shape (387, 697)
plt.figure(figsize=(40,40))
plt.subplot(131)
plt.imshow(img1_gray, cmap='gray')
plt.title('Sober + row_data ')
Color_Reversal_1 = ones -G_L1 #顏色反轉
plt.subplot(132)
plt.imshow(Color_Reversal_1,cmap='gray')
plt.title(' Sober + G_L1')
Color_Reversal_2 = ones-G_L2 #顏色反轉
plt.subplot(133)
plt.imshow(G_L2,cmap='gray')
plt.title(' Sober +G_L2 ')
plt.show()

采用opencv 封裝的Harris 角點檢測方法檢測角點
影像的角點檢測
檢測影像中的角點(幾條邊相交的位置)【1】
1.Harris角點檢測 思想:邊緣是在各個方向上都具有高密度變化的區域 演算法基本思想是使用一個固定視窗在影像上進行任意方向上的滑動,比較滑動前與滑動后兩種情況,視窗中的像素灰度變化程度,如果存在任意方向上的滑動,都有著較大灰度變化,那么我們可以認為該視窗中存在角點,
角點的特征:
>輪廓之間的交點;
>對于同一場景,即使視角發生變化,通常具備穩定性質的特征;
>該點附近區域的像素點無論在梯度方向上還是其梯度幅值上有著較大變化;
>就是一階導數(即灰度圖的梯度)中的區域最大所對應的像素點就是角點.
harris 角點檢測的步驟
1.當視窗(小的影像片段)同時向 x 和 y 兩個方向移動時,計算視窗內部的像素值變化量 d f(x,y) ;
2.對于每個視窗,都計算其對應的一個角點激活函式 G;
3.然后對該函式進行閾值處理,如果 G > threshold,表示該視窗對應一個角點特征.
2.Shi-Tomasi角點檢測
Harris角點檢測的改進版
Shi-Tomasi 發現,角點的穩定性其實和矩陣 M 的較小特征值有關
OpenCV 中的 Harris 角點檢測
Open 中的函式 cv2.cornerHarris() 可以用來進行角點檢測,引數如下:
? img - 資料型別為 float32 的輸入影像,
? blockSize - 角點檢測中要考慮的領域大小,
? ksize - Sobel 求導中使用的視窗大小
? k - Harris 角點檢測方程中的自由引數,取值引數為 [0,04,0.06].
————————————————
原文鏈接:https://blog.csdn.net/fuhao7i/article/details/111176488
magic_cube= cv2.imread('figures/magic_cube.jpg') #cv2讀取是BGR格式
magic_cube_gray = cv2.cvtColor(magic_cube,cv2.COLOR_BGR2GRAY)
corners_Harris = cv2.cornerHarris(magic_cube_gray,3,3,0.06) #shape (500, 500)
#Sobel運算x,y
cube_G_x = convolution_ndarray(sob_x,magic_cube_gray)
cube_G_y = convolution_ndarray(sob_y, magic_cube_gray)
cube_G_L1 =np.absolute(cube_G_x) +np.absolute(cube_G_y)
plt.figure(figsize=(40,40))
plt.subplot(131)
plt.imshow(magic_cube_gray,cmap ='gray')
plt.subplot(132)
plt.imshow(corners_Harris,cmap='gray')
plt.subplot(133)
plt.imshow(cube_G_L1,cmap='gray')
plt.show()
'''如下圖所示,直接顯示的檢測效果并不理想,但sobel算子運算得到的邊緣圖十分明顯
cube的上面灰度值與255較為接近,偏差不明顯,之后使用threshold進行角點檢測'''

'如下圖所示,直接顯示的檢測效果并不理想,cube的上面灰度值與255較為接近,偏差不明顯,故而使用threshold'
'''對該函式進行閾值處理,如果 G > threshold,表示該視窗對應一個角點特征.'''
threshold= 0.1*corners_Harris.max()
flag = corners_Harris > threshold
'''方法1,由np.where 直接找到 符合條件的array 下標'''
# where(condition, [x, y])
# x,y = np.where(flag) #回傳tuple 回傳了一個基于原本資料的地址索引 type() -> 2
x,y = np.where(flag)
corners_data1 = []
for i,j in zip(x,y):
corners_data1.append(corners_Harris[i][j])
'''方法2,由 統計學習的數學運算方法傳入一個由True,false組成的flag,
直接得到一個符合條件的一維資料'''
corners_data2 = corners_Harris[flag]
'''測驗data_index 所指向的資料是否和corners_data所記錄的符合的資料一致'''
corners_data1 == corners_data2
#資料比對均為True,說明由方法1和方法2獲得的資料一樣
array([ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True, True, True, True, True,
True, True, True, True, True])
'''對于方法2的解釋說明'''
a = np.array([[1,2,3],[1,2,3]])
flag1 = np.array([[True,True,True],[False,True,False]])
b = a[flag1] #這種方法只是回傳合格的資料,但并沒有原始資料所在的下標,且形狀為1維,適合label標簽的選取分類
'''plot 繪制角點'''
plt.figure(figsize=(40,40))
plt.subplot(121)
plt.scatter(y,x,c = 'red')
plt.imshow(magic_cube_gray,cmap='gray')
plt.subplot(122)
plt.scatter(y,x,c = 'red')
plt.imshow(cube_G_L1,cmap='gray')
plt.show()
plt.savefig('figures/cube_Harris.png')

<Figure size 432x288 with 0 Axes>
如上圖所示,角點位置坐標全部標注為紅色,資料在X,Y中保存對應的位置下標,實測所知,得到的資料x
,y轉換后可以正常畫圖使用 即x,y = y,x
推薦文章
主成分分析,獨立成分分析,+t-SNE 分布隨機可視化降維的對比
線性回歸預測波士頓房價
基于邏輯回歸的鳶尾花分類
資料表示和特征工程
參考文獻
機器學習 使用OpenCV、Python和scikit-learn進行智能影像處理(原書第2版)-(elib.cc) by (印)阿迪蒂亞·夏爾馬(Aditya Sharma)(印)維什韋什·拉維·什里馬利(Vishwesh Ravi Shrimali)(美)邁克爾·貝耶勒(Michael Beyeler)
Sobel算子,百度百科
角點檢測Harris與Shi-Tomas
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/436396.html
標籤:AI
