我有一张白/黑的图像。我想对此图像上的白色像素应用高斯滤镜。但是,我想逐像素地应用它,因为我想为不同的像素提供不同的高斯带宽参数。
例如,图像上只有2个像素是白色,其他像素是黑色。我想对这2个像素应用不同的高斯滤波器。假设X [2]和Y [2]是2个像素的坐标。
Gaussian bandwidth for X[0] and Y[0] is [10, 10], standard deviation is 1.
Gaussian bandwidth for X[1] and Y[1] is [20, 20], standard deviation is 3.
我知道roifilt2可以在ROI上工作,但它似乎只适用于图像区域而不是单个像素。我在检查ROI处理后按照我的理解编码,但下面的代码给出了错误:
Error using imwrite (line 422)
Image data can not be empty.
Error in guassianFilter (line 73)
imwrite(out,[outdir,imname,'.png'],'png');
过滤后的输出图像似乎是空的。但我是matlab的新手,我不知道为什么会这样,以及如何解决它。 :(
我可以直接调用任何matlab函数来完成这项工作吗?
代码:
while ischar(tline)
line = regexp(tline,' ','split');
if(strcmp(line{1},'touch') == 1)
c = floor(str2double(line{1,3})); % same as X[0] as I mentioned above
r = floor(str2double(line{1,4})); % same as Y[0] as I mentioned above
BW = roipoly(im,c,r);
G = fspecial('gaussian',[10 10],1);
out = roifilt2(G,im,BW);
end
if(strcmp(line{1},'dT') == 1)
c = floor(str2double(line{1,3})); % same as X[1] as I mentioned above
r = floor(str2double(line{1,4})); % same as X[1] as I mentioned above
BW = roipoly(im,c,r);
G = fspecial('gaussian',[20 20], 3);
out = roifilt2(G,im,BW);
end
tline = fgets(fid);
end
fclose(fid);
imname=strtok(imList(cnt).name,'.');
imwrite(out,[outdir,imname,'.png'],'png');
答案 0 :(得分:1)
在概述一个应该有效的想法之前,让我观察一下您发布的代码的一个问题。查看对roifilt2
的调用,您会看到out
被您从文件中读取的每个单像素指令的结果覆盖。即使你发现了导致结果空图像的其他一些错误,结果也永远不会是复合结果。
这个怎么样?您可以先从文件中读取所有像素位置和相应的带宽,然后单独从这些坐标以两个笔划重建滤波后的图像。读取像素列表可能看起来像这样
fid = fopen('points.txt');
pxl = struct('x', {}, 'y', {}, 'sig', {});
n_pxl = 0;
tline = fgets(fid);
while ischar(tline)
line = regexp(tline,' ','split');
n_pxl = n_pxl + 1;
pxl(n_pxl).x = floor(str2double(line{1,3}));
pxl(n_pxl).y = floor(str2double(line{1,4}));
if strcmp(line{1},'touch') == 1
pxl(n_pxl).sig = 1;
elseif strcmp(line{1},'dT') == 1
pxl(n_pxl).sig = 3;
else
pxl(n_pxl).sig = nan;
end
tline = fgets(fid);
end
fclose(fid);
其中x
和y
是位置,sig
是带宽。假设WIDTH
和HEIGHT
是图片的尺寸,您可以将合成结果图像初始化为展平out = zeros(HEIGHT, WIDTH);
。您的过滤器大小的查找向量可以是flt_size = [10, 15, 20];
。在某些for
- 循环sig = [1, 3]
上,我们创建了每个"幻灯片"在收集与特定西格玛相对应的所有像素之后,覆盖的一部分
im_raw = zeros(HEIGHT, WIDTH);
for k = find([pxl.sig] == sig)
im_raw(pxl(k).y, pxl(k).x) = 1;
end
并使用过滤操作的结果递增合成
fsz = flt_size(sig);
out = out + conv2(im_raw, fspecial('gaussian', [fsz, fsz], sig), 'same');
总之,循环可能会这样:
out = zeros(HEIGHT, WIDTH);
flt_size = [10, 15, 20];
for sig = [1, 3]
im_raw = zeros(HEIGHT, WIDTH);
for k = find([pxl.sig] == sig)
im_raw(pxl(k).y, pxl(k).x) = 1;
end
fsz = flt_size(sig);
out = out + conv2(im_raw, fspecial('gaussian', [fsz, fsz], sig), 'same');
end
使用略大的带宽进行说明,这里有一个例子,每个类别中有两个点。左图和中图显示每个"幻灯片",右图显示复合图像。每张图片均按imagesc
缩放显示。