matlab练习程序(动感模糊)

  其实在matlab中调用系统函数fspecial和imfilter这两个函数就能很简单的实现动感模糊,不过我可不想就这样简单的实现,所以就自己从头写了。动感模糊最复杂的就是构造卷积矩阵了,卷积矩阵由两个参数决定,模糊半径r和模糊角度theta,通过这两个参数,就能构造不同的模板矩阵,而图像卷积时则和普通的卷积没有什么区别。

  构造模板矩阵,首先是通过模糊半径r确定模板矩阵的宽和高,这里需要用到勾股定理,这里的r其实就相当于勾股定理中的弦,也就是斜边,那么模板的高就是r*sin(theta),宽就是r*cos(theta),为了下面卷积的方便,判断这里的宽和高,把不是奇数的加1变为奇数。然后是通过theta确定模板矩阵中数据的位置,这里只要符合h=w*tan(theta)这样一个关系的位置就都赋值r,然后对矩阵归一化就行了。当然,边界处理的细节就看下面的代码吧。

  上面是我构造矩阵的方法,和matlab与photoshop都不一样,不太清楚他们是怎样构造的,photoshop是完全不清楚,matlab是分析不出来。维基百科上有一个构造公式:http://zh.wikipedia.org/wiki/%E5%8B%95%E6%85%8B%E6%A8%A1%E7%B3%8A,不过我试了试,用这种方法好像构造不出来,if的第二个条件我不太清楚意义是什么。

下面是代码:

clear all;
close all;
clc;
r=50;           %模糊半径
jiaodu=-45;      %模糊角度
jiaodu=mod(jiaodu,360);     %经过这个处理,对所有角度均适用了。
flag=0;

%%下面是把卷积模板做出来。
if jiaodu>=0 && jiaodu<90
    jiaodu=jiaodu;
    flag=1;
end

if jiaodu>=90 && jiaodu<180
    jiaodu=180-jiaodu;
    flag=2;
end

if jiaodu>=180 && jiaodu<270
    jiaodu=jiaodu-180;
    flag=3;
end

if jiaodu>=270 && jiaodu<360
    jiaodu=360-jiaodu;
    flag=4;
end

H=floor(r*sin(jiaodu*pi/180));
W=floor(r*cos(jiaodu*pi/180));

if mod(H,2)==0
    H=H+1;
end

if mod(W,2)==0
    W=W+1;
end

w=zeros(H,W);
if jiaodu ~= 90 && jiaodu ~= 270
    for i=1:H
        for j=1:W
            tmp=floor(j*tan(jiaodu*pi/180));
            if tmp+1==i
                w(i,j)=r;
            end
        end
    end
else
    for i=1:H
        w(i,1)=r;
    end
end

w=w/sum(sum(w));
if flag==1 || flag==3       %如果角度在1,3象限,卷积矩阵上下翻转
    w=flipud(w);        
end

%%下面是正常的图像处理,卷积等
HH=floor(H/2);
WW=floor(W/2);

img=imread('lena.jpg');
img=double(img);
[m n]=size(img);
imshow(mat2gray(img));

imgn=zeros(m+2*HH+1,n+2*WW+1);
imgn(HH+1:m+HH,WW+1:n+WW)=img;

imgn(1:HH,WW+1:n+WW)=img(1:HH,1:n); 
imgn(1:m+HH,n+WW+1:n+2*WW+1)=imgn(1:m+HH,n:n+WW);
imgn(m+HH+1:m+2*HH+1,WW+1:n+2*WW+1)=imgn(m:m+HH,WW+1:n+2*WW+1);
imgn(1:m+2*HH+1,1:WW)=imgn(1:m+2*HH+1,WW+1:2*WW);

for i=HH+1:m+HH
    for j=WW+1:n+WW        
        s=imgn(i-HH:i+HH,j-WW:j+WW).*w;
        imgn(i,j)=sum(sum(s))/sum(sum(w));    
    end
end

figure;
img=imgn(HH+1:m+HH,WW+1:n+WW);
imshow(mat2gray(img));

下面是效果:

原图

这里的处理效果,半径为50,角度为-45度

photoshop中相同参数的处理效果。

posted @ 2012-11-13 13:43  Dsp Tian  阅读(2111)  评论(0编辑  收藏  举报