【python-openCV】画像内を3点クリック⇒なす角を計算する方法!

このページではpythonを使って、以下の動画のように画像内のクリックした3点からなす角を算出する方法をご紹介していきます。

基本的には画像内を3回左クリックするだけでOKです。

 

※Python(無料のプログラミング言語)のインストール~実行方法までは以下で解説しています。

 

スポンサーリンク

必要なライブラリ一覧

今回は以下のライブラリを使用していきます。

◆OpenCV

◆numpy

◆math

インストールしていない方はまずはインストールから始めましょう。

 

※Anacondaを使っている人はopenCV以外はインストールされているはずです。

openCVについては以下に参考記事を載せておきます。

 

スポンサーリンク

使用する画像の紹介

今回はいつものように以下の画像を使用していきます。

使用するサンプル画像の紹介

※今回は白黒画像であることを想定してコードを書いていますので、もしあなたがカラー画像で同じことを実行したい場合はいくつかコードを書き換える必要があります。

 

スポンサーリンク

角度の算出方法の紹介

今回は内積の公式を使って角度を計算していきます。

 

詳細は以下の記事で解説していますので、気になる方はまずはこちらからご覧ください。

【python-numpy】指定した3点間でのなす角を計算する方法!

 

スポンサーリンク

クリックした3点からなす角を算出するサンプルコード

それでは本題に入っていきましょう。
以下が冒頭にお見せした動画の処理を実行してくれるサンプルコードです。

※先ほど紹介した画像がこのサンプルコードと同じ場所に保存されていることを前提に書いています。

import cv2
import numpy as np
import math
file_name='sample.jpg'
img=cv2.imread(file_name,cv2.IMREAD_GRAYSCALE)
x1,y1,x2,y2=0,0,0,0
counter=0


def click_deg(event, x, y, flags, params):
    global x1,y1,x2,y2,img2,counter
    if event == cv2.EVENT_LBUTTONDOWN and counter==0:
        counter=1
        x1=x
        y1=y
    elif event == cv2.EVENT_MOUSEMOVE and counter==1:
        img2=np.copy(img)
        cv2.circle(img2,center=(x1,y1),radius=5,color=255,thickness=-1)
        cv2.line(img2,(x1,y1),(x,y),255, thickness=1, lineType=cv2.LINE_4)
        cv2.imshow('window', img2)
    elif event == cv2.EVENT_LBUTTONDOWN and counter==1:
        counter=2
        x2=x
        y2=y
    elif event == cv2.EVENT_MOUSEMOVE and counter==2:
        img2=np.copy(img)
        cv2.circle(img2,center=(x1,y1),radius=5,color=255,thickness=-1)
        cv2.line(img2,(x1,y1),(x2,y2),255, thickness=1, lineType=cv2.LINE_4)
        cv2.circle(img2,center=(x2,y2),radius=5,color=255,thickness=-1)
        cv2.line(img2,(x2,y2),(x,y),255, thickness=1, lineType=cv2.LINE_4)
        cv2.imshow('window', img2)
    elif event == cv2.EVENT_LBUTTONDOWN and counter==2:
        img2=np.copy(img)
        x3=x
        y3=y
        cv2.circle(img2,center=(x1,y1),radius=5,color=255,thickness=-1)
        cv2.line(img2,(x1,y1),(x2,y2),255, thickness=1, lineType=cv2.LINE_4)
        cv2.circle(img2,center=(x2,y2),radius=5,color=255,thickness=-1)
        cv2.line(img2,(x2,y2),(x3,y3),255, thickness=1, lineType=cv2.LINE_4)
        cv2.circle(img2,center=(x3,y3),radius=5,color=255,thickness=-1)      
        #角度計算開始
        vec1=[x2-x1,y2-y1]
        vec2=[x2-x3,y2-y3]
        absvec1=np.linalg.norm(vec1)
        absvec2=np.linalg.norm(vec2)
        inner=np.inner(vec1,vec2)
        cos_theta=inner/(absvec1*absvec2)
        theta=round(math.degrees(math.acos(cos_theta)),3)
        deg_str=str(theta)+'deg'
        cv2.putText(img2,deg_str,(30, 50),cv2.FONT_HERSHEY_PLAIN,2,255,2,cv2.LINE_AA)
        cv2.imshow('window', img2)
        counter=0
        
cv2.imshow('window', img)
cv2.setMouseCallback('window', click_deg)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

スポンサーリンク

サンプルコードの使い方

最後に先ほどのサンプルコードの使い方を説明しておきます。

 

①コードを実行すると先ほどの画像がWindow上に現れます。

②任意の場所を3回クリックします。

⇒これで左上に計測結果が表示されます。

③再度計測したい場合はまた②を実施すればOKです。

 

これで以下のような処理を実行できます。

スポンサーリンク

おわりに

というわけで今回はpython-openCVを使って、画像内のクリックした3点からなす角を算出する方法をご紹介しました。

 

実験データの分析の際などにぜひご活用ください。

 

このように、私のブログでは様々なスキルを紹介しています。

過去記事一覧

 

今は仕事中で時間がないかもしれませんが、ぜひ通勤時間中などに他の記事も読んでいただけると嬉しいです。
⇒興味をもった方は【ヒガサラ】で検索してみてください。

確実にスキルアップできるはずです。

 

最後に、この記事が役に立ったという方は、ぜひ応援よろしくお願いします。
↓ 応援ボタン
にほんブログ村 IT技術ブログへ
にほんブログ村

それではまた!

コメント

タイトルとURLをコピーしました