Elsaの技術日記(徒然なるままに)

主に自分で作ったアプリとかの報告・日記を記載

MENU

OpenCVで映像のズームイン・ズームアウトを試してみる

今回はOpenCVで映像のズームイン・ズームアウトを行ってみたいと思います。
言語はPythonです。



Pythonバージョン

使用するPythonのバージョンですが、
Python 3.7.4
になります。

■映像のズームイン・ズームアウトのコード

早速、ズームイン・ズームアウトのコードをご紹介します。
コードはこちら。
こちらは、2倍の倍率でズームインしているコードになります。

import cv2

scale = 2 #ここを変更すると倍率が変化する

capture = cv2.VideoCapture(0)

while(True):
    ret, frame = capture.read()

    height, width, channels = frame.shape[:3]
    if int(scale) < 1:
        scale = 1
    roi_width = width / int(scale)
    roi_height = height / int(scale)
    sabun_w1 = int((width - roi_width)/2)
    sabun_w2 = int((width + roi_width)/2)
    sabun_h1 = int((height - roi_height)/2)
    sabun_h2 = int((height + roi_height)/2)
    frame = frame[sabun_w1:sabun_w2, sabun_h1:sabun_h2]
    frame = cv2.resize(frame, (width, height))
    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

capture.release()
cv2.destroyAllWindows()

ズームインの流れをまとめていきます。
一例としてこちらの画像を例に用います。
f:id:Elsammit:20220414222340j:plain

まずは中央の枠の領域を指定するための座標を算出します。
算出しているコードはこちらにあたります。

    roi_width = width / int(scale)
    roi_height = height / int(scale)
    sabun_w1 = int((width - roi_width)/2)
    sabun_w2 = int((width + roi_width)/2)
    sabun_h1 = int((height - roi_height)/2)
    sabun_h2 = int((height + roi_height)/2)

こちらのコードでしている範囲を画像で表すとこちらの範囲になります。
f:id:Elsammit:20220414222714p:plain

次に枠内を切り取ります。
切り取りのコードはこちらにあたります。

frame = frame[sabun_w1:sabun_w2, sabun_h1:sabun_h2]

切り取り後の画像はこちらになります。
f:id:Elsammit:20220414223117p:plain

最後に、切り取り後の画像に対して元の画像サイズにリサイズすることによりズームインが実現出来ます。
該当コードはこちら。

frame = cv2.resize(frame, (width, height))

最終的な画像はこちらの通りとなり、中央領域の画像が拡大します。
f:id:Elsammit:20220414223510p:plain

■動的に拡大率を変更するには
ここまでで、倍率を変更してズームイン・ズームアウトを行う方法をまとめてきました。
次にコンソール上で倍率を入力すると動的にズームイン・ズームアウトを行うコードをまとめていきます。

import cv2
import threading

scale = 1
def input_keybord():
    while True:
        global scale
        scale = input("Enter scale: ")

capture = cv2.VideoCapture(0)

thread1 = threading.Thread(target=input_keybord)
thread1.start()

while(True):
    ret, frame = capture.read()

    height, width, channels = frame.shape[:3]
    if int(scale) < 1:
        scale = 1
    roi_width = width / int(scale)
    roi_height = height / int(scale)
    sabun_w1 = int((width - roi_width)/2)
    sabun_w2 = int((width + roi_width)/2)
    sabun_h1 = int((height - roi_height)/2)
    sabun_h2 = int((height + roi_height)/2)
    frame = frame[sabun_w1:sabun_w2, sabun_h1:sabun_h2]
    frame = cv2.resize(frame, (width, height))
    cv2.imshow('frame',frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

capture.release()
cv2.destroyAllWindows()

先ほど解説したズームインコードとの差分は、

def input_keybord():
    while True:
        global scale
        scale = input("Enter scale: ")

をスレッドで実行してscaleをコンソール上で変更できるようにした点です。
コンソール上で整数値を入力すれば、それに合わせてscaleが変わるので、
倍率が変化してズームイン・ズームアウトが行える原理です。

■実際に動かしてみる
実際にコードを動かして、ズームイン/ズームアウトするか確認していきます。
結果はこちら!!
問題なくズームイン・ズームアウトが実現出来ました。
youtu.be

■最後に

今回はOpenCVでズームイン・ズームアウトする方法をまとめてみました。
OpenCVは様々なことが実現出来、触っていて楽しいです。