2013-02-07 42 views
1

我有一個白色/黑色的圖像。我想對此圖像上的白色像素應用高斯濾鏡。但是,我想逐像素地應用它,因爲我想給不同的像素提供不同的高斯帶寬參數。如何應用高斯濾波器在matlab中的圖像的單個像素?

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

回答

1

概述一個想法,應該工作之前,讓我看到一個問題的代碼你發佈了,看看你對roifilt2的調用,你會發現out被你從文件中讀取的每個單像素指令的結果覆蓋,即使你發現了一些導致空的結果圖像的其他bug,結果永遠不會複合材料。

這個怎麼樣。您可以首先從文件中讀取所有像素位置和相應的帶寬,然後從這些座標中單獨以兩個筆劃重建濾波後的圖像。讀取像素列表可以像這樣

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是圖像的尺寸,可以將複合結果圖像初始化爲平坦的out = zeros(HEIGHT, WIDTH);。篩選器大小的查找矢量可能爲flt_size = [10, 15, 20];。在一些for -loop超過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 

使用稍大的帶寬用於說明,H舉個例子,每個類別有兩點。左側和中間圖像顯示每個「幻燈片」,右側圖像顯示覆合。每個圖像顯示爲imagesc

Example

+0

非常感謝你支持!我非常感謝您的時間和精力,使其能夠理解清楚。 – Jasmine