次のように、マトリックスに 0 と 1 の論理円形マスクがあります。
別の行列の外側の境界だけを取得する最速の方法は何ですか?
基本的に、行に重複する 1 がある場合、各行の左から最初の 1 と右から最初の 1 をスキャンする必要があります (一番上、一番下のポイントに 1 が 1 つだけあります)。これを行うための高速な方法を見つける?
次のように、マトリックスに 0 と 1 の論理円形マスクがあります。
別の行列の外側の境界だけを取得する最速の方法は何ですか?
基本的に、行に重複する 1 がある場合、各行の左から最初の 1 と右から最初の 1 をスキャンする必要があります (一番上、一番下のポイントに 1 が 1 つだけあります)。これを行うための高速な方法を見つける?
そのためにregionpropsを使用できます。円を識別するいくつかの例を次に示します。
または、円が 1 つだけでノイズがないことが確実な場合は、下/上/左/右の端を見つけて、そこから作業できると思います。
m = loadcirclefunction();
pix_left = find(any(m,1),1,'first');
pix_right = find(any(m,1),1,'last');
pix_top = find(any(m,2),1,'first');
pix_bottom= find(any(m,2),1,'last');
他の答えは、画像内の一般的な円を見つけるのに適していますが、バイナリ マスク内の円を探していることがわかっているため、おそらく bwmorph が最善の策です。
I=imread('0ateM.png');
BW=im2bw(I);
BW2=bwmorph(BW,'endpoints');
編集: コメントで述べたように、円を拡大して、元の円マスクのすぐ外側の 0 ピクセルを 1 に設定し、他のすべてを 0 に設定するには、元のマスクを反転してから bwmorph を使用できます:
WB=-(BW-1);
WB2=bwmorph(WB,'endpoints');
これには、画像の境界線が 1 に変更されるという不幸な副作用があります。もちろん、これは簡単に変更できます。mxn 画像の場合:
WB2(1,:)=0; WB2(:,1)=0; WB2(:,n)=0; WB2(m,:)=0;
別のアプローチは、元の画像にフィルターを直接使用することです。
f=[1 1 1; 1 -9 1; 1 1 1];
G=filter2(f,BW);
BW2=im2bw(G);
これにより、上記の WB2 と同じ結果が得られ、白い枠の問題は発生しません。このim2bw
呼び出しが必要なのは、フィルタ後の値が 0 または 1 ではなく、-8 から 8 の間の範囲になり、負の値を 0 に、正の値を 1 にしたいからです。
ブルートフォースは画像のサイズに比例します。画像をコピーする必要があるため、方法を改善してもあまり得られないというのが私の意見です。それにもかかわらず、それは非常に高速である必要があり、画像上の任意の数の円に対して機能します.
function bound = find_bound(circle)
[sy sx] = size(circle);
bound = circle;
for i = 2:sy-1
for j = 2:sx-1
if (~circle(i,j))
bound(i,j) = any((circle(i-1:i+1,j-1:j+1)-circle(i,j))(:));
end
end
end