-
2022-07-14 11:40:52
前言
无
一、角点是神马?
角点被定义为图像边缘曲线上曲率极大值的点或图像亮度变化剧烈的点 ,这些点既保留了图像的重要特征,又有效地减少了信息的数据量。
二、Harris角点检测算法原理
Harris算法以 Morave算法为基础,如果某一点朝任一方向发生小小的偏移都能引起灰度的较大变化 ,那么就认为该点是角点.简单易学的解释,但想要详细了解Harris算法可查看我推荐的博文。
图像特征之Harris角点检测_skycrygg的博客-CSDN博客_harris角点检测
步骤
1.计算x y 方向的梯度值Mat_x,Mat_y
代码如下(示例):
//Step1 //1.1 创建x与y方向内核 Mat xKernel = (Mat_<double>(1, 3) << -1, 0, 1); //[-1,0,1] x方向 Mat yKernel = xKernel.t();//反转矩阵。 该方法通过矩阵表达式进行矩阵求逆。 //Mat yKernel = (Mat_<double>(3, 1) << -1, 0, 1); //[-1 // 0 // 1] y方向 //1.2卷积获取x与y方向的梯度值 Mat Ix, Iy; filter2D(gray, Ix, CV_64F, xKernel); filter2D(gray, Iy, CV_64F, yKernel);
2.计算Mat_xx,Mat_yy,Mat_xy
代码如下(示例):
//Step2 //计算Mat_xx,Mat_yy,Mat_xy Mat Ix2, Iy2, Ixy; Ix2 = Ix.mul(Ix);// 执行两个矩阵按元素相乘 获取Mat_xx。 Iy2 = Iy.mul(Iy);// 执行两个矩阵按元素相乘 获取Mat_yy。 Ixy = Ix.mul(Iy);// 执行两个矩阵按元素相乘 获取Mat_xy。
3.利用高斯函数对Mat_xx,Mat_yy,Mat_xy进行滤波
代码如下(示例):
//Step3 //3.1获取高斯滤波内核 Mat gaussKernel = getGaussianKernel(7,1); //3.2利用高斯函数对Mat_xx,Mat_yy,Mat_xy进行滤波 filter2D(Ix2, Ix2, CV_64F, gaussKernel); filter2D(Iy2, Iy2, CV_64F, gaussKernel); filter2D(Ixy, Ixy, CV_64F, gaussKernel);
4.计算局部特征结果矩阵M的特征值和响应函数
代码如下(示例):
//Step4 //计算局部特征结果矩阵M的特征值和响应函数 //C(i,j) = Det(M) - k(trace(M)^2) k∈(0.04,0.06] Mat cornerStrength(gray.size(),CV_64F); int width = gray.size().width; int height = gray.size().height; for (int h = 0; h < height; h++) { for (int w = 0; w < width; w++) { //M = [Ix2,Ixy // Ixy,Iy2] //det = Ix2 * Ix2 - Ixy^2 //trace = Ix2 + Iy2 //C = det - k * trace double det_m = Ix2.at<double>(h, w) * Iy2.at<double>(h, w) - pow(Ixy.at<double>(h, w), 2); double trace_m = Ix2.at<double>(h, w) + Iy2.at<double>(h, w); cornerStrength.at<double>(h, w) = det_m - k * trace_m * trace_m; } }
5.将计算完的响应函数的值C进行非极大值抑制,滤除边缘与非角点的点,保留满足大于设定的阈值的区域
代码如下(示例):
//Step5 //5.1寻找最大值 double maxStrength; minMaxLoc(cornerStrength,NULL,&maxStrength,NULL,NULL); //5.2非极大值抑制 Mat dilated; dilate(cornerStrength,dilated,Mat()); Mat localMax; compare(cornerStrength,dilated,localMax,CMP_EQ); //5.3保留满足大于设定的阈值 Mat cornerMap; double qualityLevel = 0.01; double thresh = qualityLevel * maxStrength; cornerMap = cornerStrength > thresh;// 大于标识符重载函数 // 等同于threshold(cornerStrength,cornerMap,thresh,255,THRESH_BINARY) bitwise_and(cornerMap,localMax,cornerMap);
6.找出角点
代码如下(示例):
// Iterate over the pixels to obtain all feature points 迭代像素以获得所有特征点 for (int y = 0; y < cornerMap.rows; y++) { const uchar* rowPtr = cornerMap.ptr<uchar>(y); //行指针 for (int x = 0; x < cornerMap.cols; x++) { // if it is a feature point 如果是特征点(像素值非0值为特征点) if (rowPtr[x]) { points.push_back(cv::Point(x, y)); } } }
三、Harris角点算法的实现(完整版)
//算法原理步骤 //1.计算x y 方向的梯度值Mat_x,Mat_y //2.计算Mat_xx,Mat_yy,Mat_xy //3.利用高斯函数对Mat_xx,Mat_yy,Mat_xy进行滤波 //4.计算局部特征结果矩阵M的特征值和响应函数 //C(i,j) = Det(M) - k(trace(M)^2) k∈(0.04,0.06] //5.将计算完的响应函数的值C进行非极大值抑制,滤除边缘与非角点的点,保留满足大于设定的阈值的区域 //6.找出角点 void myDetecHarrisCornerAlgorithm(const Mat& src, vector<cv::Point> &points, double k) { Mat gray; if (src.channels() == 3) { cvtColor(src, gray, COLOR_BGR2GRAY); } else if (src.channels() == 1) { gray = src.clone(); } else { cout << "Image channnels is Error! " << endl; return ; } gray.convertTo(gray,CV_64F); //Step1 //1.1 创建x与y方向内核 Mat xKernel = (Mat_<double>(1, 3) << -1, 0, 1); //[-1,0,1] x方向 Mat yKernel = xKernel.t();//反转矩阵。 该方法通过矩阵表达式进行矩阵求逆。 //Mat yKernel = (Mat_<double>(3, 1) << -1, 0, 1); //[-1 // 0 // 1] y方向 //1.2卷积获取x与y方向的梯度值 Mat Ix, Iy; filter2D(gray, Ix, CV_64F, xKernel); filter2D(gray, Iy, CV_64F, yKernel); //Step2 //计算Mat_xx,Mat_yy,Mat_xy Mat Ix2, Iy2, Ixy; Ix2 = Ix.mul(Ix);// 执行两个矩阵按元素相乘 获取Mat_xx。 Iy2 = Iy.mul(Iy);// 执行两个矩阵按元素相乘 获取Mat_yy。 Ixy = Ix.mul(Iy);// 执行两个矩阵按元素相乘 获取Mat_xy。 //Step3 //3.1获取高斯滤波内核 Mat gaussKernel = getGaussianKernel(7,1); //3.2利用高斯函数对Mat_xx,Mat_yy,Mat_xy进行滤波 filter2D(Ix2, Ix2, CV_64F, gaussKernel); filter2D(Iy2, Iy2, CV_64F, gaussKernel); filter2D(Ixy, Ixy, CV_64F, gaussKernel); //Step4 //计算局部特征结果矩阵M的特征值和响应函数 //C(i,j) = Det(M) - k(trace(M)^2) k∈(0.04,0.06] Mat cornerStrength(gray.size(),CV_64F); int width = gray.size().width; int height = gray.size().height; for (int h = 0; h < height; h++) { for (int w = 0; w < width; w++) { //M = [Ix2,Ixy // Ixy,Iy2] //det = Ix2 * Ix2 - Ixy^2 //trace = Ix2 + Iy2 //C = det - k * trace double det_m = Ix2.at<double>(h, w) * Iy2.at<double>(h, w) - pow(Ixy.at<double>(h, w), 2); double trace_m = Ix2.at<double>(h, w) + Iy2.at<double>(h, w); cornerStrength.at<double>(h, w) = det_m - k * trace_m * trace_m; } } //Step5 //5.1寻找最大值 double maxStrength; minMaxLoc(cornerStrength,NULL,&maxStrength,NULL,NULL); //5.2非极大值抑制 Mat dilated; dilate(cornerStrength,dilated,Mat()); Mat localMax; compare(cornerStrength,dilated,localMax,CMP_EQ); //5.3保留满足大于设定的阈值 Mat cornerMap; double qualityLevel = 0.01; double thresh = qualityLevel * maxStrength; cornerMap = cornerStrength > thresh;// 大于标识符重载函数 // 等同于threshold(cornerStrength,cornerMap,thresh,255,THRESH_BINARY) bitwise_and(cornerMap,localMax,cornerMap); //Step6 // Iterate over the pixels to obtain all feature points 迭代像素以获得所有特征点 for (int y = 0; y < cornerMap.rows; y++) { const uchar* rowPtr = cornerMap.ptr<uchar>(y); //行指针 for (int x = 0; x < cornerMap.cols; x++) { // if it is a feature point 如果是特征点(像素值非0值为特征点) if (rowPtr[x]) { points.push_back(cv::Point(x, y)); } } } }
四.角点检测效果
总结
无
更多相关内容 -
Harris角点检测算法
2018-10-02 10:44:57harris角点检测 算法代码和说明文档。采用matlab编写的。压缩文件里面包含m文件,dox说明为文档,ppt说明文档,以及检测用的图片 -
基于像素点灰度差的Harris角点检测算法
2021-02-25 03:30:17针对Harris算法在图像处理过程中特征点提取实时性和抗噪能力较差、计算量大的问题,提出一种结合像素点灰度差的Harris角点检测算法。将被检测点与半径为3的邻近圆周上16个像素点作对比,以此计算非相似像素点的个数来... -
一种改进的Harris角点检测算法
2021-03-10 23:20:14角点是图像的重要特征。对经典的Harris算法进行了理论分析和...结果表明,对Harris角点检测算法中的参数进行改进后,能够更加突出角点背景的对比度,在一定层度上降低了阈值选取的复杂度。结果由于经典Harris 算法。 -
基于Sobel边缘检测的圆周Harris角点检测算法
2020-05-08 19:43:21提出一种基于Sobel边缘检测的圆周Harris角点检测算法:首先采用Sobel边缘检测进行角点预筛选,本质上提高检测效率;随后采用圆周窗口模板对筛选后的角点进行非极大值抑制,减少漏检点与伪角点的个数;最后采用临近点剔除... -
Harris角点检测算法概述
2021-02-23 18:05:33Harris角点检测算法Harris角点检测算法概述
角点特征的提取一般是取某点为中心的窗口计算响应值,然后筛选出响应值显著的点为角点。一般认为,如果一个点是角点,则以角点为中心的窗口向任何方向滑动时,窗口内灰度分布变化均应该较大;如果一个点是边缘点,则滑动窗口时在边缘走向上灰度分布基本不变而垂直边缘的方向上变化剧烈。如图所示,经典的角点提取算子有Moravec算子和Harris算子。Moravec算子分别统计当前点所在窗口向水平、竖直、对角线和反对角线四个方向滑动一个像素时的灰度变化平方和,也就是统计四个方向的灰度梯度平方和,取这四个值中的最小值作为该点的兴趣值:若这一指标大于某阈值,则说明在四个方向上灰度都变化大,该点很可能为角点,经过非极大值抑制后保留真正的角点。这一算法计算简便,但是容易受噪声影响。
Harris算子与Moravec算子出发点类似,讨论了角点和非角点的窗口灰度分布特点。而Harris算子考虑了噪声影响,在计算中引入了使用高斯卷积核(下式),且更进一步导出了新的判断测度。
w u , v = e − u 2 + v 2 2 σ 2 w_{u,v}=e^{-\frac{u^2+v^2}{2\sigma^2}} wu,v=e−2σ2u2+v2
如下式所示, I ( x , y ) I(x,y) I(x,y)表示图像灰度函数(连续的二元函数),窗口向任意方向滑动 ( d x , d y ) (dx,dy) (dx,dy)时,窗口内的灰度变化情况为加权的差分平方和;窗口内的像素点 ( u , v ) (u,v) (u,v)处作一阶泰勒展开后舍去二次小项,并进一步整理得到一个二次型,其的性质由矩阵 M M M反映。
E d x , d y = ∑ ( u , v ) ∈ N b w u , v [ I d x + u , d y + v − I u , v ] 2 = ∑ ( u , v ) ∈ N b w u , v [ ∂ I ∂ x d x + ∂ I ∂ y d y + o ( d x 2 , d y 2 ) ] 2 = ∑ ( u , v ) ∈ N b ( w u , v ∂ I ∂ x 2 ) ( d x ) 2 + 2 ∑ ( u , v ) ∈ N b w u , v ∂ I ∂ x ∂ I ∂ y d x d y + ∑ ( u , v ) ∈ N b ( w u , v ∂ I ∂ y 2 ) ( d y ) 2 = A d x 2 + B d y 2 + 2 C d x d y = [ d x d y ] M [ d x d y ] \begin{aligned} E_{dx,dy} &= \sum_{(u,v)\in{N_{b}}}{w_{u,v}[I_{dx+u,dy+v}-I_{u,v}]^2}\\ &= \sum_{(u,v)\in{N_{b}}}{w_{u,v}[\frac{\partial I}{\partial x}dx+\frac{\partial I}{\partial y}dy+o(dx^2,dy^2)]^2}\\ &= \sum_{(u,v)\in{N_{b}}}{(w_{u,v}\frac{\partial I}{\partial x}^2)}(dx)^2+2\sum_{(u,v)\in{N_{b}}}{w_{u,v}\frac{\partial I}{\partial x}\frac{\partial I}{\partial y}}dxdy+\sum_{(u,v)\in{N_{b}}}{(w_{u,v}\frac{\partial I}{\partial y}^2)}(dy)^2\\ &= Adx^2+Bdy^2+2Cdxdy\\ &= \begin{bmatrix}dx&dy\end{bmatrix} M \begin{bmatrix}dx\\dy\end{bmatrix} \end{aligned} Edx,dy=(u,v)∈Nb∑wu,v[Idx+u,dy+v−Iu,v]2=(u,v)∈Nb∑wu,v[∂x∂Idx+∂y∂Idy+o(dx2,dy2)]2=(u,v)∈Nb∑(wu,v∂x∂I2)(dx)2+2(u,v)∈Nb∑wu,v∂x∂I∂y∂Idxdy+(u,v)∈Nb∑(wu,v∂y∂I2)(dy)2=Adx2+Bdy2+2Cdxdy=[dxdy]M[dxdy]
其中 A = ∑ ( u , v ) ∈ N b ( w u , v ∂ I ∂ x 2 ) A=\sum_{(u,v)\in{N_{b}}}{(w_{u,v}\frac{\partial I}{\partial x}^2)} A=∑(u,v)∈Nb(wu,v∂x∂I2), B = ∑ ( u , v ) ∈ N b ( w u , v ∂ I ∂ y 2 ) B=\sum_{(u,v)\in{N_{b}}}{(w_{u,v}\frac{\partial I}{\partial y}^2)} B=∑(u,v)∈Nb(wu,v∂y∂I2), C = ∑ ( u , v ) ∈ N b w u , v ∂ I ∂ x ∂ I ∂ y C=\sum_{(u,v)\in{N_{b}}}{w_{u,v}\frac{\partial I}{\partial x}\frac{\partial I}{\partial y}} C=∑(u,v)∈Nbwu,v∂x∂I∂y∂I, M = [ A C C B ] M=\begin{bmatrix}A&C\\C&B\end{bmatrix} M=[ACCB]
M M M的具体计算即下式所示:
M = ∑ ( u , v ) ∈ N b w u , v [ I x 2 I x I y I x I y I y 2 ] M=\sum_{(u,v)\in{N_{b}}}w_{u,v} \begin{bmatrix} I_{x}^{2} & I_{x}I_{y}\\ I_{x}I_{y} & I_{y}^{2} \end{bmatrix} M=(u,v)∈Nb∑wu,v[Ix2IxIyIxIyIy2]
M M M可以特征分解为以 M = A T P A M=A^{T}PA M=ATPA的形式, A A A是正交矩阵; P P P是对角阵,主对角线元素为特征值,所以上面式子可以分解为这一形式:
E x , y ≈ [ d x ′ d y ′ ] [ λ 1 0 0 λ 2 ] [ d x ′ d y ′ ] E_{x,y}\approx \begin{bmatrix}dx'&dy'\end{bmatrix} \begin{bmatrix} \lambda_{1} & 0\\ 0 & \lambda_{2} \end{bmatrix} \begin{bmatrix}dx'\\ dy'\end{bmatrix} Ex,y≈[dx′dy′][λ100λ2][dx′dy′]
而 [ d x ′ d y ′ ] = A [ d x d y ] \begin{bmatrix}dx'\\ dy'\end{bmatrix}=A\begin{bmatrix}dx\\ dy\end{bmatrix} [dx′dy′]=A[dxdy]
是正交变换后的窗口平移滑动矢量。如果两个特征值 λ 1 , λ 2 \lambda_1,\lambda_2 λ1,λ2都比较大,则说明窗口向任何方向滑动都导致较大的灰度变化,当前点很可能为角点;如果只有其中一个比较大,则说明可能是边缘点。因此,将两个特征值的大小情况作为角点判据是合理的。
实际上借助式\eqref{eq:Rindex}构造了指标 R = d e t ( M ) − k ⋅ [ t r ( M ) ] 2 R=det(M)-k·[tr(M)]^{2} R=det(M)−k⋅[tr(M)]2避免进行特征分解的不必要计算。 R R R称为响应值函数,它综合反映了两个特征值的情况;R为正值时,值越大,越可能是角点。R的取值与两特征值的情况见图~\ref{fig:Rindex}d e t ( M ) = λ 1 ∗ λ 2 t r ( M ) = λ 1 + λ 2 \begin{aligned} det(M)&=\lambda_{1}*\lambda_{2}\\ tr(M)&=\lambda_{1}+\lambda_{2} \end{aligned} det(M)tr(M)=λ1∗λ2=λ1+λ2
算法的具体步骤如下:
- 计算窗口内每个像素的梯度;
- 按照\eqref{eq:Mexpansion}计算梯度自相关矩阵的带权和矩阵 M M M;
- 从矩阵 M M M计算性能指标R,如果大于给定阈值则保留;
- 全部像素处理后进行非极大值抑制。
-
harris角点检测算法的改进
2014-05-04 20:30:05harris角点检测算法的改进,比传统角点检测算法更强大,matlab程序 -
harris角点检测算法实现
2021-07-23 22:54:54算法流程: 1、将图像转换为灰度图像; 2、利用Sobel滤波器求出 海森矩阵 (Hessian matrix) : 3、将高斯滤波器分别作用于Ix²、Iy²、IxIy;...4、计算每个像素的 R= ...=max(R) * th 的像素点即为角点。th常取0...算法流程:
1、将图像转换为灰度图像;
2、利用Sobel滤波器求出 海森矩阵 (Hessian matrix) :
3、将高斯滤波器分别作用于Ix²、Iy²、IxIy;
4、计算每个像素的 R= det(H) - k(trace(H))²。det(H)表示矩阵H的行列式,trace表示矩阵H的迹。通常k的取值范围为[0.04,0.16];
5、满足 R>=max(R) * th 的像素点即为角点。th常取0.1。
python代码实现:
#!/usr/bin/env python3 # coding: utf-8 import cv2 import copy import numpy as np def bgr2gray(img): gray = 0.2126 * img[..., 2] + 0.7152 * img[..., 1] + 0.0722 * img[..., 0] gray = gray.astype(np.uint8) return gray def sobel_filtering(gray): # get shape img_h, img_w = gray.shape # sobel kernel sobel_y = np.array(((1, 2, 1), (0, 0, 0), (-1, -2, -1)), dtype=np.float32) sobel_x = np.array(((1, 0, -1), (2, 0, -2), (1, 0, -1)), dtype=np.float32) # padding tmp = np.pad(gray, (1, 1), 'edge') # prepare ix = np.zeros_like(gray, dtype=np.float32) iy = np.zeros_like(gray, dtype=np.float32) # get differential for y in range(img_h): for x in range(img_w): ix[y, x] = np.mean(tmp[y: y + 3, x: x + 3] * sobel_x) iy[y, x] = np.mean(tmp[y: y + 3, x: x + 3] * sobel_y) ix2 = ix ** 2 iy2 = iy ** 2 ixy = ix * iy return ix2, iy2, ixy def gaussian_filtering(I, k_size=3, sigma=3): # get shape img_h, img_w = I.shape # gaussian i_t = np.pad(I, (k_size // 2, k_size // 2), 'edge') # gaussian kernel K = np.zeros((k_size, k_size), dtype=np.float32) for x in range(k_size): for y in range(k_size): _x = x - k_size // 2 _y = y - k_size // 2 K[y, x] = np.exp(-(_x ** 2 + _y ** 2) / (2 * (sigma ** 2))) K /= (sigma * np.sqrt(2 * np.pi)) K /= K.sum() # filtering for y in range(img_h): for x in range(img_w): I[y, x] = np.sum(i_t[y: y + k_size, x: x + k_size] * K) return I def corner_detect(img, ix2, iy2, ixy, k=0.04, th=0.1): # prepare output image out = copy.deepcopy(img) # get R R = (ix2 * iy2 - ixy ** 2) - k * ((ix2 + iy2) ** 2) # detect corner out[R >= np.max(R) * th] = [255, 0, 0] out = out.astype(np.uint8) return out def harris_corner(img): # 1. grayscale gray = bgr2gray(img) # 2. get difference image ix2, iy2, ixy = sobel_filtering(gray) # 3. gaussian filtering ix2 = gaussian_filtering(ix2, k_size=3, sigma=3) iy2 = gaussian_filtering(iy2, k_size=3, sigma=3) ixy = gaussian_filtering(ixy, k_size=3, sigma=3) # 4. corner detect out = corner_detect(img, ix2, iy2, ixy) return out def main(): # Read image img = cv2.imread("test.jpg") img = cv2.resize(img, (512, 512)) img = img.astype(np.float32) # Harris corner detection out = harris_corner(img) cv2.imwrite("out.jpg", out) print("proc ok.") if __name__ == "__main__": main()
结果:
opencv python版本实现:
对于每一个像素(x,y),在(blockSize*blockSize)邻域内,计算梯度图的协方差矩阵M(x,y) ,然后通过上面第二步中的角点响应函数得到结果图。图像中的角点可以为该结果图的局部最大值。即可以得到输出图中的局部最大值,这些值就对应图像中的角点。
Harris 角点检测函数:
cv2.cornerHarris(src, blockSize, ksize, k, dst, borderType)
src:数据类型为float32的输入图像
blockSize:角点检测中要考虑的领域大小
ksize:Sobel求导中使用的窗口大小
k:Harris 角点检测方程中的自由参数,取值参数为 [0,04,0.06].
dst:目标图像
borderType:边界类型
import cv2 import numpy as np def test(): img = cv2.imread("test.jpg") img = cv2.resize(img, (512, 512)) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = np.float32(gray) # 输入图像必须是 float32,最后一个参数在 0.04 到 0.05 之间 dst = cv2.cornerHarris(gray, 3, 3, 0.04) # result is dilated for marking the corners, not important # dst = cv2.dilate(dst, None) # Threshold for an optimal value, it may vary depending on the image. img[dst > 0.1 * dst.max()] = [255, 0, 0] cv2.imwrite("out2.jpg", img) print("proc ok.")
结果:
相关链接:
参考文章:
1、python实现Harris角点检测算法(本文代码来源)
https://www.jb51.net/article/201957.htm
2、opencv实现版本python
https://blog.csdn.net/yukinoai/article/details/88759615
3、opencv c++版本实现
-
一种改进的Harris角点检测算法 (2015年)
2021-05-22 16:11:32角点是图像的重要特征点。 对经典的 Harris 算法进行了理论分析和...结果表明,对Harris角点检测算法中的参数进行改进后,能够更加突出角点与背景的对比度,在一定程度上降低了阈值选取的复杂度,结果优于经典Harris算法。 -
【老生谈算法】Harris角点检测算法原理及其MATLAB编程实现.doc
2022-07-02 18:23:11【老生谈算法】Harris角点检测算法原理及其MATLAB编程实现.doc -
python实现Harris角点检测算法
2021-01-13 16:18:39算法流程:将图像转换为灰度图像利用Sobel滤波器求出 海森矩阵 (Hessian matrix) :将高斯滤波器分别作用于Ix²、Iy²、IxIy计算每个像素的 R= det(H) - k(trace...=max(R) * th 的像素点即为角点。th常取0.1。Harri...算法流程:
将图像转换为灰度图像
利用Sobel滤波器求出 海森矩阵 (Hessian matrix) :
将高斯滤波器分别作用于Ix²、Iy²、IxIy
计算每个像素的 R= det(H) - k(trace(H))²。det(H)表示矩阵H的行列式,trace表示矩阵H的迹。通常k的取值范围为[0.04,0.16]。
满足 R>=max(R) * th 的像素点即为角点。th常取0.1。
Harris算法实现:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# Harris corner detection
def Harris_corner(img):
## Grayscale
def BGR2GRAY(img):
gray = 0.2126 * img[..., 2] + 0.7152 * img[..., 1] + 0.0722 * img[..., 0]
gray = gray.astype(np.uint8)
return gray
## Sobel
def Sobel_filtering(gray):
# get shape
H, W = gray.shape
# sobel kernel
sobely = np.array(((1, 2, 1),
(0, 0, 0),
(-1, -2, -1)), dtype=np.float32)
sobelx = np.array(((1, 0, -1),
(2, 0, -2),
(1, 0, -1)), dtype=np.float32)
# padding
tmp = np.pad(gray, (1, 1), 'edge')
# prepare
Ix = np.zeros_like(gray, dtype=np.float32)
Iy = np.zeros_like(gray, dtype=np.float32)
# get differential
for y in range(H):
for x in range(W):
Ix[y, x] = np.mean(tmp[y : y + 3, x : x + 3] * sobelx)
Iy[y, x] = np.mean(tmp[y : y + 3, x : x + 3] * sobely)
Ix2 = Ix ** 2
Iy2 = Iy ** 2
Ixy = Ix * Iy
return Ix2, Iy2, Ixy
# gaussian filtering
def gaussian_filtering(I, K_size=3, sigma=3):
# get shape
H, W = I.shape
## gaussian
I_t = np.pad(I, (K_size // 2, K_size // 2), 'edge')
# gaussian kernel
K = np.zeros((K_size, K_size), dtype=np.float)
for x in range(K_size):
for y in range(K_size):
_x = x - K_size // 2
_y = y - K_size // 2
K[y, x] = np.exp( -(_x ** 2 + _y ** 2) / (2 * (sigma ** 2)))
K /= (sigma * np.sqrt(2 * np.pi))
K /= K.sum()
# filtering
for y in range(H):
for x in range(W):
I[y,x] = np.sum(I_t[y : y + K_size, x : x + K_size] * K)
return I
# corner detect
def corner_detect(gray, Ix2, Iy2, Ixy, k=0.04, th=0.1):
# prepare output image
out = np.array((gray, gray, gray))
out = np.transpose(out, (1,2,0))
# get R
R = (Ix2 * Iy2 - Ixy ** 2) - k * ((Ix2 + Iy2) ** 2)
# detect corner
out[R >= np.max(R) * th] = [255, 0, 0]
out = out.astype(np.uint8)
return out
# 1. grayscale
gray = BGR2GRAY(img)
# 2. get difference image
Ix2, Iy2, Ixy = Sobel_filtering(gray)
# 3. gaussian filtering
Ix2 = gaussian_filtering(Ix2, K_size=3, sigma=3)
Iy2 = gaussian_filtering(Iy2, K_size=3, sigma=3)
Ixy = gaussian_filtering(Ixy, K_size=3, sigma=3)
# 4. corner detect
out = corner_detect(gray, Ix2, Iy2, Ixy)
return out
# Read image
img = cv.imread("../qiqiao.jpg").astype(np.float32)
# Harris corner detection
out = Harris_corner(img)
cv.imwrite("out.jpg", out)
cv.imshow("result", out)
cv.waitKey(0)
cv.destroyAllWindows()
实验结果:
原图:
Harris角点检测算法检测结果:
点个赞再走呗!
-
计算机视觉(二)HARRIS角点检测算法与SIFT
2022-03-30 18:51:07度量角点响应6.HARRIS角点检测器的响应函数7.HARRIS角点检测算法的优点8.HARRIS角点检测算法的缺点9.HARRIS角点检测实例10.寻找图像中对应点二、SIFT(尺度不变特征变换)1.SIFT的目的与意义2.SIFT算法解决的问题3.... -
harris_harris角点检测_corner_matlab图像处理_
2021-09-29 08:59:32harris corner detection for 2d -
数字图像处理编程PPT讲义-Harris角点检测算法
2022-03-28 21:23:06对Harris算法的理解 程序的目标和功能 明确编程框架和模块功能 编写各模块子程序 -
harris角点检测算法
2014-04-04 22:31:05Harris角点检测算法是由Chris Harris和Mike Stephens在1988年提出的一种特征点检测算子。算法在计算角点时用到与自相关函数相关联的矩阵M,并且使用一阶偏导来描述图像的亮度变化,微分算子可以反应像素点灰度在任意... -
一种改进的Harris角点检测算法 (2014年)
2021-04-26 07:24:01arris角点检测算法是一种经典算法,但对于大尺度图像,误检现象比较严重,并且耗时过长.本文提出一种新的检测算法,通过对圆形区域进行非极大值抑制,能够明显地降低角点检测时间,并且能够有效地减少误检.同时,... -
【计算机视觉】Harris角点检测算法的实现
2020-02-25 19:32:20Harris角点检测算法的实现Harris角点检测算法的原理基础知识角点算法思想数学表达实验实验说明代码实现不同场景下的算法分析场景一、纹理平坦1. 实验素材2. 实验结果3. 实验分析场景二、角点丰富1. 实验素材2. 实验... -
Harris角点检测算法整理1
2022-08-03 22:59:33图 1 观测窗口在图像不同区域移动二.数学推导图像中,窗口移动[, ]所产生灰度变化的自相关函数为(, ) = ∑ (, )[( + , + ) − (, )] -
Matlab实现Harris角点检测算法
2020-12-14 23:21:00角点 一般的角点检测都是对有具体定义的、或者是...目前的角点检测算法可归纳为3类:基于灰度图像的角点检测、基于二值图像的角点检测、基于轮廓曲线的角点检测。角点是图像很重要的特征,对图像图形的理解和分析有很 -
改进的harris角点检测算法
2019-01-22 21:25:10基于matlab的改进的harris角点检测算法,与harris算法可以对比。 -
Harris角点检测算法讲义.ppt
2022-05-25 12:16:08Harris角点检测算法讲义.ppt -
亚像素级的多尺度Harris角点检测算法的制作方法
2021-04-25 00:40:32本发明属于一种图像检测方法,具体为一种针对传统Harris角点的亚像素级别的检测方法。技术背景在机器视觉研究中,角点检测是一个重要环节。在摄像机标定,立体匹配,三维重建等计算机视觉处理任务中起重要作用。角点... -
改进Harris角点检测算法1
2022-08-03 15:48:03摘要:采用B样条函数替代高斯窗口函数进行数据平滑滤波,再对角点进行预筛选,获取候选角点。为提高算法的自适应性,在非极大值抑制时采用自适应阈值。进行了检测精度和效 -
Harris角点检测算法的优化研究 (2011年)
2021-06-14 01:19:41在研究Harris角点检测算法时,发现检测出的角点常常会受到噪声的影响。通过优化Har-ris角点响应函数,避免了角点响应函数中k值的影响,提高了每个目标像素点的响应值精度。把该方法运用到人脸特征的检测中,实验结果表明...