如何在 Matlab 的一个特定方向上模糊图像?

How to blur an image in one specific direction in Matlab?

我有一张图片,我想使用 Matlab 在一个特定的方向和距离上对其进行模糊处理。

我发现有一个名为 fspecial('motion',len,theta) 的过滤器。

这里有一个例子:

I = imread('cameraman.tif');
imshow(I);
H = fspecial('motion',20,45);
MotionBlur = imfilter(I,H,'replicate');
imshow(MotionBlur);

然而模糊的图片在2个方向上都模糊了!在本例中为 225 度和 45 度。 它应该怎么做才能在特定方向(例如 45)而不是两个方向模糊它?

我想你想要所谓的 "comet" kernel。我不确定 "motion" 模糊使用的是什么内核,但根据您提供的图像,我猜它是对称的。

这里有一些代码可以用来在一个方向上应用 comet 内核。如果你想要一个任意角度,你将不得不改变周围的东西。你可以从输出中看到它在一个方向上涂抹,因为只有一侧有黑色带(由于那里缺少像素)。

L = 5; % kernel width
sigma=0.2; % kernel smoothness

I = imread('cameraman.tif');
x = -L:1.0:L;

[X,Y] = meshgrid(x,x);
H1 = exp((-sigma.*X.^2)+(-sigma.*Y.^2));
kernel = H1/sum((H1(:)));

Hflag = double((X>0));
comet_kernel = Hflag.*H1;
comet_kernel=comet_kernel/sum(comet_kernel(:));

smearedImage = conv2(double(I),comet_kernel,'same');

imshow(smearedImage,[]);

更新代码:这将对彗星内核应用任意旋转。还要注意前面示例中的 sigma 与此处的 sxsy 之间的区别,它们控制内核的长度和宽度参数,正如 Andras 在评论中所建议的那样。

L = 5; % kernel width
sx=3;
sy=10;
theta=0;

I = imread('cameraman.tif');
x = -L:1.0:L;

[X,Y] = meshgrid(x,x);
rX = X.*cos(theta)-Y.*sin(theta);
rY = X.*sin(theta)+Y.*cos(theta);
H1 = exp(-((rX./sx).^2)-((rY./sy).^2));
Hflag = double((0.*rX+rY)>0);
H1 = H1.*Hflag;
comet_kernel = H1/sum((H1(:)))

smearedImage = conv2(double(I),comet_kernel,'same');

imshow(smearedImage,[]);

基于我写了这段代码完全解决了我的问题:

L = 10; % kernel width
sx=0.1;
sy=100;
THETA = ([0,45,90,135,180,225,270,320,360])*pi/180;
for i=1:length(THETA)

    theta=(THETA(i)+pi)*-1;

    I = imread('cameraman.tif');
    x = -L:1.0:L;

    [X,Y] = meshgrid(x,x);
    rX = X.*cos(theta)-Y.*sin(theta);
    rY = X.*sin(theta)+Y.*cos(theta);
    H1 = exp(-((rX./sx).^2)-((rY./sy).^2));
    Hflag = double((0.*rX+rY)>0);
    H1 = H1.*Hflag;
    comet_kernel = H1/sum((H1(:)));

    smearedImage = conv2(double(I),comet_kernel,'same');

     % Fix edges
    smearedImage(:,[1:L, end-L:end]) = I(:,[1:L, end-L:end]); % Left/Right edge
    smearedImage([1:L, end-L:end], :) = I([1:L, end-L:end], :); % Top/bottom edge

    % Keep only inner blur
    smearedImage(L:end-L,L:end-L) = min(smearedImage(L:end-L,L:end-L),double(I(L:end-L,L:end-L)));


    figure
    imshow(smearedImage,[]);
    title(num2str(THETA(i)*180/pi))
    set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
end