このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
交点角度の測定
この例では、境界トレース ルーチンである bwtraceboundary
を使用して、2 つの ビームの角度と交点を測定する方法を示します。マシン ビジョン アプリケーションに共通の作業は、イメージ取得およびイメージ処理手法を使ったハンズフリー測定です。
手順 1: イメージの読み込み
gantrycrane.png
を読み取り、2 つの注目ビームを矢印で示します。これはブリッジを組み立てるときに使用するガントリー クレーンのイメージです。
RGB = imread("gantrycrane.png"); imshow(RGB) text(size(RGB,2),size(RGB,1)+15,"Image courtesy of Jeff Mather", ... FontSize=7,HorizontalAlignment="right"); line([300 328],[85 103],Color=[1 1 0]); line([268 255],[85 140],Color=[1 1 0]); text(150,72,"Measure the angle between these beams",Color="y", ... FontWeight="bold");
手順 2: 関心領域の抽出
イメージをトリミングし、前に選択したガントリー クレーンのビームのみを取得します。この手順は、2 つの金属ビームのエッジを抽出しやすくします。
imtool
によって表示されるピクセル情報を使用して、四角形領域の座標を取得できます。
start_row = 34; start_col = 208; cropRGB = RGB(start_row:163,start_col:400,:); imshow(cropRGB)
後で使用するために、(x,y) のオフセットを格納します。各オフセットが、関心領域の前にある最後のピクセルに対応するように 1 を減算します。
offsetX = start_col-1; offsetY = start_row-1;
手順 3: イメージのしきい値処理
関数 bwtraceboundary
では、バイナリ イメージで白になる対象オブジェクトが必要になります。このため、イメージを白黒に変換してイメージの補数を取ります。
I = im2gray(cropRGB); BW = imbinarize(I); BW = ~BW; imshow(BW)
手順 4: 各境界の初期点の検出
関数 bwtraceboundary
では、境界上に 1 つのポイントを指定する必要があります。このポイントは、境界のトレース プロセスの開始位置として使用されます。
下のビームのエッジを抽出するには、イメージ内の列を選択し、バックグランド ピクセルからオブジェクト ピクセルに遷移が起きるまで確認します。後で bwtraceboundary
ルーチンで使用できるように、この位置を保存しておきます。この手順を別のビームでも繰り返しますが、今度は横方向にトレースします。
dim = size(BW); % Horizontal beam col1 = 4; row1 = find(BW(:,col1), 1); % Angled beam row2 = 12; col2 = find(BW(row2,:), 1);
手順 5: 境界のトレース
bwtraceboundary
ルーチンは、境界ポイントの (X, Y) 位置を抽出するために使用します。角度および交点の計算精度を最大にするには、ビーム エッジのポイントをできるだけ多く抽出することが重要です。ポイントの数を実験的に決定する必要があります。水平バーの初期点は北から南にスキャンして得られたので、探索ステップはオブジェクトの外側に向かうように設定するのが最も安全です ("North")。
boundary1 = bwtraceboundary(BW,[row1, col1],"N",8,70); % Set the search direction to counterclockwise, in order to trace downward boundary2 = bwtraceboundary(BW,[row2, col2],"E",8,90,"counter"); imshow(RGB) hold on % Apply offsets in order to draw in the original image plot(offsetX+boundary1(:,2),offsetY+boundary1(:,1),"g",LineWidth=2); plot(offsetX+boundary2(:,2),offsetY+boundary2(:,1),"g",LineWidth=2);
手順 6: 境界に線を適合させる
(X,Y) 座標の組み合わせは前の手順で得られましたが、すべてのポイントが線上に正確に配置されているわけではありません。角度と交点を計算するにはどのポイントを使用するのが良いでしょうか。取得したポイントがすべて等しく重要であると仮定して、境界ピクセルの位置に線を一致させます。
線の式は y = [x 1]*[a; b] です。polyfit
を使用し、最小二乗法で 'a' と 'b' のパラメーター値を求めることができます。
ab1 = polyfit(boundary1(:,2),boundary1(:,1),1); ab2 = polyfit(boundary2(:,2),boundary2(:,1),1);
手順 7: 交点角度の測定
ドット積を使用して角度を見つけます。
vect1 = [1 ab1(1)]; % Create a vector based on the line equation
vect2 = [1 ab2(1)];
dp = dot(vect1, vect2);
ベクトルの長さを計算します。
length1 = sqrt(sum(vect1.^2)); length2 = sqrt(sum(vect2.^2));
交差角度のうち、大きい方の角度を度単位で取得します。
angle = 180-acos(dp/(length1*length2))*180/pi
angle = 129.4971
手順 8: 交点の検出
交点座標 (X,Y) を取得するために 2 つの方程式を解きます。
intersection = [1 ,-ab1(1); 1, -ab2(1)] \ [ab1(2); ab2(2)];
元のトリミングされていないイメージでの位置を計算するためにオフセットを適用します。
intersection = intersection + [offsetY; offsetX]
intersection = 2×1
143.0917
295.7494
手順 9: 結果のプロット
交点に "X" を描画します。
inter_x = intersection(2); inter_y = intersection(1); plot(inter_x,inter_y,"yx","LineWidth",2);
イメージに、ビームの角度と交点の (x,y) 座標について注釈を付けます。
angleString = [sprintf("%1.3f",angle)+"{\circ}"]; text(inter_x-80,inter_y-25,angleString, ... Color="y",FontSize=14,FontWeight="bold"); intersectionString = sprintf("(%2.1f,%2.1f)",inter_x,inter_y); text(inter_x-10,inter_y+20,intersectionString,... Color="y",FontSize=14,FontWeight="bold");
参考
bwboundaries
| imbinarize
| bwtraceboundary
| polyfit