5

次のように、マトリックスに 0 と 1 の論理円形マスクがあります。

マスク

別の行列の外側の境界だけを取得する最速の方法は何ですか?

基本的に、行に重複する 1 がある場合、各行の左から最初の 1 と右から最初の 1 をスキャンする必要があります (一番上、一番下のポイントに 1 が 1 つだけあります)。これを行うための高速な方法を見つける?

4

3 に答える 3

6

そのために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');
于 2012-11-06T00:02:10.583 に答える
4

他の答えは、画像内の一般的な円を見つけるのに適していますが、バイナリ マスク内の円を探していることがわかっているため、おそらく bwmorph が最善の策です。

I=imread('0ateM.png');
BW=im2bw(I);
BW2=bwmorph(BW,'endpoints');

bwmorph 後の画像 編集: コメントで述べたように、円を拡大して、元の円マスクのすぐ外側の 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 にしたいからです。

于 2012-11-06T00:39:55.267 に答える
0

ブルートフォースは画像のサイズに比例します。画像をコピーする必要があるため、方法を改善してもあまり得られないというのが私の意見です。それにもかかわらず、それは非常に高速である必要があり、画像上の任意の数の円に対して機能します.

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
于 2012-11-06T00:26:31.707 に答える