2017-04-20 3 views
0

私は画像内のさまざまな点を通って飛行機にフィットすることになっていますが、画像内の特定の点を通る線を強制することに問題があります。これは、特に線が90度のときに発生します。次のようにどのようにして線を正しくフィットさせ、画像の特定の点を通過させるのですか?

私のコードは次のとおりです。

I = [3 3 3 3 3 2 2 
    3 3 3 3 2 2 2 
    3 3 3 3 2 2 2 
    3 3 1 2 2 2 2 
    1 1 1 2 2 2 2 
    1 1 1 1 1 2 2 
    1 1 1 1 1 1 1]; 

% force the line through point p 
p = [3,3]; 

% points to fit plane through 
edgeA = [3,3.5; 3,4; 2.5,4; 2,4; 1.5,4]; 
edgeB = [3.5,3; 4,3; 4.5,3; 5,3]; 


% fit a plane through p and edgeA 
xws = [p(2), edgeA(:,2)']'; 
yws = [p(1), edgeA(:,1)']'; 
Cws = [xws ones(size(xws))]; 
dws = yws; 
Aeqws = [p(2) 1]; 
beqws = [p(1)]; 

planefitA = lsqlin(Cws ,dws,[],[],Aeqws, beqws); 


% fit a plane through p and edgeB 
xwn = [p(2), edgeB(:,2)']'; 
ywn = [p(1), edgeB(:,1)']'; 
Cwn = [xwn ones(size(xwn))]; 
dwn = ywn; 
Aeqwn = [p(2) 1]; 
beqwn = [p(1)]; 

planefitB = lsqlin(Cwn ,dwn,[],[],Aeqwn, beqwn); 



%%%%% plot the fitted planes: 
xAxis = linspace(0, size(I, 2), 12); 

%obtain linear curve 
fA = planefitA(1)*xAxis + planefitA(2); 
fB = planefitB(1)*xAxis + planefitB(2); 

%plot the fitted curve 
RI = imref2d(size(I),[0 size(I, 2)],[0 size(I, 1)]); 
figure, imshow(I, RI, [], 'InitialMagnification','fit')  
grid on; 
hold on; 
plot(xAxis,fA, 'Color', 'b', 'linewidth', 2); 
plot(xAxis,fB, 'Color', 'r', 'linewidth', 2); 

90 degrees lineedgeB秋のすべてのポイント。しかし、関数はこれらの点を通って間違った線をフィッティングすることになります。したがって、私はpolyfitを提案する方法がわからない、この特定の行のために

planefitB = polyfit([p(2), edgeB(:,2)'], [p(1), edgeB(:,1)'], 1); 

作品を使用しているので、私はこれを知っているが、問題は、私はこれらのプロセスは私のイメージでは異なる場所で何度も繰り返されていることであるときに、ラインがだろう90度である。

どうすればこの作品を作ることができますか?どうもありがとう。

+0

私はあなたの語彙で少し苦労しています。あなたは 'line'と' plane'を交換しています。あなたは(3,3)点が線上に正確にあり、最小二乗が他の騒々しい点に収まるように見えますか? – Peter

+0

飛行機はどこですか?すべて2dのように見えますか?ポリフィットはどこから来たのですか?上記の制約付き最適化とはどのような関係がありますか? 「私」とは何ですか?私はそれがどこでも使用されて表示されません – Peter

+0

@ピーターあなたの応答に感謝します。はい、すべての2Dです、私は今データを持っていないが、後で3次元を追加します。第二に、あなたが言ったように、私は線がポイント(3,3)を通過し、最小二乗が他のポイントにフィットするようにしたい。第3に、 'edgeB'データ内の全ての点は同一線上にあるので、このような状況で' polyfit'を使用することは適切ではありません。最後に、「私」はイメージです。すべてのデータポイントは 'I'から来ています。コードを実行すると' I'が使用されます。 – User110

答えて

0

これは、線の角度のみの最小二乗解となる。オフセットは、それが通過しなければならないという事実によって固定される(3,3)。これを表現する最も簡単な方法は、既知の交差点でデータポイントを相殺することです。つまり、データポイントから(3,3)を減算し、y=mxの場合はy=mxの場合には最高のmを適合させます。

非垂直の場合は、しかしVandermonde行列に定数1を補強していない:

slope = (edgeA(:,2) - p(2)) \ (edgeA(:,1) - p(1)); 

これはまさにあなたの制約LSQソリューションと同じ答えを与えます。

垂直線の場合:非垂直線は、y = mxの標準関数形式で表すことができます。最小二乗公式は、暗黙的に独立変数と従属変数を仮定します。垂直線はそれに従わないので、唯一の一般的な選択は、従属変数yの残差だけでなく、両方の変数の誤差を考慮する「総最小二乗」定式化です。

これを書く最も簡単な方法は、最小二乗の意味でax - byを最小にするためにaとbを選択することです。 [x_k -y_k]*[a b].'はできるだけゼロベクトルに近くなければなりません。これは、[x -y]行列の空白に最も近いベクトルです。これはsvdで計算できます。

[u s v] = svd(bsxfun(@minus, edgeA, p)); 

をVの最後の列がnullスペースに最も近いので、V(*戻ってあなたのx/yの定義は、(EDGEA-P)へのマッピング:列とfudging兆候を交換することは、私たちがちょうど直接SVDを使用することができます:、2)は線であるので、y乗数は上の位置にあり、xは下にあり、符号が反転します。 Y = MX形式に変換するには、単に分割:あなたは違った残差を扱っているので、この答えは、通常の最小二乗法よりもかなり異なるものになることを

slope = -v(2,2)/v(1,2); 

を注意、答えます。また、「傾き」を計算する最後のステップは、既に議論した理由(Infを生成する)のために垂直のケースでは機能しないため、おそらく標準化された2ベクトルコーナーケースはありません。

関連する問題