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

動作するはずのアイデアの概要を説明する前に、投稿したコードの問題を 1 つ観察させてください。への呼び出しをroifilt2見るとout、ファイルから読み取った各単一ピクセル命令の結果で上書きされていることがわかります。空の結果画像になる他のバグを見つけたとしても、結果は決して合成されません。

これはどう。最初にすべてのピクセル位置と対応する帯域幅をファイルから読み取り、次にこれらの座標のみから 2 回のストロークでフィルター処理された画像を再構築できます。ピクセルリストの読み取りは次のようになります

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は帯域幅です。と が画像の寸法であると仮定するWIDTHHEIGHT、合成結果の画像を flat に初期化できますout = zeros(HEIGHT, WIDTH);。フィルター サイズのルックアップ ベクトルはflt_size = [10, 15, 20];. 一部のfor-loop oversig = [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

ここでは例として、各カテゴリの 2 つのポイントについて、わずかに広い帯域幅を使用して説明します。左と中央の画像はそれぞれの「スライド」を示し、右の画像は合成を示しています。各画像は でスケーリングされて表示されimagescます。

例

于 2013-02-07T04:04:39.943 に答える