Harris找角点
分为3个部分
1. 直接求E找角点
2. 通过泰勒公式等求R找角点
3. 不同程度的高斯模糊后找角点
1. 直接求E的方法。
主函数:
%导入图片,转换成double型,转换成灰度图
iml=imread('iml.jpg');
imr=imread('imr.jpg');
iml=im2double(iml);
imr=im2double(imr);
iml_gray=rgb2gray(iml);
imr_gray=rgb2gray(imr);
imshow(iml_gray),title('iml_gray');
figure,imshow(imr_gray),title('imr_gray');
%调用 Harris_E( ) 计算得到矩阵E
I_big_sq=21; %大方块大小为21x21
I_little_sq=9; %在I中移动的正方形,对Harris_E中的patch_red
sigma=4; %Harris_E中的高斯矩阵的sigma
E_l=Harris_E(iml_gray, I_big_sq, I_little_sq, sigma);
E_r=Harris_E(imr_gray, I_big_sq, I_little_sq, sigma);
figure,imshow(E_l,[]),title('E_l');
figure,imshow(E_r,[]),title('E_r');
%设置阈值,筛选点
Threshold=0.2;
%筛选右图
high_Er=size(E_r,1);
wide_Er=size(E_r,2);
E_rt=zeros(high_Er, wide_Er);
for i=1:high_Er
for j=1:wide_Er
if E_r(i,j)>Threshold
E_rt(i,j)=1;
end
end
end
figure,imshow(E_rt),title('筛选后的右图E_rt');
%筛选左图
high_El=size(E_l,1);
wide_El=size(E_l,2);
E_lt=zeros(high_El, wide_El);
for i=1:high_El
for j=1:wide_El
if E_l(i,j)>Threshold
E_lt(i,j)=1;
end
end
end
figure,imshow(E_lt),title('筛选后的左图E_lt');
%在原图上框出特征
sq_keypoint(imr_gray,E_rt,I_big_sq,I_little_sq);%右图
sq_keypoint(iml_gray,E_lt,I_big_sq,I_little_sq);%左图
Harris_E函数内容:
function [ E_sq ] = Harris_E( img,I_big_sq,I_little_sq,sigma )
%输入图片的长宽
high=size(img,1);
wide=size(img,2);
%得到大小为I_little_sq的高斯矩阵
hsize=I_little_sq;
w=fspecial('gaussian',hsize,sigma);
figure,mesh(w);
%E的矩阵
%总E矩阵的高=原图每列I的个数(high/I_big_sq)*每个E矩阵的边长(移动方块往上移动格数+往下移动格数+1原始位置)
E_sq_row=((I_big_sq-1)/2-(I_little_sq-1)/2)*2+1; %一个E的row
E_sq_col=((I_big_sq-1)/2-(I_little_sq-1)/2)*2+1; %一个E的col
E_sq=zeros(fix(high/I_big_sq)*E_sq_row,fix(wide/I_big_sq)*E_sq_col); %总的E
%计算E
for i=1:(high/I_big_sq) %遍历每一大块 中心(x,y)
y=(I_big_sq+1)/2+I_big_sq*(i-1); %得到中心点y坐标
for j=1:(wide/I_big_sq)
x=(I_big_sq+1)/2+I_big_sq*(j-1); %得到中心点x坐标
%取出需要计算的原正方形
patch_red=img(y-(I_little_sq-1)/2:y+(I_little_sq-1)/2,x-(I_little_sq-1)/2:x+(I_little_sq-1)/2);
%计算中心点为(x,y)方块的对应E,遍历每个(u,v)
for v=(-1)*((I_big_sq-1)/2-(I_little_sq-1)/2):((I_big_sq-1)/2-(I_little_sq-1)/2)
for u=(-1)*((I_big_sq-1)/2-(I_little_sq-1)/2):((I_big_sq-1)/2-(I_little_sq-1)/2)
%取出移动后的正方形
patch_green=img((y-(I_little_sq-1)/2+v):(y+(I_little_sq-1)/2+v),(x-(I_little_sq-1)/2+u):(x+(I_little_sq-1)/2+u));
%计算E矩阵中的(u,v)处的值,取和(权重*(移动后-原方块))
sum=0;
for m=1:I_little_sq
for n=1:I_little_sq
sum=sum+w(m,n)*(patch_green(m,n)-patch_red(m,n));
end
end
%存储E
E_sq((i-1)*E_sq_row+(E_sq_row+1)/2+v,(j-1)*E_sq_col+(E_sq_col+1)/2+u)=sum;
end
end
end
end
end
sq_keypoint函数内容:
function sq_keypoint(imr_gray,E_rt,I_big_sq,I_little_sq)
%在原图上框出特征
high_Ert=size(E_rt,1);
wide_Ert=size(E_rt,2);
length_E=((I_big_sq-1)/2-(I_little_sq-1)/2)*2+1; %E中一块的边长
figure,imshow(imr_gray),title('找到的特征');
hold on;
for i=1:high_Ert/length_E %遍历E中每一块,取出中心点
y_E=(length_E+1)/2+(i-1)*length_E;
for j=1:wide_Ert/length_E
x_E=(length_E+1)/2+(j-1)*length_E;
for v=(-1)*(length_E-1)/2:(length_E-1)/2
for u=(-1)*(length_E-1)/2:(length_E-1)/2
if E_rt(y_E+v,x_E+u)==1 %如果该点是特征点
%找到对应在原图上的中心坐标
y=(i-1)*I_big_sq+(I_big_sq+1)/2+v;
x=(j-1)*I_big_sq+(I_big_sq+1)/2+u;
%在原图上用四条线框出特征
line([(x-(I_little_sq-1)/2) (x+(I_little_sq-1)/2)],[(y-(I_little_sq-1)/2) (y-(I_little_sq-1)/2)],'color','r');
line([(x-(I_little_sq-1)/2) (x+(I_little_sq-1)/2)],[(y+(I_little_sq-1)/2) (y+(I_little_sq-1)/2)],'color','r');
line([(x-(I_little_sq-1)/2) (x-(I_little_sq-1)/2)],[(y-(I_little_sq-1)/2) (y+(I_little_sq-1)/2)],'color','r');
line([(x+(I_little_sq-1)/2) (x+(I_little_sq-1)/2)],[(y-(I_little_sq-1)/2) (y+(I_little_sq-1)/2)],'color','r');
end
end
end
end
end
hold off;
end
2.用泰勒公式计算,计算量更少。
主函数:
>> %导入图片,转换成double型,转换成灰度图
img=imread('img.png');
img=im2double(img);
img_gray=rgb2gray(img);
imshow(img_gray),title('img_gray');
%调用Harris_corner()得到角点
threshold=10^(-7); %阈值要大于0
I_big_sq=21; %大方块大小为21x21
I_little_sq=9; %在I中移动的正方形
sigma=4; %高斯矩阵的sigma
[corner]=Harris_corner(img_gray,I_big_sq,I_little_sq,sigma, threshold);
figure,imshow(corner),title('Harris角点');
%在原图框出角点
sq_corner(img_gray,corner,I_little_sq);
Harris_corner函数内容:
function [corner]=Harris_corner( img,I_big_sq,I_little_sq,sigma,threshold)
%输入图片的长宽
high=size(img,1);
wide=size(img,2);
corner=zeros(high,wide);
%得到大小为I_little_sq的高斯矩阵
hsize=I_little_sq;
w=fspecial('gaussian',hsize,sigma);
for i=1:(high/I_big_sq) %遍历每一大块 中心(x,y)
y=(I_big_sq+1)/2+I_big_sq*(i-1); %得到中心点y坐标
for j=1:(wide/I_big_sq)
x=(I_big_sq+1)/2+I_big_sq*(j-1); %得到中心点x坐标
%遍历每个(u,v)
for v=(-1)*((I_big_sq-1)/2-(I_little_sq-1)/2):((I_big_sq-1)/2-(I_little_sq-1)/2)
for u=(-1)*((I_big_sq-1)/2-(I_little_sq-1)/2):((I_big_sq-1)/2-(I_little_sq-1)/2)
%取出移动后的正方形
patch_green=img((y+v)-(I_little_sq-1)/2:(y+v)+(I_little_sq-1)/2,(x+u)-(I_little_sq-1)/2:(x+u)+(I_little_sq-1)/2);
[ix iy]=gradient(patch_green);
lambda1=zeros(I_little_sq,I_little_sq);
lambda2=zeros(I_little_sq,I_little_sq);
%计算E矩阵中的(u,v)处的值,取和(权重*(移动后-原方块))
for m=1:I_little_sq
for n=1:I_little_sq
lambda1(m,n)=ix(m,n)*ix(m,n);
lambda2(m,n)=iy(m,n)*iy(m,n);
end
end
%计算R
alpha=0.04;
R=lambda1*lambda2-alpha*((lambda1+lambda2)^2);
%只有R大于0,并且大于阈值的时候才是角点
if R>threshold
corner(y+v,x+u)=1;
end
end
end
end
end
end
sq_corner函数 内容:
function sq_corner(img_gray,corner,I_little_sq)
%用四条线把找的的特征框出来
temp=(I_little_sq-1)/2;
figure,imshow(img_gray),title('找到的corner');
hold on;
for j=1+temp:size(corner,1)-temp
for i=1+temp:size(corner,2)-temp
if corner(j,i)==1
line([(i-temp) (i-temp)],[(j-temp) (j+temp)],'color','r');
line([(i+temp) (i+temp)],[(j-temp) (j+temp)],'color','r');
line([(i-temp) (i+temp)],[(j-temp) (j-temp)],'color','r');
line([(i-temp) (i+temp)],[(j+temp) (j+temp)],'color','r');
end
end
end
hold off;
end
3.用不同程度的高斯模糊处理图片后再找角点。
%导入图片
im1=imread('im1.png');
im1=rgb2gray(im1);
im1=im2double(im1);
>> %高斯模糊sigma1=1时
sigma1=1;
hsize=11;
B1=gao(im1,sigma1,hsize);
figure,imshow(B1,[]);
Threshold=10^(-8);%设置阈值
I_big_sq=21;
I_little_sq=9;
sigma=4;
corner_1=Harris_corner(B1, I_big_sq,I_little_sq, sigma,Threshold);
%在原图上框出特征
sq_corner(im1,corner_1,I_little_sq);
>> %高斯模糊sigma2=4时
sigma2=4;
hsize=11;
B2=gao(im1,sigma2,hsize);
figure,imshow(B2,[]);
Threshold=10^(-8);%设置阈值
I_big_sq=21;
I_little_sq=9;
sigma=4;
corner_2=Harris_corner(B2, I_big_sq,I_little_sq, sigma,Threshold);
%在原图上框出特征
sq_corner(im1,corner_2,I_little_sq);
>> %高斯模糊sigma3=10时
sigma3=10;
hsize=11;
B3=gao(im1,sigma3,hsize);
figure,imshow(B3,[]);
Threshold=10^(-8);%设置阈值
I_big_sq=21;
I_little_sq=9;
sigma=4;
corner_3=Harris_corner(B3, I_big_sq,I_little_sq, sigma,Threshold);
%在原图上框出特征
sq_corner(im1,corner_3,I_little_sq);
高斯模糊对找角点的影响。
sigma=1
sigma=4
(有时候模糊会有更多的角点)
sigma=10