日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

OpenCV角點檢測的實現示例_python

作者:山居秋暝LS ? 更新時間: 2022-05-31 編程語言

Harris 角點檢測算法

1. 角點

角點是水平方向、垂直方向變化都很大的像素。

角點檢測算法的基本思想:?

? ? ? ? 使用一個固定窗口在圖像上進行任意方向上的滑動,比較滑動前與滑動后兩種情況,窗口中的像素灰度變化程度,如果存在任意方向上的滑動,都有著較大灰度變化,那么我們可以認為該窗口中存在角點。

? ? ? ? 目前,角點檢測算法還不是十分完善,許多算法需要依賴大量的訓練集和冗余數據來防止和減少錯誤的特征的出現。對于角點檢測算法的重要評價標準是:其對多幅圖像中相同或者相似特征的檢測能力,并且能夠應對光照變化、或者圖像旋轉等影響。

關于角點的具體描述可以有幾種:

  • 一階導數(即灰度的梯度)的局部最大所對應的像素點;
  • 兩條及兩條以上邊緣的交點;
  • 圖像中梯度值和梯度方向的變化速率都很高的點;?
  • 角點處的一階導數最大,二階導數為零,指示物體邊緣變化不連續的方向。 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

三類角點檢測算法:

  • 基于二值圖像的角點檢測;
  • 基于輪廓曲線的角點檢測;
  • 基于灰度圖像的角點檢測:基于梯度、基于模板和基于模板和梯度組合三類方法;常見的基于模板的角點檢測算法有:Kitchen-Rosenfeld角點檢測算法,Harris角點檢測算法,KLT角點檢測算法及SUSAN角點檢測算法。基于模板的方法主要是考慮像素領域點灰度的變化,即亮度的變化。

2. 流程

(1)找出角點
用高斯算子求出像素水平方向和垂直方向的梯度dx, dy,–> 對梯度的平方dxdx ,dydy, dxdy濾波得到Wxx ,Wxy,Wyy --> 在求的(WxxWyy - Wxy**2)/(Wxx + Wyy)作為候選角點。

(2)篩選角點
根據閾值篩選角點–> 取得角點的坐標 -->根據角點坐標得到角點所在的行 --> 在角點周圍,刪除掉其他角點。–> result

(3)標記角點

3. 實現

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from scipy.ndimage import filters

## 1.找出角點
### 1.1 步驟:img求導 --> imx ,imy 濾波-->Wxx ,Wxy,Wyy --> (Wxx*Wyy - Wxy**2)/(Wxx + Wyy)
def compute_harris_response(img,sigma=3):
? ? # 求梯度
? ? imgx,imgy ?= np.zeros(img.shape),np.zeros(img.shape)
? ? filters.gaussian_filter(img,(sigma,sigma),(0,1),imgx)
? ? filters.gaussian_filter(img,(sigma,sigma),(1,0),imgy) # [260,263]
? ? # 對梯度進行高斯濾波
? ? wxx = filters.gaussian_filter(imgx**2,sigma)
? ? wyy = filters.gaussian_filter(imgy**2,sigma) # [260,263]
? ? wxy = filters.gaussian_filter(imgx*imgy,sigma)# [260,263]
? ? ## 求行列式和跡
? ? wdet = wxx*wyy -wxy**2
? ? wtr = wxx + wyy
? ? return ?wdet/wtr

## 2 篩選角點
### 2.1 步驟:根據閾值篩選角點--> 取得角點的坐標 -->根據角點坐標得到角點所在的行 ?-->
# --> 在角點周圍,刪除掉其他角點
def get_harris_points(harri,min_dist=4,threshold=0.1):
? ? corner_thre = harri.max()*threshold ?# 角點閾值
? ? mask = (harri > corner_thre)*1 ?# 取出大于閾值的點為候選角點
? ? cords = np.array(mask.nonzero()).T ?# 取候選角點的坐標

? ? values = [harri[i[0],i[1]] for i in cords] ?# 候選角點的值
? ? cls = np.argsort(values) ? ? # 對角點排序得到排序后的序列號,序列號也是候選角點所在的行

? ? loc = np.zeros(harri.shape) ? # 劃出可行性區域
? ? loc[min_dist:-min_dist,min_dist:-min_dist] = 1

? ? re_cords = []
? ? for i in cls: ?# 篩選角點。先取出角點,角點周圍的點不再取出
? ? ? ? if loc[cords[i,0],cords[i,1]] == 1 :
? ? ? ? ? ? re_cords.append(cords[i])
? ? ? ? ? ? loc[cords[i,0]-min_dist:cords[i,0]+min_dist,cords[i,1]-min_dist:cords[i,1]+min_dist]=0
? ? return re_cords

def plot_harri(img,cords):
? ? plt.figure()
? ? plt.gray()
? ? plt.imshow(img)
? ? plt.plot([i[1] for i in cords],[i[0] for i in cords],'.')
? ? plt.axis('off')
? ? plt.show()

## 3 測試
if __name__ == '__main__':
? ? img = np.array(Image.open('luna.png').convert('L'))
? ? harri = compute_harris_response(img)
? ? re_cords = get_harris_points(harri)
? ? plot_harri(img,re_cords)

原文鏈接:https://blog.csdn.net/qq_35732321/article/details/123717928

欄目分類
最近更新