1

我有一个白色/黑色的图像。我想将高斯滤波器应用于此图像上的白色像素。但是,我想逐个像素地应用它,因为我想为不同的像素提供不同的高斯带宽参数。

例如,图像上只有 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'); 
4

1 回答 1

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);

其中xy是位置,sig是带宽。假设WIDTHHEIGHT是图像的尺寸,您可以将合成结果图像初始化为 flat out = zeros(HEIGHT, WIDTH);。过滤器大小的查找向量可能是flt_size = [10, 15, 20];. 在一些for-loop over 中sig = [1, 3],我们在收集与特定 sigma 对应的所有像素之后创建覆盖的每个“幻灯片”

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

例子

于 2013-02-07T04:04:39.943 回答