web-dev-qa-db-ja.com

MATLABで画像をブロックに分割する方法は?

256x256の画像があり、それぞれ128x128の4つのブロックに分割して、A1からA4としてアドレス指定したいと思います。今度はそれらを別々に呼び出して、それらに対していくつかの操作を実行したいと思います。これはblkproc関数を使用して実行できることは知っていますが、正確にはどの程度ですか?

このようにblkprocと呼びますか?

B=blkproc(I,[4 4],?)

「?」の代わりに何を入力すればよいですか。また、作成された4つのブロックに対処するにはどうすればよいですか。

13
anubhav

blockproc (および非推奨のblkproc)は両方とも Image Processing Toolbox の関数なので、基本的なMATLABを追加すると思いました。追加のツールボックスを必要としないソリューション...

行列を部分行列に分割する場合、1つの方法は、 mat2cell を使用して行列を分割し、各部分行列をセル配列のセルに格納することです。あなたの場合、構文は次のようになります。

C = mat2cell(I, [128 128], [128 128]);

Cは2x 2のセル配列になり、各セルにはIの128x128の部分行列が格納されます。各セルで操作を実行する場合は、関数 cellfun を使用できます。たとえば、各部分行列の値の平均を取りたい場合は、次のようにします。

meanValues = cellfun(@(x) mean(x(:)), C);

最初の引数は 関数ハンドル から 無名関数 で、最初に各部分行列を列ベクトルに再形成し、次に平均を取ります。出力は、各部分行列の平均値の2行2列の行列です。 cellfunに渡す関数がセルごとに異なるサイズまたはタイプの出力を作成する場合、cellfunはそれらの連結に問題があり、エラーをスローします。

??? Error using ==> cellfun
Non-scalar in Uniform output, at index 1, output 1.
Set 'UniformOutput' to false.

cellfunへの呼び出しの最後に..., 'UniformOutput', false);を追加すると、上記の場合の出力は、代わりに2行2列のセル配列各部分行列で操作を実行した結果が含まれます。

12
gnovice

blockprocblkprocの新しい名前です(非推奨です)。画像内の各ブロックに関数を適用するために使用できます。たとえば、行列Iを8x8ブロックに分割し、各ブロックの平均を計算する場合は、次のようにします。

B=blockproc(I, [8 8], @(x) mean(x.data(:)));

Bは、ブロックの平均を含む行列です。

ここで注意すべき2つのこと:

  • 指定子[8 8]は、ブロックのnumberではなく、ブロックのsizeを指定します。

  • blockprocに渡す関数の外部では、ブロック自体にアクセスすることはできません。ブロック自体が必要な場合は、エイドリアンが提案したように行う必要があります。

    A1=I(1:128, 1:128);
    A2=I(129:256, 1:128);
    A3=I(1:128, 129:256);
    A4=I(129:256, 129:256);
    

    もちろん、実際のプログラムでは、おそらくループを使用してこれを行う必要があります。

7
Martin B

myImageが256x256の画像である場合、そうではありませんか

image_top_left = myImage(1:128,1:128);
image_top_right = myImage(1:128,129:256);
image_bottom_left = myImage(129:256,1:128);
image_bottom_right = myImage(129:256,129:256);

3
Adrien Plisson

256 * 256だけでなく、すべてのサイズの画像でプログラムを機能させる方がよいでしょう。


[row, col]=size(your_image);
mr = round(row/2); % median of rows
mc = round(col/2); % median of columns
% Now divide your image and call each of them separately and do what ever you   want
top_left  = your_image(1:mr  , 1:mc);
top_right = your_image(1:mr  , (mc+1):col); 
bot_left  = your_image((mr+1):row , 1:mc);
bot_right = your_image((mr+1):row , (mc+1):col);
% final stage is to combining these parts again to return to its original shape 
Back_to_original = [top_left,top_right ; bot_left,bot_right]; `   

これがお役に立てば幸いです。

1
saif