【Python】OpenCVで動画に図形を描画する

Pythonの応用
スポンサーリンク

OpenCVを使ったPythonでの動画処理について、ここではwebカメラで撮影しているストリーム動画の画面に図形を描写してみます。

この画面への図形描写は、画像からのオブジェクト検出であるとか、機械学習などの顔認証などを行う時に、顔の部分などを四角で囲んで表示するような処理に繋がります。

すでに画像ファイルに関しての描画処理は行っていますので以下を参考にしてください。

【Python】OpenCVで線や図を描く - rectangle, circle, line, putText, polylines
PythonにOpenCVをインポートして画像に線や図を描画する方法学びます。ここでは矩形のrectangle()、円のcircle()、直線のline()、テキストのputText()、 多角形のpolylines()を扱います。

では、動画ストリームに図形を描画していきましょう。

スポンサーリンク

動画に図形を固定位置に描画する

まず、動画に四角形を特定の位置に描画するコードを書いていきます。最後に全体のコードをまとめて再掲します。

基本的なところはカメラの接続のコードがベースになります。

import cv2

cap = cv2.VideoCapture(0)

width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

OpenCVライブラリーをインポートして、VideoCapture()で0を指定してwebカメラと接続します。ここは動画ファイルのパスを指定して、保存してある動画を利用しても構いません。get()でビデオの映像の幅と高さを自動的に取得して、intでキャストして整数にしています。このあたりはこれまでの処理と同じです。

x = width//2
y = height//2

w = width//4
h = height//4

ここでは描く図形の座標と幅を画面のサイズを基準に与えています。x,yは四角の左上の座標で、w,hはそこを基準にした幅と高さです。座標を整数で与える為に小数点以下切り捨ての割り算を行っています。

