0

バイナリイメージによって定義された形状境界のエッジに伝播したいポイントのセットがあります。形状の境界は、1px幅の白いエッジによって定義されます。

これらの点の座標は、2行n列の行列に格納されています。形状は凹状の境界を形成し、約2500ポイントで作られた穴はありません。形状の境界に伝播したいポイントが約80〜150あります。

一連の点から直交する方向に各点から光線を当てて、どの点で形状境界と交差するかを検出したいと思います。直交方向はすでに決定されています。必要な目的のために、ポイント1とポイント+ 1を使用して、ポイントに対して計算された等高線の法線を使用して計算されます。

これを行うための最良の方法は何でしょうか?使用できるレイトレーシングアルゴリズムのようなものはありますか?

よろしくお願いします!

編集:私は質問をより明確にすることを試み、問題を説明する画像を追加しました。画像では、灰色の線は形状の輪郭を表し、赤い点は伝播したい点を表し、緑の線は架空の直交投影光線を表しています。

代替テキストhttp://img504.imageshack.us/img504/3107/orth.png

別の編集:明確にするために、各ポイントの法線を計算するために使用されるコードを投稿しました。ここで、xtとytは、各点の座標を格納するベクトルです。通常の値を計算した後、linspace関数と要求された直交線の長さを使用して伝播できます。

%#derivaties of contour
dx=[xt(2)-xt(1) (xt(3:end)-xt(1:end-2))/2 xt(end)-xt(end-1)];
dy=[yt(2)-yt(1) (yt(3:end)-yt(1:end-2))/2 yt(end)-yt(end-1)];

%#normals of contourpoints
l=sqrt(dx.^2+dy.^2);
nx = -dy./l; 
ny =  dx./l;

normals = [nx,ny];
4

2 に答える 2

0

これは、1つの形状に対してテストする単位ベクトルの数によって異なります。1つの形状と多くのテストがある場合、最も簡単な方法は、形状座標を、すでに解を暗黙的に表す極座標に変換することです。ただし、形状が異なり、すべての形状に対してテストが数回しかない場合、これはあまり効果的な解決策ではない可能性があります。

編集された質問に基づいて更新します。

光線が原点だけでなく任意の点から開始できる場合は、すべての点に対してテストする必要があります。これは、テストする光線がいずれかの座標方向の原点から開始するように形状境界を変換することで簡単に実行できます(私の例のコードでは正のx)

% vector of shape boundary points (assumed to be image coordinates, i.e. integers)
shapeBoundary = [xs, ys];

% define the start point and direction you want to test
startPoint = [xsp, ysp];
testVector = unit([xv, yv]);

% now transform the shape boundary
shapeBoundaryTrans(:,1) = shapeBoundary(:,1)-startPoint(1);
shapeBoundaryTrans(:,2) = shapeBoundary(:,2)-startPoint(2);
rotMatrix = [testVector(2), testVector(1); ...
             testVector(-1), testVector(2)];
% somewhat strange transformation to keep it vectorized
shapeBoundaryTrans = shapeBoundaryTrans * rotMatrix';

% now the test is easy: find the points close to the positive x-axis
selector = (abs(shapeBoundaryTrans(:,2)) < 0.5) & (shapeBoundaryTrans(:,1) > 0);
shapeBoundaryTrans(:,2) = 1:size(shapeBoundaryTrans, 1)';
shapeBoundaryReduced = shapeBoundaryTrans(selector, :);
if (isempty(shapeBoundaryReduced))
    [dummy, idx] = min(shapeBoundaryReduced(:, 1));
    collIdx = shapeBoundaryReduced(idx, 2);
    % you have a collision with point collIdx of your shapeBoundary
else
    % no collision
end

これはおそらくもっと良い方法で行うことができますが、あなたは考えを理解します...

于 2010-04-19T00:08:39.593 に答える
0

私があなたの問題を正しく理解している場合(各点を形状境界の最も近い点に投影する)、次のことができます

  1. sub2ind「2行n列のマトリックス」の説明を白いピクセルのBW画像に変換するために使用します。

    myimage=zeros(imagesize); myimage(imagesize, x_coords, y_coords) = 1

  2. 境界の外側imfillを埋めるために使用します

  3. 結果の画像を実行[D,L] = bwdist(BW)し、からの回答を読み取りますL

かなり簡単なはずです。

于 2010-04-19T17:57:43.740 に答える