(完整版)Harris角点检测算法编程步骤及示例演示
python实现Harris角点检测算法
python实现Harris⾓点检测算法算法流程:1. 将图像转换为灰度图像2. 利⽤Sobel滤波器求出海森矩阵 (Hessian matrix) :3. 将⾼斯滤波器分别作⽤于Ix²、Iy²、IxIy4. 计算每个像素的 R= det(H) - k(trace(H))²。
det(H)表⽰矩阵H的⾏列式,trace表⽰矩阵H的迹。
通常k的取值范围为[0.04,0.16]。
5. 满⾜ R>=max(R) * th 的像素点即为⾓点。
th常取0.1。
Harris算法实现:import cv2 as cvimport numpy as npimport matplotlib.pyplot as plt# Harris corner detectiondef Harris_corner(img):## Grayscaledef BGR2GRAY(img):gray = 0.2126 * img[..., 2] + 0.7152 * img[..., 1] + 0.0722 * img[..., 0]gray = gray.astype(np.uint8)return gray## Sobeldef Sobel_filtering(gray):# get shapeH, W = gray.shape# sobel kernelsobely = 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)# paddingtmp = np.pad(gray, (1, 1), 'edge')# prepareIx = np.zeros_like(gray, dtype=np.float32)Iy = np.zeros_like(gray, dtype=np.float32)# get differentialfor 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 ** 2Iy2 = Iy ** 2Ixy = Ix * Iyreturn Ix2, Iy2, Ixy# gaussian filteringdef gaussian_filtering(I, K_size=3, sigma=3):# get shapeH, W = I.shape## gaussianI_t = np.pad(I, (K_size // 2, K_size // 2), 'edge')# gaussian kernelK = 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 // 2K[y, x] = np.exp( -(_x ** 2 + _y ** 2) / (2 * (sigma ** 2))) K /= (sigma * np.sqrt(2 * np.pi))K /= K.sum()# filteringfor 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 detectdef corner_detect(gray, Ix2, Iy2, Ixy, k=0.04, th=0.1):# prepare output imageout = np.array((gray, gray, gray))out = np.transpose(out, (1,2,0))# get RR = (Ix2 * Iy2 - Ixy ** 2) - k * ((Ix2 + Iy2) ** 2)# detect cornerout[R >= np.max(R) * th] = [255, 0, 0]out = out.astype(np.uint8)return out# 1. grayscalegray = BGR2GRAY(img)# 2. get difference imageIx2, Iy2, Ixy = Sobel_filtering(gray)# 3. gaussian filteringIx2 = 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 detectout = corner_detect(gray, Ix2, Iy2, Ixy)return out# Read imageimg = cv.imread("../qiqiao.jpg").astype(np.float32)# Harris corner detectionout = Harris_corner(img)cv.imwrite("out.jpg", out)cv.imshow("result", out)cv.waitKey(0)cv.destroyAllWindows()实验结果:原图:Harris⾓点检测算法检测结果:点个赞再⾛呗!。
Haris角点检测算子
2014.3.30 周报 Harris 角点检测算子Harris 角点检测算子是 Moravec 角点检测算子的改良( 1) Harris 算子用高斯函数取代二值窗口函数,对离中心点愈来愈近的像素给予较大的权重,以减少噪声影响。
w( x, y)1 2 e ( x 2 y 2 ) / 2 22图 1 高斯函数(2) Moravec 算子只考虑了每隔 45 度方向, Harris 算子用 Taylor 睁开去近似随意方向。
E(u, v)w( x, y)[ I ( x u, y v) I ( x, y)]2x, yw( x, y)[ I x u O(u 2 , v 2 )] 2x, y写成矩阵形式:2I x I yI x2MI xI x I y( 1-2)w( x, y)2w( x, y)2x , yI x I y I y I x I y I yE (u, v) u( 1-3)[ u, v] Mv式中, lx 为 x 方向的差分, ly 为 y 方向的差分, w(x,y) 为高斯函数。
(3)Harris 采纳了一种新的角点判断方法。
矩阵M 的两个特点向量 l 1 和 l 2 与矩阵 M 的主曲率成正比。
Harris 利用 l 1 , l 2 来表征变化最快和最慢的两个方向,若两个都很大就是角点,一个大一个小就是边沿,两个都小就是在变化迟缓的图像地区。
文档收集自网络,仅用于个人学习图 2 用矩阵M的特点向量分类图像像素点可是解特点向量需要比许多的计算量,且两个特点值的和等于矩阵M 的迹,两个特点值的积等于矩阵 M 的队列式。
所以用(1-4)式来判断角点质量。
( k 常取 0.04-0.06 )文档采集自网络,仅用于个人学习R det M k(traceM ) 2(1-4)(4) Harris 算法总结Step1:对每一像素点计算有关矩阵MA w( x, y) I x 2B w( x, y) I y2C D w( x, y) ( I x2 I y2 )A BMCDStep2:计算每个像素的 Harris 角点响应R ( AB CD ) 2 k( A B) 2Step3:在w* w范围内找寻极大值点,若Harris 角点响应大于阈值,则视为角点。
OpenCV-Python:Harris角点检测与Shi-Tomasi角点检测
OpenCV-Python:Harris⾓点检测与Shi-Tomasi⾓点检测⼀、Harris⾓点检测原理:⾓点特性:向任何⽅向移动变换都很⼤。
Chris_Harris 和 Mike_Stephens 早在 1988 年的⽂章《A CombinedCorner and Edge Detector》中就已经提出了焦点检测的⽅法,被称为Harris ⾓点检测。
将窗⼝向各个⽅向移动(u,v)然后计算所有差异的总合:表达式如下:⾓点检测中要使E(u,v)的值最⼤。
这就是说必须使⽅程的第⼆项的取值最⼤。
对上⾯的等式进⾏泰勒级数展开,然后再通过⼏步数学换算(参考其他标准教材),我们得到下⾯的等式:其中这⾥ Ix 和 Iy 是图像在 x 和 y ⽅向的导数(可以使⽤cv2.Sobel()计算得到)根据⼀个⽤来判定窗⼝内是否包含⾓点的等式进⾏打分其中λ1 和λ 2 是矩阵M的特征值所以根据这些特征中我们可以判断⼀个区域是否是⼀个⾓点、边界或是平⾯当λ1 和λ 2都⼩时,|R| 也⼩,这个区域就是⼀个平坦区域当λ 1 ≫λ 2 或者λ 1 ≪λ 2时,R⼩于0,这个区域是边缘当λ 1 和λ 2 都很⼤,并且λ 1 ~λ 2 中的时,R 也很⼤,(λ 1 和λ 2 中最⼩值都⼤于阈值),说明这个区域是⾓点⽤下图来表⽰我们的结论:所以Harris ⾓点检测的结果是⼀个由⾓点分数构成的灰度图像。
选取适当的阈值对结果进⾏⼆值化,我们就检测到了图像中的⾓点。
OpenCV中的⾓点检测使⽤ cv2.cornerHarris(),参数如下: img:数据类型为float32的输⼊图像(灰度图) blockSize:⾓点检测中要考虑的领域⼤⼩ ksize:Sobel求导中使⽤的窗⼝⼤⼩ k:Harris⾓点检测⽅程中的⾃由参数,取值参数为[0.04,0.06]import cv2import numpy as npimg = cv2.imread('blox.jpg')# 1. Harris⾓点检测基于灰度图gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 2. Harris⾓点检测dst = cv2.cornerHarris(gray, 2, 3, 0.04)# 腐蚀⼀下,便于标记dst = cv2.dilate(dst, None)# ⾓点标记为红⾊img[dst > 0.01 * dst.max()] = [0, 0, 255]cv2.imwrite('blox-RedPoint.png', img)cv2.imshow('dst', img)cv2.waitKey(0)⼆、Shi-Tomasi⾓点检测 & 适合于跟踪的图像特征Shi-Tomasi ⾓点检测是在Harris⾓点检测上进⾏了修改。
Harris角点检测
Harris⾓点检测⽬录OpenCV可以检测图像的主要特征,然后提取这些特征、使其成为图像描述符,这类似于⼈的眼睛和⼤脑。
这些图像特征可作为图像搜索的数据库。
此外,⼈们可以利⽤这些关键点将图像拼接起来,组成⼀个更⼤的图像,⽐如将许多图像放在⼀块,然后形成⼀个360度全景图像。
这⾥我们将学习使⽤OpenCV来检测图像特征,并利⽤这些特征进⾏图像匹配和搜索。
我们会选取⼀些图像,并通过单应性,检测这些图像是否在另⼀张图像中。
⼀特征检测算法有许多⽤于特征检测和提取的算法,我们将会对其中⼤部分进⾏介绍。
OpenCV最常使⽤的特征检测和提取算法有:Harris:该算法⽤于检测⾓点;SIFT:该算法⽤于检测斑点;SURF:该算法⽤于检测⾓点;FAST:该算法⽤于检测⾓点;BRIEF:该算法⽤于检测斑点;ORB:该算法代表带⽅向的FAST算法与具有旋转不变性的BRIEF算法;通过以下⽅法进⾏特征匹配:暴⼒(Brute-Force)匹配法;基于FLANN匹配法;可以采⽤单应性进⾏空间验证。
⼆特征定义那么,究竟什么是特征呢?为什么⼀副图像的某个特定区域可以作为⼀个特征,⽽其他区域不能呢?粗略的讲,特征就是有意义的图像区域,该区域具有独特特征和易于识别性。
因此⾓点及⾼密度区域都是很好的特征,⽽⼤量重复的模式或低密度区域(例如图像中的蓝⾊天空)则不是很好的特征。
边缘可以将图像分为两个区域,因此也可以看做好的特征。
斑点是与周围有很⼤差别的像素区域,也是有意义的特征。
⼤多数特征检测算法都会涉及图像的⾓点、边和斑点的识别,也有⼀些涉及脊向的概念,可以认为脊向是细长物体的对称轴,例如识别图像中的⼀条路。
⾓点和边都好理解,那什么是斑点呢?斑点通常是指与周围有着颜⾊和灰度差别的区域。
在实际地图中,往往存在着⼤量这样的斑点,如⼀颗树是⼀个斑点,⼀块草地是⼀个斑点,⼀栋房⼦也可以是⼀个斑点。
由于斑点代表的是⼀个区域,相⽐单纯的⾓点,它的稳定性要好,抗噪声能⼒要强,所以它在图像配准上扮演了很重要的⾓⾊。
完整版Harris角点检测算法编程步骤及示例演示
Harris 角点检测算法编程步骤及示例演示也不说那么多废话了,要介绍啥背景意义之类的,角点检测,顾名思义,就是检测角点,最简单的就是两条线的交点了,还有比如下国际象棋的棋盘格子的交点之类的,反正就是检测这些点。
简单将Harris 角点检测算法的思想说下,就是拿一个小窗在图像中移动,通过考察这个小窗口内图像灰度的平均变换值来确定角点。
1)如果窗口内区域图像的灰度值恒定,那么所有不同方向的偏移几乎不发生变化;2)如果窗口跨越一条边,那么沿着这条边的偏移几乎不发生变化,但是与边垂直的偏移会发生很大的变化;3)如果窗口包含一个孤立的点或者角点,那么所有不同方向的偏移会发生很大的变化。
面给出具体数学推导:设图像窗口平移量为( u,v) ,产生的灰度变化为E(u,v),有E(u,v)二sum[w(x,y)[l(x+u,y+v)-l(x,y)F2棋中w(x,y)为窗口函数, l(x+u,y+v为平移后的灰度值,l(x,y)为平移前的灰度值。
有泰勒公式展开可得:l(x+u,y+v)=l(x,y)+lx*u+ly*v+0(uA2,v八2);lx,ly分别为偏微分,在图像中为图像的方向导数因此E(u,v)=sum[w(x,y) [lx*u+ly*v+O(u八2,v八2)]八2],可以近似得到E(u,v)=sum[w(x,y) [lx*u+ly*v]^2],即E(u,v)二[u,v][lx八2,lx*ly;lx*ly,ly八2][u,v]T令M=[lx八2,lx*ly;lx*ly,ly八2],因此最后对角点的检测成了对矩阵M的特征值的分析了,令M 其特征值为x1,x2;当x1>>x2或者x2>>x1,则检测到的是边缘部分;当x1,x2都很小,图像窗口在所有移动的方向上移动灰度级都无明显变化.当X1,X2都很大时且相当,检测到的是角点。
编程时用x1,x2不方便,因此定义角点响应函数;R二det(M)-k(trace(M))八2;其中det(M)为矩阵M的行列式,trace(M)为矩阵M的迹。
harris角点检测算法步骤
harris角点检测算法步骤Harris角点检测算法步骤:一、引言Harris角点检测算法是计算机视觉中常用的角点检测算法之一。
它通过分析图像的局部灰度变化来寻找图像中的角点,被广泛应用于图像处理、物体识别、图像匹配等领域。
本文将介绍Harris角点检测算法的步骤及其原理。
二、灰度处理Harris角点检测算法首先需要将彩色图像转换为灰度图像,这是因为角点检测主要关注图像的灰度变化而非颜色信息。
通过将彩色图像的每个像素的RGB值加权平均,可以得到相应的灰度值。
三、计算梯度接下来,对灰度图像进行梯度计算。
梯度表示图像中的灰度变化,是图像中像素灰度值变化最快的方向。
通过对图像使用Sobel算子或其他梯度计算算法,可以计算出每个像素的梯度幅值和方向。
四、计算结构张量在Harris角点检测算法中,结构张量是一个重要的概念。
对于每个像素点,结构张量是一个2x2的矩阵,它描述了该像素点周围区域的灰度变化情况。
结构张量的计算公式包括对梯度幅值的平方、梯度幅值的乘积以及梯度方向的加权。
五、计算角点响应函数角点响应函数是Harris角点检测算法的核心。
它通过对结构张量进行特征值分解,得到每个像素点的角点响应值。
角点响应值的计算公式是通过特征值的乘积减去特征值的和,再乘以一个经验系数。
如果特征值的乘积较大,说明该像素点是角点。
六、非极大值抑制由于角点响应函数在角点处达到最大值,但在边缘和平坦区域也可能有较大值,为了提取出准确的角点,需要进行非极大值抑制。
在非极大值抑制过程中,对于每个像素点,比较其角点响应值与周围像素点的角点响应值,如果大于周围像素点的角点响应值,则保留,否则抑制。
七、阈值处理为了进一步提取出准确的角点,可以根据角点响应值设置一个阈值。
只有角点响应值大于阈值的像素点才被认为是角点。
阈值的选择是一个关键问题,需要根据具体应用场景和图像特点进行调整。
八、角点标记最后一步是将检测到的角点在原始图像上进行标记。
Harris角点检测算法原理及其MATLAB编程实现
%扩展图像边缘1个像素
Ix=zeros(m+2,n+2); Iy=zeros(m+2,n+2); Ix(:,2:n+1)=tmp(:,3:n+2)-tmp(:,1:n); Iy(2:m+1,:)=tmp(3:m+2,:)-tmp(1:m,:); Ix2=Ix(2:m+1,2:n+1).^2; Iy2=Iy(2:m+1,2:n+1).^2; Ixy=Ix(2:m+1,2:n+1).*Iy(2:m+1,2:n+1); h=fspecial('gaussian',[7 7],2); Ix2=filter2(h,Ix2); Iy2=filter2(h,Iy2); Ixy=filter2(h,Ixy); %滤波
在公式(2)中, I x 、 I y 是图像 I(x,y)的偏导数。这样,公式(1)就能近似表示为:
c( x, y, x, y ) ( I (u,v) I (u x,v y))
w 2
(2)
x I x(u,v) I y(u,v) y x
2
A g ( I x) I x w
2
2
B g ( I y) I y w
C g ( I xy ) I xy w
2
4) 求出每个像素的 Harris 响应值 R , 令小于阀值的响应值 R 为零;
R R : det M (traceM ) t
2
5) 进行 3×3 邻域非极大值抑制,图像中的角点用局部极大值的点表示; 6)记录下角点在原图像中的位置,即图像角点所在位置。 MATLAB运行结果如下:
Harris角点检测算法详解
不适用opencv的代码(转)//////////////////////////////////////////////////////////////////////// Construction/Destruction//////////////////////////////////////////////////////////////////////#define B(image,x,y) ((uchar *)(image->imageData+image->widthStep*(y)))[(x)*3]#define G(image,x,y) ((uchar *)(image->imageData+image->widthStep*(y)))[(x)*3+1]#define R(image,x,y) ((uchar *)(image->imageData+image->widthStep*(y)))[(x)*3+2]#define S(image,x,y) ((uchar *)(image->imageData+image->widthStep*(y)))[(x)]//卷积计算求Ix,Iy,以及滤波//a指向的数组是size1*size2(滤波器大小)大小的...求导,a 指滤波器,xwidth,ywidth指图像大小px=i-size1/2+i1;py=j-size2/2+j1;分别消掉了size1/2,size2/2,所以这样就更好理解了。
for(i=size1/2;i<ywidth-size1/2;i++)for(j=size2/2;j<xwidth-size2/2;j++)这里的size/2是为了不把图像边界算进去。
CvMat *mbys(CvMat *mat,intxwidth,intywidth,double *a,int size1,int size2)//size{inti,j;int i1,j1;intpx,py;int m;CvMat *mat1;mat1=cvCloneMat(mat);for(i=size1/2;i<ywidth-size1/2;i++)for(j=size2/2;j<xwidth-size2/2;j++){m=0;for(i1=0;i1<size1;i1++)for(j1=0;j1<size2;j1++){px=i-size1/2+i1;py=j-size2/2+j1;//CV_MAT_ELEM访问矩阵元素m+=CV_MAT_ELEM(*mat,double,px,py)*a[i1*size1+j1];}CV_MAT_ELEM(*mat1,double,i,j)=m;}return mat1;}//计算Ix2,Iy2,IxyCvMat *mbxy(CvMat *mat1,CvMat *mat2,int xwidth,intywidth){inti,j;CvMat *mat3;mat3=cvCloneMat(mat1);for(i=0;i<ywidth;i++)for (j=0;j<xwidth;j++){CV_MAT_ELEM(*mat3,double,i,j)=CV_MAT_ELEM(*mat1,double,i,j)*CV_MAT_ELEM(*mat2,double,i,j);}return mat3;}//用来求得响应度CvMat *mbcim(CvMat *mat1,CvMat *mat2,CvMat *mat3,int xwidth,intywidth){inti,j;CvMat *mat;mat=cvCloneMat(mat1);for(i = 0; i <ywidth; i++){for(j = 0; j <xwidth; j++){//注意:要在分母中加入一个极小量以防止除数为零溢出CV_MAT_ELEM(*mat,double,i,j)=(CV_MAT_ELEM(*mat1,double,i,j)*CV_MAT_ELEM(*mat2,double,i,j)- CV_MAT_ELEM(*mat3,double,i,j)*CV_MAT_ELEM(*mat3,double,i,j))/(CV_MAT_ELEM(*mat1,double,i,j)+CV_MAT_ELEM(*mat2,double,i,j)+0.000001);}}return mat;}//用来求得局部极大值CvMat *mblocmax(CvMat *mat1,int xwidth,intywidth,int size){inti,j;double max=-1000;int i1,j1;intpx,py;CvMat *mat;mat=cvCloneMat(mat1);for(i=size/2;i<ywidth-size/2;i++)for(j=size/2;j<xwidth-size/2;j++){max=-10000;for(i1=0;i1<size;i1++)for(j1=0;j1<size;j1++){px=i-size/2+i1;py=j-size/2+j1;if(CV_MAT_ELEM(*mat1,double,px,py)>max)max=CV_MAT_ELEM(*mat1,double,px,py);}if(max>0)CV_MAT_ELEM(*mat,double,i,j)=max;elseCV_MAT_ELEM(*mat,double,i,j)=0;}return mat;}//用来确认角点CvMat *mbcorner(CvMat *mat1,CvMat *mat2,int xwidth,intywidth,intsize,double thresh){CvMat *mat;inti,j;mat=cvCreateMat(ywidth,xwidth,CV_32FC1);for(i=size/2;i<ywidth-size/2;i++)for(j=size/2;j<xwidth-size/2;j++){if(CV_MAT_ELEM(*mat1,double,i,j)==CV_MAT_ELEM(*mat2,double,i,j))//首先取得局部极大值 //mat1是CRF相应的所有。
计算机视觉实验报告-Harris角点检测
1实验目的Harris角点检测阅读代码,为代码添加备注,即大致描述每一部分代码分别实现的什么功能SIFT关键点检测及特征匹配调试代码,根据代码进一步掌握算法相关步骤2实验过程2.1Harris角点检测实验图片所用代码import cv2import numpy as npimport matplotlib.pyplot as pltif __name__ == "__main__":# 1. 读取图像文件img = cv2.imread('corner.png')gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)gray = np.float32(gray)# 2. Harris角点检测dst = cv2.cornerHarris(gray, 5, 5, 0.04)dst = cv2.dilate(dst, None) # 膨胀,非极大值抑制thres = 0.01 * dst.max()finalImg = img.copy()finalImg[dst > thres] = [255, 0, 0]imgs = [img, finalImg]titles = ['Raw', 'Corner']for i in range(2):plt.subplot(1, 2, i + 1)plt.imshow(imgs[i], 'gray')plt.title(titles[i])plt.xticks([]), plt.yticks([])# 3. 显示结果plt.show()实验效果代码分析及现象算法基本思想是使用一个固定窗口在图像上进行任意方向上的滑动,比较滑动前与滑动后两种情况,窗口中的像素灰度变化程度,如果存在任意方向上的滑动,都有着较大灰度变化,那么我们可以认为该窗口中存在角点。
Harris角点检测(含Matlab函数的关键代码)[转载]
Harris⾓点检测(含Matlab函数的关键代码)[转载]在上述教程中涉及到了Harris⾓点检测的推导以及各种⾓点检测⽅法的⽐较,⾮常值得⼀看。
这⾥只是简单的整理⼀下,⽤⽩话说明⼀下Harris⾓点检测算法的步骤:1. 计算图像的⽅向导数,分别保存为两个数组Ix以及Iy,这⾥可以使⽤任何⽅法,⽐较正统的是使⽤Gaussian函数,因为在Harris⾓点检测的推导过程中默认是采⽤了Gaussian函数作为其计算图像偏导数的⽅法。
当然使⽤简单的Prewitt或者Sobel算⼦也没有关系。
2. 为每⼀个点计算局部⾃相关矩阵 u(x,y) = [Ix(x,y)^2*W Iy(x,y)Ix(x,y)*W;Ix(x,y)Iy(x,y)*W Iy(x,y)^2*W];这⾥*W代表以x,y为中⼼与⾼斯模板W做卷积,⽽这个模板的⼤⼩则需要你⾃⼰指定。
3. 如果这个u的两个特征值都很⼩,则说明这个区域是个平坦区域。
如果u的某个特征值⼀个⼤⼀个⼩,则是线,如果两个都很⼤,那么就说明这是个⾓点。
Harris提供了另⼀个公式来获取这个点是否是⾓点的⼀个评价:corness = det(u) - k*trace(u)^2;这个corness就代表了⾓点值,其中k是你⾃⼰取的⼀个固定的变量,典型的为[0.04,0.06]之间。
当然在求取了每个点的corness以后,最好再做⼀个极⼤值抑制,这样的效果⽐直接设置⼀个阀值要好。
转⾃:/prleader/archive/2009/02/23/3930571.aspx——————————————————————————————————————Matlab 中 cornermetric 函数的关键代码filter_coef = fspecial('gaussian',[1 5],1.5);w = filter_coef' * filter_coef;% compute gradientsA = imfilter(I,[-1 0 1] ,'replicate','same','conv');B = imfilter(I,[-1 0 1]','replicate','same','conv');A = A(2:end-1,2:end-1);B = B(2:end-1,2:end-1);% compute A, B, and CC = A .* B;A = A .* A;B = B .* B;% filter A, B, and CA = imfilter(A,w,'replicate','full','conv');B = imfilter(B,w,'replicate','full','conv');C = imfilter(C,w,'replicate','full','conv');% clip to image sizeremoved = (numel(filter_coef)-1) / 2 - 1;A = A(removed+1:end-removed,removed+1:end-removed);B = B(removed+1:end-removed,removed+1:end-removed);C = C(removed+1:end-removed,removed+1:end-removed); cornerness = (A .* B) - (C .^ 2) - sensitivity_factor * ( A + B ) .^ 2;。
数字图像处理编程讲义Harris角点检测算法
实际编程步骤
程序界面(一)
程序界面(一)
程序界面(二)
附:算法每一步效果的演示
参考文献
HARRIS C, STEPHENS M. “A Combined Corner and Edge Detector” Proceedings of Fourth Alvey Vision Conference. 1988, 147-151.
数字图像处理编程讲义 -Harris角点检测算法
山东大学信息科学与工程学院 2005年11月18日
准备工作- 写在我们开发一个程序之前
对Harris算法的理解 程序的目标和功能 明确编程框架和模块功能 编写各模块子程序
Harris算法的感性认识
下图是边缘的直观概念
角点:最直观的印象就是在水平、竖直两 个方向上变化均较大的点,即Ix、Iy都较大
边缘:仅在水平、或者仅在竖直方向有较 大的变化量,即Ix和Iy只有其一较大
平坦地区:在水平、竖直方向的变化量均 较小,即Ix、Iy都较小
Measurement -角点判定准则
实际编程步骤
c++ 角点算法
角点算法通常用于图像处理中来检测和识别图像中的角点。
下面是一个简单的C++示例代码,演示如何使用OpenCV库来实现角点检测。
cpp复制代码
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main() {
// 读取图像
Mat image = imread("image.jpg");
// 创建Harris角点检测器
Ptr<Detector> detector = createHarrisDetector(3, 3, 0.04, 100.0, 50);
// 检测角点
vector<Point2f> corners;
detector->detect(image, corners);
// 在图像上绘制角点
for (int i = 0; i < corners.size().size(); i++) {
circle(image, corners[i], 5, Scalar(0, 255, 0), -1);
}
// 显示结果
imshow("Harris Corner Detection", image);
waitKey(0);
return0;
}
在上述代码中,我们首先使用OpenCV库读取一张图像。
然后,我们创建一个Harris角点检测器,并使用该检测器来检测图像中的角点。
最后,我们在图像上绘制检测到的角点,并显示结果。
Harris角点检测
• 一个PPT讲义: Darya Frolova, Denis Simakov,
Matching with Invariant Features, The Weizmann Institute of Science, March 2004
R的等高线图(k=0.2)
R的等高线图(k=0.1)
R的等高线图(k=0.05)
Harris检测:数学表达
λ2 “Edge” R<0 “Corner”
R>0 • R 只与M的特征值有关 • 角点:R 为大数值正数 • 边缘:R为大数值负数 • 平坦区:R为小数值 “Flat” |R| small “Edge” R<0 λ1
λmax, λmin
快速变化的方向
M的特征值
E(u,v)的椭圆形式
(λmax)-1/2 (λmin)-1/2
缓慢变化的方向
Harris检测:数学表达
通过M的两个特征 值的大小对图像点 进行分类: λ2 “Edge” λ2 >> λ1 “Corner” λ1 和 λ2 都较大且数值 相当 λ1 ~ λ2;
C.Harris was with The Plessey Company plc. U.K. in 1988.
Harris角点检测基本思想
• 从图像局部的小窗口观察图像特征 • 角点定义 窗口向任意方向的移动都导致图像 灰度的明显变化
Harris角点检测基本思想
平坦区域: 平坦区域: 任意方向移动, 任意方向移动, 无灰度变化
图像窗口在所有方向上移 动都产生明显灰度变化
如果λ1 和 λ2 都很小, 图像窗口在所有方向上 移动都无明显灰度变化
“Flat” region
harris角点检测原理步骤说明[技巧]
一、Harris角点检测基本理论1.1 简略表达:角点:最直观的印象就是在水平、竖直两个方向上变化均较大的点,即Ix、Iy都较大边缘:仅在水平、或者仅在竖直方向有较大的变化量,即Ix和Iy只有其一较大平坦地区:在水平、竖直方向的变化量均较小,即Ix、Iy都较小角点响应R=det(M)-k*(trace(M)^2) (附录资料给出k=0.04~0.06,opencv指出是0.05-0.5,浮动较大)det(M)=λ1*λ2trace(M)=λ1+λ2R取决于M的特征值,对于角点|R|很大,平坦的区域|R|很小,边缘的R为负值。
1.2 详细描述:见附录里的ppt1.3 算法步骤其中,局部极大值可用先膨胀后与原图比较的方法求得,具体见二中源码。
二、opencv代码实现harris类[cpp]view plaincopyprint?1. #ifndef HARRIS_H2. #define HARRIS_H3. #include "opencv2/opencv.hpp"4.5. class harris6. {7. private:8. cv::Mat cornerStrength; //opencv harris函数检测结果,也就是每个像素的角点响应函数值9. cv::Mat cornerTh; //cornerStrength阈值化的结果10. cv::Mat localMax; //局部最大值结果11. int neighbourhood; //邻域窗口大小12. int aperture;//sobel边缘检测窗口大小(sobel获取各像素点x,y方向的灰度导数)13. double k;14. double maxStrength;//角点响应函数最大值15. double threshold;//阈值除去响应小的值16. int nonMaxSize;//这里采用默认的3,就是最大值抑制的邻域窗口大小17. cv::Mat kernel;//最大值抑制的核,这里也就是膨胀用到的核18. public:19. harris():neighbourhood(3),aperture(3),k(0.01),maxStrength(0.0),threshold(0.01),nonMaxSize(3){20.21. };22.23. void setLocalMaxWindowsize(int nonMaxSize){24. this->nonMaxSize = nonMaxSize;25. };26.27. //计算角点响应函数以及非最大值抑制28. void detect(const cv::Mat &image){29. //opencv自带的角点响应函数计算函数30. cv::cornerHarris (image,cornerStrength,neighbourhood,aperture,k);31. double minStrength;32. //计算最大最小响应值33. cv::minMaxLoc (cornerStrength,&minStrength,&maxStrength);34.35. cv::Mat dilated;36. //默认3*3核膨胀,膨胀之后,除了局部最大值点和原来相同,其它非局部最大值点被37. //3*3邻域内的最大值点取代38. cv::dilate (cornerStrength,dilated,cv::Mat());39. //与原图相比,只剩下和原图值相同的点,这些点都是局部最大值点,保存到localMax40. cv::compare(cornerStrength,dilated,localMax,cv::CMP_EQ);41. }42.43. //获取角点图44. cv::Mat getCornerMap(double qualityLevel) {45. cv::Mat cornerMap;46. // 根据角点响应最大值计算阈值47. threshold= qualityLevel*maxStrength;48. cv::threshold(cornerStrength,cornerTh,49. threshold,255,cv::THRESH_BINARY);50. // 转为8-bit图51. cornerTh.convertT o(cornerMap,CV_8U);52. // 和局部最大值图与,剩下角点局部最大值图,即:完成非最大值抑制53. cv::bitwise_and(cornerMap,localMax,cornerMap);54. return cornerMap;55. }56.57. void getCorners(std::vector<cv::Point> &points,58. double qualityLevel) {59. //获取角点图60. cv::Mat cornerMap= getCornerMap(qualityLevel);61. // 获取角点62. getCorners(points, cornerMap);63. }64.65. // 遍历全图,获得角点66. void getCorners(std::vector<cv::Point> &points,67. const cv::Mat& cornerMap) {68.69. for( int y = 0; y < cornerMap.rows; y++ ) {70. const uchar* rowPtr = cornerMap.ptr<uchar>(y);71. for( int x = 0; x < cornerMap.cols; x++ ) {72. // 非零点就是角点73. if (rowPtr[x]) {74. points.push_back(cv::Point(x,y));75. }76. }77. }78. }79.80. //用圈圈标记角点81. void drawOnImage(cv::Mat &image,82. const std::vector<cv::Point> &points,83. cv::Scalar color= cv::Scalar(255,255,255),84. int radius=3, int thickness=2) {85. std::vector<cv::Point>::const_iterator it=points.begin();86. while (it!=points.end()) {87. // 角点处画圈88. cv::circle(image,*it,radius,color,thickness);89. ++it;90. }91. }92.93. };94.95. #endif // HARRIS_H相关测试代码:[cpp]view plaincopyprint?1. cv::Mat image, image1 = cv::imread ("test.jpg");2. //灰度变换3. cv::cvtColor (image1,image,CV_BGR2GRAY);4.5.6. // 经典的harris角点方法7. harris Harris;8. // 计算角点9. Harris.detect(image);10. //获得角点11. std::vector<cv::Point> pts;12. Harris.getCorners(pts,0.01);13. // 标记角点14. Harris.drawOnImage(image,pts);15.16. cv::namedWindow ("harris");17. cv::imshow ("harris",image);18. cv::waitKey (0);19. return 0;相关测试结果:三、改进的Harris角点检测从经典的Harris角点检测方法不难看出,该算法的稳定性和k有关,而k是个经验值,不好把握,浮动也有可能较大。
包含sobel检测子的harris角点检测matlab代码 -回复
包含sobel检测子的harris角点检测matlab代码-回复如何使用Matlab实现包含Sobel检测子的Harris角点检测算法引言:Harris角点检测算法是计算机视觉领域中常用的特征点检测算法。
它可以在图像中自动检测出具有角点特征的位置,对于图像特征提取、物体识别、图像拼接等任务有广泛的应用。
在本文中,我们将介绍如何使用Matlab 实现Harris角点检测算法,并对其中涉及的Sobel检测子进行解释和实现。
一、Harris角点检测算法简介Harris角点检测算法是由Chris Harris和Mike Stephens在1988年提出的。
它通过计算图像中每个像素点的局部特征,来判断该像素点是否具有角点特征。
Harris角点检测算法的核心思想是利用图像的灰度变化,即图像中局部区域的灰度变化在不同方向上有较大的差异,而平坦区域的灰度变化在各个方向上变化较小。
二、Sobel检测子简介Sobel检测子是一种常用的边缘检测算子,用于检测图像中的边缘。
它通过比较像素点的灰度值来确定边缘的位置。
Sobel检测子是基于梯度的方法,它通过计算图像在两个方向上的灰度梯度来确定边缘的位置。
三、Matlab实现Harris角点检测算法以下是一个简单的Matlab代码示例,用于实现Harris角点检测算法并包含Sobel检测子:matlab读取图像image = imread('lena.jpg');image = rgb2gray(image); 转为灰度图像计算图像梯度dx = double(conv2(image, [1 0 -1; 2 0 -2; 1 0 -1], 'same'));dy = double(conv2(image, [1 2 1; 0 0 0; -1 -2 -1], 'same'));计算梯度矩阵中的元素dx2 = dx .^ 2;dy2 = dy .^ 2;dxdy = dx .* dy;设置窗口大小、滑动窗口步长、极小值阈值windowSize = 3;step = 1;threshold = 1e-6;初始化角点矩阵corners = zeros(size(image));遍历图像中的每个点for i = 1 + windowSize / 2 : step : size(image, 1) - windowSize / 2 for j = 1 + windowSize / 2 : step : size(image, 2) - windowSize / 2计算窗口中的梯度矩阵dx2_sum = sum(sum(dx2(i - windowSize / 2 : i + windowSize / 2, j - windowSize / 2 : j + windowSize / 2)));dy2_sum = sum(sum(dy2(i - windowSize / 2 : i + windowSize / 2, j - windowSize / 2 : j + windowSize / 2)));dxdy_sum = sum(sum(dxdy(i - windowSize / 2 : i + windowSize / 2, j - windowSize / 2 : j + windowSize / 2)));计算角点响应函数R = (dx2_sum * dy2_sum - dxdy_sum ^ 2) - 0.04 * (dx2_sum + dy2_sum) ^ 2;根据阈值判断是否是角点if R > thresholdcorners(i, j) = R;endendend显示检测结果imshow(image);hold on;[x, y] = find(corners > threshold);plot(y, x, 'r*');hold off;在以上代码中,我们首先读取一张图像,并将其转换为灰度图像。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Harris角点检测算法编程步骤及示例演示
也不说那么多废话了,要介绍啥背景意义之类的,角点检测,顾名思义,就是检测角点,最简单的就是两条线的交点了,还有比如下国际象棋的棋盘格子的交点之类的,反正就是检测这些点。
简单将Harris角点检测算法的思想说下,就是拿一个小窗在图像中移动,通过考察这个小窗口内图像灰度的平均变换值来确定角点。
(1)如果窗口内区域图像的灰度值恒定,那么所有不同方向的偏移几乎不发生变化;
(2)如果窗口跨越一条边,那么沿着这条边的偏移几乎不发生变化,但是与边垂直的偏移会发生很大的变化;
(3)如果窗口包含一个孤立的点或者角点,那么所有不同方向的偏移会发生很大的变化。
下面给出具体数学推导:
设图像窗口平移量为(u,v),产生的灰度变化为E(u,v),
有E(u,v)=sum[w(x,y)[I(x+u,y+v)-I(x,y)]^2],其中w(x,y)为窗口函数,
I(x+u,y+v)为平移后的灰度值,I(x,y)为平移前的灰度值。
有泰勒公式展开可得:
I(x+u,y+v)=I(x,y)+Ix*u+Iy*v+O(u^2,v^2);
Ix,Iy分别为偏微分,在图像中为图像的方向导数.
因此E(u,v)=sum[w(x,y) [Ix*u+Iy*v+O(u^2,v^2)]^2],
可以近似得到E(u,v)=sum[w(x,y) [Ix*u+Iy*v]^2],即
E(u,v)=[u,v][Ix^2,Ix*Iy;Ix*Iy,Iy^2][u,v]T
令M=[Ix^2,Ix*Iy;Ix*Iy,Iy^2],因此最后对角点的检测成了对矩阵M的特征值的分析了,令M其特征值为x1,x2;
当x1>>x2或者x2>>x1,则检测到的是边缘部分;
当x1,x2都很小,图像窗口在所有移动的方向上移动灰度级都无明显变化.
当X1,X2都很大时且相当,检测到的是角点。
编程时用x1,x2不方便,因此定义角点响应函数;
R=det(M)-k(trace(M))^2;
其中det(M)为矩阵M的行列式,trace(M)为矩阵M的迹。
下面给出更具数学公式实际编程的步骤:
1.利用水平,竖直差分算子对图像的每个像素进行滤波以求得
Ix,Iy,进而求得M中的四个元素的值。
M=[Ix^2,Ix*Iy;Ix*Iy,Iy^2]
2.对M的四个元素进行高斯平滑滤波,为的是消除一些不必要
的孤立点和凸起,得到新的矩阵M。
3.接下来利用M计算对应每个像素的角点响应函数R,即:
R=det(M)-k(trace(M))^2;
也可以使用改进的R:
R=[Ix^2*Iy^2-(Ix*Iy)^2]/(Ix^2+Iy^2);里面没有随意给定的参数k,取值应当比第一个令人满意。
4.在矩阵R中,同时满足R(i,j)大于一定阈值threshold和R(i,j)
是某领域内的局部极大值,则被认为是角点。
下面给出程序代码:还不错,自己一步步查资料写的,还算详细。
function main
clc;
clear;
close all;
%The coner points extractions using Harris methods;
frame=imread('*.jpg');
figure(1);
imshow(frame);
%调用harris角点检测子函数;
%输入参数解释:frame为输入图像,7为高斯滤波窗口大小,2为均方差sigma的值,
%0,04为推荐的k值,winsize为极大抑制窗口的大小且给参数时为奇数;
%输出参数解释:posX为检测到角点X坐标,posY为检测到角点Y坐标,
%cnt为检测到角点的个数,Out_Image为输出图像;
[posX,posY,cnt,Out_Image]=conerdetection(frame,7,2,0.04,7) ; %输出的图像已经是2值化的
figure(2);
imshow(Out_Image);
hold on;
plot(posX,posY,'ro','MarkerSize',15);
disp(cnt);
end
function
[posX,posY,cnt,Out_Image]=conerdetection(frame,GaussWindow,s igma,k,winsize)
%ImageData: gracyscale image of input
%GaussWindow: The sizes of Gauss window
%sigma:The variance
%default value
%winsize为极大抑制窗口大小
Out_Image=frame;
ImageData=frame;
ImageData= double(ImageData(:,:,2)); %ImageData数据矩阵式一个三通道的,我们角点标记只需选择一个可以;
%ImageData=im2bw(ImageData,0.5); %或者将3通
道的的图像转换成2值化的图像,完成提取;
%算法解释:
%1:利用水平,竖直差分算子对图像的每个像素进行滤波以求得Ix,Iy,进而求得M矩阵中四个元素的值;
%M=[Ix*Ix,Ix*Iy;Ix*Iy,Iy*Iy]
orig_image=ImageData;
fx=[-2,-1,0,1,2];
Ix=filter2(fx,orig_image);
fy=[-2;-1;0;1;2];
Iy=filter2(fy,orig_image);
Ix2=Ix.*Ix;
Iy2=Iy.*Iy;
Ixy=Ix.*Iy;
%2:对M的四个元素进行高斯平滑滤波,得到新的矩阵M;
%滤波平滑,消除突出点,得到新的矩阵M;
h=fspecial('gaussian',[GaussWindow,GaussWindow],sigma);
%建立滤波算子
Ix2=filter2(h,Ix2); %filter2是用h滤波器放在Ix2移动进行模板滤波
Iy2=filter2(h,Iy2); %消除y方向上的突兀点
Ixy=filter2(h,Ixy);
%提取前的图像矩阵的预处理;
height=size(orig_image,1); %返回图像矩阵的行数给高
width=size(orig_image,2); %返回图像矩阵的列数给宽
result=zeros(height,width); % 纪录角点位置,角点处值为1
R=zeros(height,width); %创建与图像矩阵大小相同的零矩阵
Rmax=0; % 图像中最大的R 值
%3:接下来利用M计算对应于每个像素的角点响应函数Cim(即R);
%计算公式为:R=det(M)-k*(trace(M))^2,其中k为一个任意数,经验选取0.04就可以;
%由于k的取值有些太随意,因此,改用此公式,用新的公式定义R:R=det(M)/Tr(M);
%即Cim=R=[Ix*Ix*Iy*Iy-(Ix*Iy)*(Ix*Iy)]/[Ix*Ix+Iy*Iy];
for i=1:height
for j=1:width
M=[Ix2(i,j),Ixy(i,j);Ixy(i,j),Iy2(i,j)]; %%自相关矩阵
R(i,j)=det(M)-0.04*(trace(M))^2; %% 计算R 值,det()求一个方阵的行列式(Determinant);trace()求方阵的迹,即该方阵对角线上元素之和;
if R(i,j)>Rmax
Rmax=R(i,j);
end
end
end
%winsize为非极大抑制窗口
winr=(winsize-1)/2; %the radius of the neighborhood
istart=winr+1;
jstart=winr+1;
iend=height-winr;
jend=width-winr;
cnt=0;
for i=istart:iend
for j=jstart:jend
subr=R((i-winr):(i+winr),(j-winr):(j+winr)); %取出winr*winr这块区域里面的的矩阵;
subrmax=max(max(subr));
if(R(i,j)>k*Rmax)&&(R(i,j)==subrmax)
result(i,j)=1;
cnt=cnt+1;
end
end
end
[posY,posX]=find(result==1);
% %cnt为检测出来的角点的个数;
% figure(2);
% imshow(orig_image);
% hold on;
% plot(posX,posY,'ro','MarkerSize',15);
% disp(cnt);
end
以下这幅图就是角点检测的一个实际例子:
当然这幅图像是用手机随便照的,如果做标定肯定是不能满足的。
下面这幅是使用标准的黑白棋盘格时的角点检测值:。