while True:

    ret, frame = cap.read()
    
    cv2.rectangle(frame, (x, y), (x+w, y+h), color=(0,0,255),thickness= 4)

    cv2.imshow('frame', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

while文を使って、カメラのキャプチャーを実行しますが、全体的なコードは別のところでこれまで行ってきた処理と一緒です。read()で読み込み、imshow()で表示、if文の部分で[q]キーを押して処理を中断します。

違いは、rectangle()を用いて四角形を描く部分です。動画のframeを渡し、四角形の左上の座標と右下の座標を与え、色を赤色に指定、線の太さを4としています。

cap.release()
cv2.destroyAllWindows()

カメラを解放し、ウインドウを破棄しています。

全体のコードを再掲するとこうなります。

import cv2


cap = cv2.VideoCapture(0)

width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

x = width//2
y = height//2

w = width//4
h = height//4

while True:

    ret, frame = cap.read()

    cv2.rectangle(frame, (x, y), (x+w, y+h), color=(0,0,255),thickness= 4)

    cv2.imshow('frame', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

これをPythonファイルに保存してターミナルから実行すると次のようなイメージで映像が表示されるはずです。

webカメラで自撮りしている場合は、上記のようなイメージで表示され、赤色の四角い枠が固定された位置に描かれます。

スポンサーリンク

動画に図形をマウスでインタラクティブに描画する

上では動画の設定した位置に四角形を描画しましたが、ここではマウスで動画をクリックした位置に任意の大きさの四角形を描画する操作をしてみます。

上のコードでは最初に描画する図形の座標を変数として設定しましたが、ここではマウスのクリックで図形を描画するコールバック関数を設定していこうと思います。

マウスのクリックでの図形描画は以下でもsetMouseCallback()を使って行いましたので参照してください。

【Python】OpenCVを使ったマウス操作での直接描画 - setMouseCallback()
Pythonに画像処理ライブラリのOpenCVを使って、マウスの操作で画像を描画する方法をみていきます。マウスイベントにはEVENT_LBUTTONDOWN、EVENT_MOUSEMOVE、EVENT_LBUTTONUPなどがあります。

では、ライブラリーをインポートするところから順にコードを書いていきましょう。最後に全体のコードをまとめて再掲します。

import cv2


def draw_rectangle(event,x,y,flags,param):

    global pt1,pt2,topLeft_clicked,botRight_clicked

    if event == cv2.EVENT_LBUTTONDOWN:

        if topLeft_clicked == True and botRight_clicked == True:
            topLeft_clicked = False
            botRight_clicked = False
            pt1 = (0,0)
            pt2 = (0,0)

        if topLeft_clicked == False:
            pt1 = (x,y)
            topLeft_clicked = True

        elif botRight_clicked == False:
            pt2 = (x,y)
            botRight_clicked = True

draw_rectangle()という関数を定義します。変数にマウスの操作を示すevent、マウスの座標を示すx、y、他に必要となるフラグやパラメーターをflags、paramsを与えています。

global変数として、pt1、pt2で座標、topLeft_clicked、botRight_clickedはそれに対応した図形の左上の位置と右下の位置でのクリック操作の判定を与えます。

if event == cv2.EVENT_LBUTTONDOWN: でマウスの左ボタンかクリックされた時の動作を続けて決めていきます。

if topLeft_clicked == True and botRight_clicked == True: で図形の左上と右下がクリックで決定された場合は、マウスの操作を初期値に戻しています。

if topLeft_clicked == False: でまだ図形の右上が決定されて無い場合は、マウスの位置の座標が定められて、クリックすることでその位置で描画することになります。

elif botRight_clicked == False: でまだ図形の左下が決定されて無い場合は、マウスの位置の座標が定められて、クリックすることでその位置で描画することになります。

pt1 = (0,0)
pt2 = (0,0)
topLeft_clicked = False
botRight_clicked = False

global変数のそれぞれをここで初期化しています。

cap = cv2.VideoCapture(0)

cv2.namedWindow('Drawing rectangle')

cv2.setMouseCallback('Drawing rectangle', draw_rectangle)

VideoCapture()に0を指定してカメラを接続しています。nameWindow()でウインドウの名前をつけています。setMouseCallback()でマウスイベントの処理をセットします。ここで先ほど定義したdraw_rectangleを指定しています。

while True:

    ret, frame = cap.read()

    if topLeft_clicked:
        cv2.circle(frame, center=pt1, radius=5, color=(0,0,255), thickness=-1)

    if topLeft_clicked and botRight_clicked:
        cv2.rectangle(frame, pt1, pt2, (0, 0, 255), 2)

    cv2.imshow('Drawing rectangle', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

while文でカメラを動作させています。このコードはほとんどこれまでと同じです。違うところはread()で読み込むところとimshow()で表示するところ間に、マウスの操作のコードを入れています。

if topLeft_clicked:で描画する四角形の左上の位置がクリックされた時に、circle()を使ってクリック位置に丸印をつけています。動画を読み込み、中心の位置と半径を指定し、色を赤にして塗りつぶす操作をしています。

if topLeft_clicked and botRight_clicked:で四角形の左上と右上の位置がクリックされた時に、rectangle()を使って四角形を描画しています。動画を読み込み、左上、右下の座標、色、線の太さを指定しています。

cap.release()
cv2.destroyAllWindows()

いつものように、このコードで終了さています。

全体のコードは以下のようになります。

import cv2


def draw_rectangle(event,x,y,flags,param):

    global pt1,pt2,topLeft_clicked,botRight_clicked

    if event == cv2.EVENT_LBUTTONDOWN:

        if topLeft_clicked == True and botRight_clicked == True:
            topLeft_clicked = False
            botRight_clicked = False
            pt1 = (0,0)
            pt2 = (0,0)

        if topLeft_clicked == False:
            pt1 = (x,y)
            topLeft_clicked = True

        elif botRight_clicked == False:
            pt2 = (x,y)
            botRight_clicked = True



pt1 = (0,0)
pt2 = (0,0)
topLeft_clicked = False
botRight_clicked = False

cap = cv2.VideoCapture(0)

cv2.namedWindow('Drawing rectangle')

cv2.setMouseCallback('Drawing rectangle', draw_rectangle)


while True:

    ret, frame = cap.read()

    if topLeft_clicked:
        cv2.circle(frame, center=pt1, radius=5, color=(0,0,255), thickness=-1)

    if topLeft_clicked and botRight_clicked:
        cv2.rectangle(frame, pt1, pt2, (0, 0, 255), 2)


    cv2.imshow('Drawing rectangle', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

このコードをPythonファイルに保存し、ターミナルで実行すると、カメラで写した映像が表示されます。その表示の上の任意の位置を左クリックすると赤い丸印が描画され、もう1つ別の箇所をクリックするとこの2点を対角線にした四角形が動画の上に描画されることになります。

スポンサーリンク

最後に

OpenCVを使ったPythonでの動画処理について、ここではwebカメラで撮影しているストリーム動画の画面に図形を描写してみました。

ここでは、動画の固定した位置への図形の描写と、任意の位置への図形の描写を行ってみました。

画面への図形描写は、画像からのオブジェクト検出や、機械学習などの顔認証などを行う時に顔の部分などを四角で囲んで表示するような処理に繋がりますので、その時の為に押さえて起きましょう。

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