大きな座標セット(RANSACフィットを高速化するため)から、線の周りの境界ボックス内のすべてのポイントを選択する関数を作成しています。私は最後の夜に関数を含むスクリプトを実行し、合計55k秒の30k(55Mコールで)がこの行に費やされた(X
は3×Nデカルト座標です。xmin
,などはX
と同じ長さのベクトルで、境界線):MATLABの論理インデックスパフォーマンスを改善する
inlierIdx = (X(1,:) >= xmin & X(1,:) <= xmax & X(2,:) >= ymin & X(2,:) <= ymax);
これをスピードアップする方法を教えてください。パフォーマンスを向上させるための良いスタートとなる短絡は、索引付けでは機能しないようです。 p2
は、線を定義する点であり、aは境界ボックスのオフセットであり、追加のステップではさらに12k秒がかかっています。 55Mコールは):
function [inlierX, xmin, xmax, ymin, ymax] = selectbox(X, L, a) % xmin ... ymax only for plotting purposes
% X: 3xN coords to check; L: 3x2 vector defining line; a: offset of bounding box
p1 = L(:,1);
p2 = L(:,2);
constfactor = (X(3,:)-p1(3))/(p2(3)-p1(3)); % precompute for following steps
xmin = p1(1) + (p2(1)-p1(1))*constfactor - a; % line parallel to x-component of defined line, with offset
xmax = xmin + 2*a;
ymin = p1(2) + (p2(2)-p1(2))*constfactor - a;
ymax = ymin + 2*a;
inlierIdx = (X(1,:) >= xmin & X(1,:) <= xmax & X(2,:) >= ymin & X(2,:) <= ymax);
if p1(3) == p2(3) % singularity if line is horizontal, discard then
inlierIdx = [];
end
inlierX = X(:,inlierIdx); % save & return inlier coordinates
それだけでは、真の場合、計算がスキップされている場合、WHERE句ので、私はその特異点を移動しなければならないことを私に起こったが、それはマイナーなパフォーマンスヒットです。
この関数は、各RANSACサンプルに対して呼び出され、サンプリングされた線から適度な距離にある点のみを選択して、しきい値設定の距離を計算します。
MATLABバージョンはR2016aです。
Parallel Computing Toolboxが利用可能で、私はarrayfunsにステップを移動し、gpuArraysを使って関数全体を呼び出そうとしましたが、遅くなりました。検索する
prepare coordinates
while trialcount < expectedNumTrialsNeeded
draw random sample (generated array of randomly sampled coordinates and index into it)
check if sample is not degenerate and has allowed angle
compute number of inliers:
this calls my selectbox function, to select a smaller set of points, which are near enough to check - takes 30k sec of 55k
take those points and compute their distance to the line, all points within threshold are inliers - takes 12k secs of 55k
if number of inliers > best number of inliers yet, this is new best set
update expected number of trials needed to find sample of only inliers
increment trialcount
end
return best set
私は10K-100Kポイントの配列を扱う、そして各ラインのために、私は+ 5 1Eを実行収まるようにしたい... 1E + 6件の試験を次のように
全体の文脈があります最高のセット。私は約50行を収めるために、見つかった行のinliersを削除し、残ったものに対してアルゴリズムを実行することによってそれらを処理します。
さらにコードを投稿できますか?プロファイラは時には誤解を招くことがあります。特に、ループがJITされていないと... ...また、どのバージョンのMATLABを使用していますか? –
@Rody done、おめでとうございます。 –
...その他のコード?同様に、これは関数かスクリプトですか?関数を呼び出すのは何ですか? 'inlierX'だけが重要か' inlierIdx'ですか?ただあなたが持っているすべてのMWEを投稿してください! :) –