これは、画像処理でよくある問題です。典型的な答えは、形状の重心を見つけ、重心と各角点の間の角度を見つけることです。[0,360)
角度が度の間の範囲になるように表現されていることを確認してください。これを取得したら、角度を並べ替え、結果の順序を使用してポイントの順序を決定します。
あなたが提示した画像には、作業を開始できるように、少し前処理が必要です。StackOverflow から直接画像を読み込み、黒い星が白くなるように画像を反転します。数字も削除する必要があるため、bwareaopen
テキストの小さな領域を削除します。それが完了したら、 を介してこの画像のコーナー検出を実行し、を 0.3corner
に設定して、10 個のコーナーを検出できるようにします。QualityFactor
非常に具体的に:
%// Read image from StackOverflow
im = rgb2gray(imread('http://i.stack.imgur.com/dpbpP.jpg'));
%// Threshold the image and area open it
im_thresh = im <= 100;
im_open = bwareaopen(im_thresh, 50);
%// Detect corner points
out = corner(im_open, 'QualityLevel', 0.3);
%// Show the image with the corner points
imshow(im_open);
hold on
plot(out(:,1), out(:,2), 'r.')
im_open
最終的に処理された画像が含まれています。これは私が得るものです:

では、重心を求めましょう。これは、ゼロ以外の位置の座標を見つけ、各次元の平均を見つけることで簡単に実行できます。
[rows, cols] = find(im_open);
cenX = mean(cols);
cenY = mean(rows);
cenX
画像の重心の位置がcenY
含まれます。(x,y)
正しいことを確認するために:
imshow(im_open);
hold on;
plot(cenX, cenY, 'r.', 'MarkerSize', 18);
我々が得る:

非常に素晴らしい。さて、out
前のコードに(x,y)
はコーナーポイントのポイントが含まれています。重心から各角点までの角度を決定し、角度を並べ替えるだけです。この並べ替え順序を使用してコーナー ポイントを再配置し、配置したポイントを取得します。時計回りにしたい場合は、値を昇順で並べ替える必要があります。反時計回りにしたい場合は、降順でソートする必要があります。何を決定するかはあなたにお任せしますが、両方を実行できるコードを書きます。したがって、単純に次のようにします。
%// Determine angles (in degrees)
angles = atan2d(out(:,2) - cenY, out(:,1) - cenX);
%// Any negative angles, add 360 degrees to convert to positive
angles(angles < 0) = 360 + angles(angles < 0);
%// Sort the angles
[~,ind] = sort(angles); %// clockwise
%[~,ind] = sort(angles, 'descend'); %// counter-clockwise
%// Re-arrange the corner points to respect the order
out_reorder = out(ind,:);
最後のテストは、これらの点をプロットし、各点の横に数値をプロットして、それが正しいかどうかを確認することです. これは次の方法で実行できます。
%// Show image
imshow(im_open);
hold on;
%// Show points
plot(out_reorder(:,1), out_reorder(:,2), 'r.', 'MarkerSize', 18);
%// Place a textbox at each point and show a sequence number
for idx = 1 : size(out_reorder,1)
text(out_reorder(idx,1), out_reorder(idx,2), num2str(idx), 'FontSize', 24, 'Color', 'green');
end
我々が得る:

は、私にはよく見えますよ!そのout_reorder
ため、コーナー ポイントが時計回りまたは反時計回りの順序に従うように指定します。連続して遭遇する各行は、求める時計回りまたは反時計回りの順序に自然に従う次のポイントを提供します。
また、番号付けの開始位置にも注意してください。角度 0 は、重心に対して東を指す水平線によって定義されます。したがって、昇順で開始しているため、0 に最も近いポイントは、数字の 1 が表示されている場所です。1 の後、角のポイントがなくなるまで時計回りにスイープすることがわかります。