matlab练习程序(力场变换)
把图像中每一个像素当成有质量的恒星,像素的灰度值就相当于恒星的质量,运用万有引力定律求得每个像素受到其他像素的“力”,获得力场图像。
公式就是中学的万有引力公式,不过这里是向量场,所以每一个像素受到的力不是简单的叠加,是矢量求和。
好像有用这个力场变换识别耳朵的。
这里也是求模板大小的局部力场,全局力场我运行了1天,结果不太理想。
相关代码:
main.m
clear all; close all; clc; r=3; img=imread('lena.jpg'); img=double(img); [m n]=size(mat2gray(img)); imgn=zeros(m+2*r+1,n+2*r+1); imgn(r+1:m+r,r+1:n+r)=img; imgn(1:r,r+1:n+r)=img(1:r,1:n); imgn(1:m+r,n+r+1:n+2*r+1)=imgn(1:m+r,n:n+r); imgn(m+r+1:m+2*r+1,r+1:n+2*r+1)=imgn(m:m+r,r+1:n+2*r+1); imgn(1:m+2*r+1,1:r)=imgn(1:m+2*r+1,r+1:2*r); f_field=imgn; for i=1+r:m+r for j=1+r:n+r f=0; for p=i-r:i+r for q=j-r:j+r if i~=p &&j~=q p0=[i j]; lev=[i+10 j]; p1=[p q]; jiao=multi_jiao(p1,lev,p0); %以下四步是通过夹角定理与叉积确定向量和水平向量的夹角 flag=multi(p1,lev,p0); jiao=xiangxian(jiao,flag); jiao=mod(jiao,360); value=cos(jiao*pi/180); %通过余弦确定权重,力场是一个向量场 f=f+imgn(i,j)*imgn(p,q)/sqrt((i-p)^2+(j-q)^2)*value; %万有引力定律 end end end f_field(i,j)=f; end end figure; f_field=f_field(r+1:m+r,r+1:n+r); imshow(mat2gray(f_field));
multi_jiao.m
function re=multi_jiao(p1,p2,p0) %判断<p10,p20>夹角 x=1; y=2; vec1=p1-p0; vec2=p2-p0; re=acos(dot(vec1,vec2)/(norm(vec1)*norm(vec2)))*180/pi; end
multi.m
function re=multi(p1,p2,p0) %p10,p20叉积,获取正负 x=1; y=2; re=(p1(x)-p0(x))*(p2(y)-p0(y))-(p1(y)-p0(y))*(p2(x)-p0(x)); end
xiangxian.m
function re=xiangxian(jiao,flag) if flag>0 re=360-jiao; else re=jiao; end end
下面是运行效果:
原图
7*7的局部力场
简单的标量求和,似乎有一种朦胧美