0

画像のすべてのピクセルに対して次のような操作を実行しようとしています。

方程式

Aはx*y * 4行列、wは単に1x9ベクトルです。

200x200x4x9の行列Lがあります。

Lの最初の2次元は、ピクセルの(x、y)位置です。各場所には4つの異なるサブピクセル(3次元)があります。すべてのサブピクセルにはベクトルmがあります。これは、私の方程式の最後の次元がmです。

画像全体の最初のサブピクセルの結果を取得する予定です。これを試しました。

A (:,:,1) = w * L (:, :, 1, :)  ====> Inputs must be 2-D, or at least one input must be scalar.
A (:,:,1) = w * L (:, :, 1, :)' ====> Transpose on ND array is not defined.
A (:,:,1) = w * reshape (L (:, :, 1, :), 1, 9)' ===> To RESHAPE the number of elements must not change.

L(1,1,1、:)を出力すると、個々の要素の値が得られます(ベクトルのようには見えません)。

ans(:,:,1,1) = 0.8980
ans(:,:,1,2) = 0.8065
ans(:,:,1,3) = 0.8471
ans(:,:,1,4) = 0.7607
ans(:,:,1,5) = 0.7175
ans(:,:,1,6) = 0.9020
ans(:,:,1,7) = 0.8100
ans(:,:,1,8) = 0.7640
ans(:,:,1,9) = 0.8135

編集:参考のために、

Size(A) = [200 200 4]
Size(L) = [200 200 4 9] 
Size(w) = [1 9]

編集:それは私がループを使用してそれを行う方法です

ループ

4

4 に答える 4

2

ダブルforループで行列の乗算などを使用するよりも、プロセスを逆にして、次のように短い次元でループする方がよい場合があります。

A=zeros(size(L)(1:3));
for i=1:9
    A(:,:,:)=A(:,:,:)+w(i).*L(:,:,:,i);
end

その結果、double forループを介して40000ループを実行するのではなく、合計9ループを実行します。そして、MatlabのJITAもそのようなループで動作し、さらに良い結果を生み出すと思います(私はオクターブを使用しているので、確信が持てません-オクターブのタイミングはそうではないので、タイミングテストを行う価値もありませんmatlabで有効です)。

マトリックスインデックスではなくベクトルインデックスを使用するだけで、純粋にベクトル形式でそれを行うことも可能です。それはこのように動作します:

A=zeros(size(L)(1:3));
A(:)=reshape(L,numel(A),9)*w';

このバージョンはもちろんリシェイプを使用しますが、bsxfunとsqueezeを回避し、前述の9つの値のforループを除いて他のソリューションよりも高速になると思います。

(当然、「最初のサブピクセル」のみに制限する場合は、データを制限する必要があります。forループオプションの場合は、適切な場所のコロンの代わりに1を配置します。再整形と行列の乗算の場合オプションで、表示される両方の場所でLをL(:、:、1、:)に置き換えます)

于 2013-03-17T03:23:39.493 に答える
1

squeezeベクトル形式に到達するために使用する必要があります。試す

a=squeeze(L(1,1,1,:))
于 2013-03-15T16:15:37.013 に答える
1

私は最近大ファンにbsxfunなりました。あなたを正しく理解しているとすれば、これはそれにぴったりのようです。形状を変更してから、シングルトンの寸法を自動的に拡張して入力のサイズを一致させる機能をw利用するだけです。bsxfun

w = reshape(w, [1, 1, 1, length(w)]);
A = sum(bsxfun(@times, L, w), 4);
于 2013-03-15T19:17:23.987 に答える
0

多次元乗算はMatlabでは機能しないため、実行できませんA = L * w

Mathworksページから(MATLABで多次元行列乗算を実行するにはどうすればよいですか?):

解決:

MATLABで多次元行列乗算を実行する機能は使用できません。

回避策として、FORループを使用します。

さらに、ND行列の乗算を実行するNDFUNと呼ばれるユーザー作成関数があります。詳細については、次のURLにあるNDFUNのセクションを参照してください。

http://www.mit.edu/~pwb/matlab/

ループのあるソリューションは次のようになります。

A = zeros( size(L)(1:3) );
for i = 1:size(L,1)
    for j = 1 : size(L,2)
        A(i,j,:) = squeeze( L(i,j,:,:) ) * w';
    end
end

しかし、より高速なソリューションよりも簡潔なソリューションを好む場合(ループは高速である必要があります)、回答からのアプローチを使用できます。3Dマトリックスと2Dマトリックスを乗算しsize(L) == [200 200 4 9]ます(と仮定size(w) = [1 9])。

Ac = cellfun( @(x) squeeze(x)' * w', num2cell(L,4), 'UniformOutput', false);
A = cell2mat( squeeze(Ac) );
于 2013-03-15T16:24:33.973 に答える