日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

Harris-Laplace角点检测初探+python实现

發(fā)布時間:2023/12/15 python 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Harris-Laplace角点检测初探+python实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Harris-Laplace角點檢測初探+python代碼實現(xiàn)

  • 數(shù)學(xué)學(xué)院外行入門,課程團隊作業(yè),剛學(xué)的Markdown,版排得很隨意(丑),多多擔(dān)待

預(yù)備知識

角點

  • 數(shù)字圖像特征之一,包含了大量的位置信息以及指向型信息
  • 一般而言,就是物體邊緣的一些拐點,如下圖所示:
    上圖中紅色點為角點
  • 用途:圖像匹配、后期處理抵消圖像形變、三維重建

Harris算法檢測角點(重頭戲來了)

Harris核心思路(通過周邊區(qū)域來判斷角點)

一個窗口在一檢測點處上下、左右或者沿對角線移動:

  • 平坦點flat:無論怎么移動,方框內(nèi)的灰度值不變,則平平無奇和飛機場一樣,沒有什么點;
  • 邊緣點edge:方框內(nèi)的灰度值只沿著一個方向改變,其余方向不變,則是邊緣點;
  • 角點corner:無論怎么移動,上下左右or斜向,灰度值變化都比較大,雨露均沾,則是角點。
  • Moravec算子

    其實Harris是在Moravec基礎(chǔ)上改進而來的,所以在討論Harris之前,先來看一下Moravec

    • 缺陷:Moravec只考慮了縱橫斜著四種方向,所以沒有旋轉(zhuǎn)不變性,當(dāng)原圖旋轉(zhuǎn)一下可能原來檢測是角點的點現(xiàn)在檢測就不是了,算法對圖像的旋轉(zhuǎn)魯棒性差。
    • 改進:那就考慮多一點方向唄,方向細化 =》 全微分 =》 泰勒展開
      (這個想法太妙了,擺脫了對平移量[u,v]的依賴,僅依靠自身信息來判斷角點,而且還增強了旋轉(zhuǎn)不變性)

    Harris算子


    二次型,這里是不是有點橢圓曲線的意思,詳見下圖:

    其實從線性代數(shù)的角度很好理解,就是要矩陣M的兩個特征值都很大,為了表示“兩個特征值都很大”這一層意思,給出下列角點響應(yīng)公式,角點響應(yīng)R大的話,則表明兩個特征值都很大,則該點判斷為角點。從數(shù)學(xué)的角度來看,這個角點響應(yīng)取得真好,先是乘積打頭,讓兩個值都盡可能地大,同時減去矩陣跡(trace)的平方,排除出現(xiàn)一個遠大于另一個的情況(這種情況是邊緣點),太妙了~

    • 注:這里的M矩陣省略了權(quán)重w(x,y)
    • 前面關(guān)于Harris角點檢測說了這么多,所以。。。Laplace在哪,前面不都是一階梯度嗎???我是不是找錯資料了????

    Harris-Laplace角點檢測(原來主角這才來啊,哭了)

    前言

    傳統(tǒng)的Harris角點檢測(由Harris等在1988年提出)雖然對旋轉(zhuǎn)改變有很好的檢測不變性,但是卻不具有尺度不變性及仿射不變性。為了獲得尺度不變性,就需要在傳統(tǒng)的Harris角點檢測中引入多尺度空間。Mikolajczyk和Schmid于2004年提出具有尺度不變性的Harris-Laplace檢測方法[1]。

    算法流程

    代碼實現(xiàn)

    • 以下代碼雖然能夠正常運行,但是很多細節(jié)我也還沒搞明白,看看大致框架就行,想深究細節(jié)的話看最后參考文獻[1].
    import cv2 import math import numpy as np from scipy import ndimage as ndim import matplotlib.pyplot as plt %matplotlib inline# 取最近的正奇數(shù) def odd(val):if int(val)%2 == 0:return int(val)+1else:return int(val)# 生成歸一化后的高斯內(nèi)核 def gauss_kernel(size,sigma):'''size表示高斯內(nèi)核的大小,為正的奇數(shù)sigma表述隨機變量X和Y的標(biāo)準(zhǔn)差,此處假設(shè)X和Y具有相同的標(biāo)準(zhǔn)差'''xy = range(-(size-1)//2,(size+1)//2)X,Y = np.meshgrid(xy,xy)G = 1/(2*np.pi*sigma**2)*np.exp(-0.5*(X**2+Y**2)/sigma**2)return G/np.sum(G) # 生成歸一化后的LOG內(nèi)核 def log_kernel(size,sigma):'''size表示高斯內(nèi)核的大小,為正的奇數(shù)sigma表述隨機變量X和Y的標(biāo)準(zhǔn)差,此處假設(shè)X和Y具有相同的標(biāo)準(zhǔn)差'''xy = range(-(size-1)//2,(size+1)//2)X,Y = np.meshgrid(xy,xy)LOG = (X**2+Y**2-2*sigma**2)/(sigma**4)*np.exp(-0.5*(X**2+Y**2)/sigma**2)return LOG# 非極大值抑制 def find_local_maximum(val):'''功能:查找領(lǐng)域極大值;輸入:val-矩陣輸出:row-領(lǐng)域極大值的行坐標(biāo) col-領(lǐng)域極大值的列坐標(biāo) max_local-領(lǐng)域極大值'''footprint = np.ones((3,3))footprint[1,1] = 0maxima_around = ndim.maximum_filter(val,footprint = footprint) # 8領(lǐng)域內(nèi)最大值濾波mask = val > maxima_around # 找出極大值點所在的位置points = np.argwhere(mask==1)return points # plt.imshow(img,cmap = 'gray') # plt.axis('off') # plt.showdef Har_Lap_corners_detect(img): '''功能:Harris Laplace角點檢測參數(shù):img-輸入的圖像輸出:points = [l,c,radius] l,c-角點的橫縱坐標(biāo),radius-特征尺度值所對應(yīng)的圓形區(qū)域的半徑'''# 圖像參數(shù)height,width = img.shape # 尺度參數(shù)sigma_begin = 1.5sigma_step = 1.2sigma_nb = 13sigma_array = (sigma_step**np.arange(sigma_nb))*sigma_begin# 第一部分:提取Harris角點harris_pts = np.zeros((0,3),dtype = float)k = 0.06 for i in range(sigma_nb):# 尺度s_I = sigma_array[i]ksize = odd(6*s_I+1)s_D = 0.7*s_I# # 微分掩模# x = np.arange(-round(3*s_D),round(3*s_D)+1)# Ix = np.array([x*np.exp(-x*x/(2*s_D*s_D))/(s_D*s_D*s_D*(2*np.pi)**0.5)])# Iy = Ix.T# # 分別計算x,y方向上的梯度# dx = cv2.filter2D(img,cv2.CV_32F,Ix)# dy = cv2.filter2D(img,cv2.CV_32F,Iy)# dxx = np.array([-1,0,1])g = np.array([np.exp(-x*x/(2*s_D**2))/(s_D*(2*np.pi)**0.5)])g = g/np.sum(g) # 歸一化fx = np.array([[-1,0,1]])dx = cv2.filter2D(img,cv2.CV_32F,g*fx)dy = cv2.filter2D(img,cv2.CV_32F,g.T*fx.T)# 自相關(guān)矩陣g = gauss_kernel(max(1,ksize),s_I) # 生成高斯核dx2 = cv2.filter2D(dx**2,cv2.CV_32F,g)dy2 = cv2.filter2D(dy**2,cv2.CV_32F,g)dxy = cv2.filter2D(dx*dy,cv2.CV_32F,g)cim = dx2*dy2-dxy**2-k*(dx2+dy2)**2# 閾值tmp = 0.01*np.max(cim)cim[cim<tmp] = 0# 3*3領(lǐng)域非極大值抑制points = find_local_maximum(cim)n = points.shape[0]points = np.c_[points,i*np.ones((n,1))]harris_pts = np.r_[harris_pts,points]# 第二部分:Laplace變換# 計算尺度空間log = np.zeros((height,width,sigma_nb))for i in range(sigma_nb):s_L = sigma_array[i]#img_g = cv2.filter2D(img,-1,gauss_kernel(max(1,int(6*s_I+1)),s_L))#log[:,:,i] = s_L*s_L*cv2.filter2D(img,-1,log_kernel(odd(6*s_L+1),s_L))log[:,:,i] = s_L*s_L*cv2.Laplacian(cv2.GaussianBlur(img,(odd(6*s_L+1),odd(6*s_L+1)),s_L,s_L),cv2.CV_32F,ksize = 3)# 檢測每個特征點在某一尺度LoG相應(yīng)是否最大n = harris_pts.shape[0]cpt = -1points_t = np.zeros((n,3))for i in range(n):l = int(harris_pts[i,0])c = int(harris_pts[i,1])s = int(harris_pts[i,2])val = log[l,c,s]if s>0 and s<sigma_nb-1:if val>log[l,c,s-1] and val>log[l,c,s+1]:cpt += 1;points_t[cpt,:] = harris_pts[i,:]points_t[cpt,2] = 3*sigma_array[s]elif s == 0:if val > log[l,c,1]:cpt += 1;points_t[cpt,:] = harris_pts[i,:]points_t[cpt,2] = 3*sigma_array[s]else:if val > log[l,c,s-1]:cpt += 1;points_t[cpt,:] = harris_pts[i,:]points_t[cpt,2] = 3*sigma_array[s]points = np.zeros((cpt,3))for i in range(cpt):points[i,:] = points_t[i,:]return pointsdef draw(img,points):'''功能:在原圖上標(biāo)注出角點并顯示輸入:img-圖像 points = [l,c,radius] l,c-角點的橫縱坐標(biāo),radius-特征尺度值所對應(yīng)的圓形區(qū)域的半徑'''for i in range(points.shape[0]):cv2.circle(img,(int(points[i,1]),int(points[i,0])),int(points[i,2]),(255,0,0),2) # 原來這里要橫縱坐標(biāo)互換,害我改了半天才發(fā)現(xiàn)錯誤所在,哭了。plt.figure(figsize=(7,7))plt.imshow(img)plt.axis('off')plt.show

    Harris-Laplace角點檢測

    使用上述代碼對檢測圖像角點,結(jié)果如下:

    img = cv2.imread('wujiaoxing.jpg') img1 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) img2 = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)draw(img2,Har_Lap_corners_detect(img1))

    Perfect!!!這次大作業(yè)有底了,逃出生天,哈哈哈哈哈~
    下面換一個難一點的圖試試看

    img = cv2.imread('door.jpg') img1 = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) img2 = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)draw(img2,Har_Lap_corners_detect(img1))

    。。。。這畫的什么鬼

    此處是編程過程中的小發(fā)現(xiàn),與主題無關(guān)可不看
    * 破案了,其實在MATLAB中卷積計算conv2(A,G,‘same’)與圖像濾波fitler2(G,A)的計算差不多,就是相差了一個G矩陣旋轉(zhuǎn)180度。但是對于高斯核G而言,其旋轉(zhuǎn)180度不變,所以在這種情況下,此兩者等價。
    * 矩陣的卷積運算和我想的差不多,矩陣對應(yīng)元素的相乘之后求和。
    * matlab中的filter2計算和CV2中的cv2.filter2D 差不多,除了CV2中會把小于0的點直接設(shè)置為0

    Harris-Laplace和Harris角點檢測算法(勝利就在眼前了,加油!!!)

    設(shè)計實驗,對圖像進行縮放和旋轉(zhuǎn),比較Harris-Laplace和Harris角點檢測算法的穩(wěn)定性

    實驗數(shù)據(jù)

    實驗數(shù)據(jù)來自圖像數(shù)據(jù)集網(wǎng)站,Affine Covariant Features,選擇6張存在旋轉(zhuǎn)和放縮的圖片,如下圖紅框所示:

    實驗結(jié)果

    • 分別采用Harris以及Harris-Laplace算法對這六張圖片進行角點檢測,統(tǒng)計出角點的數(shù)量,如下表所示:

    可見,Harris-Laplace算法檢測出的角點數(shù)量要比Harris算法少得多。

    • 可以用重復(fù)率來衡量角點檢測算法的穩(wěn)定性,重復(fù)率定義如下:r=NbpreNbinir = \frac{{{N_{bpre}}}}{{{N_{bini}}}}r=Nbini?Nbpre??
      式中,NbpreN_{bpre}Nbpre?表示圖像變化后檢測出的角點,NbiniN_{bini}Nbini?是的原始圖像檢測出的角點,本實驗中原始圖像選擇為img1.重復(fù)率表示圖像變化后檢測出來的角點與未發(fā)生變化時檢測出來的角點之比,因此重復(fù)率越高,表示角點檢測算子越穩(wěn)定。實驗結(jié)果如下圖所示:

    由上圖可見,在同樣的旋轉(zhuǎn)和縮放條件下,Harris-Laplace檢測算子的穩(wěn)定性要高于Harris角點檢測算子。

    總結(jié)

    • 角點一般可以認為是物體邊緣的一些拐點,屬于圖像特征信息,在很多場景下有用
    • Harris-Laplace算子是在傳統(tǒng)Harris算子基礎(chǔ)上引入尺度空間得到的,增強了傳統(tǒng)算子的尺度不變性
    • 通過實驗發(fā)現(xiàn),Harris-Laplace算子所檢測到的角點數(shù)目比傳統(tǒng)Harris算子少得多,而且在同樣的旋轉(zhuǎn)和縮放條件下更穩(wěn)定。
    • 代碼使人頭大,這也太頂了吧!!!不管了,我肝不動了,就這樣吧。
    • 經(jīng)驗教訓(xùn):這一次把大量的時間花在了代碼的實現(xiàn)上,導(dǎo)致之后的時間很少,實驗做得很水,很多場景以及參數(shù)的比較都沒有做,下一次代碼可能就沒有這么細致了,能調(diào)庫就調(diào)庫,給前期的算法賞析(“賞析”這個詞用得真好)以及后期的實驗環(huán)節(jié)多一點時間。

    參考文獻

  • K. Mikolajczyk and C. Schmid. Scale & affine invariant interest point detectors. International Journal of Computer Vision, 2004
  • matlab實現(xiàn):《現(xiàn)代數(shù)字圖像處理技術(shù)提高及應(yīng)用案例詳解(MATLAB版)》趙小川
  • 人工智能:harris角點檢測
  • 總結(jié)

    以上是生活随笔為你收集整理的Harris-Laplace角点检测初探+python实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。