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

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

MENU

OpenCVを用いた動画像重畳

今回はOpenCVを用いた動画像を重畳させる方法についてまとめます!!
ふと疑問になったため調べてみたので、こちらをまとめておこうと思いましたので。

プログラミング言語pythonを用います。
※go言語でも確認したのですが、まずはpythonから。


■画像の重畳方法

OpenCVを用いて画像を重畳する際、

cv2.AddWeighted(src1, alpha, src2, beta, gamma, dst) 

を用いれば実現させることが出来ます。
AddWeightedに与える引数(パラメータ)はそれぞれ、

src1 – first input array.
alpha – weight of the first array elements.
src2 – second input array of the same size and channel number as src1.
beta – weight of the second array elements.
dst – output array that has the same size and number of channels as the input arrays.
gamma – scalar added to each sum.

となっております。
こちらを用いて2枚の画像を重畳させるコードはこちらになります。

import numpy as np
import cv2

imgA = cv2.imread("画像1のパス")
imgB = cv2.imread("画像2のパス")
imgA = cv2.resize(imgA,(600,600))
imgB = cv2.resize(imgB,(600,600))

img_AB = cv2.addWeighted(imgA, 0.3, imgB, 0.7, 1.0)

cv2.imshow("test",img_AB)
cv2.waitKey(0)

ここで、addWeightedを用いるにあたり、
src1、src2は同じ画像サイズにする必要があります。
もし異なるサイズであった場合には、

error: (-209:Sizes of input arguments do not match) The operation is neither 'array op array' (where arrays have the same size and the same number of channels), nor 'array op scalar', nor 'scalar op array' in function 'cv::arithm_op'

といったエラーが発生します。

■画像重畳結果

確認するために用いた画像をそれぞれ、

f:id:Elsammit:20201107205137j:plain


f:id:Elsammit:20201018205834j:plain

とした場合の重畳結果はこちらになります。

【alha=0.7、beta=0.3、gamma=1.0】
f:id:Elsammit:20201107205638j:plain

【alha=0.5、beta=0.5、gamma=1.0】
f:id:Elsammit:20201107205717j:plain

【alha=0.3、beta=0.7、gamma=1.0】
f:id:Elsammit:20201107205804j:plain

■動画重畳方法

先ほどのaddWeightedを用いれば動画を重畳させることも可能になります。
コードはこちらになります。

import cv2
import sys
import time

delay = 1
window_name = 'frame'
fps = 10
size = (640,360)
capA = cv2.VideoCapture("動画1")
capB = cv2.VideoCapture("動画2")

fmt = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
writer = cv2.VideoWriter("AddWeight.mp4",fmt,fps,size)

if not capA.isOpened():
    sys.exit()
if not capB.isOpened():
    sys.exit()

while True:
    ret1, frameA = capA.read()
    ret2, frameB = capB.read()
    if ret1:
        frameA = cv2.resize(frameA,size)
        frameB = cv2.resize(frameB,size)
        img_AB = cv2.addWeighted(frameA, 0.5, frameB, 0.5, 0)
        cv2.imshow(window_name, img_AB)
        writer.write(img_AB)
        time.sleep(1/fps)
        if cv2.waitKey(delay) & 0xFF == ord('q'):
            break
    else:
        capA.set(cv2.CAP_PROP_POS_FRAMES, 0)
        capB.set(cv2.CAP_PROP_POS_FRAMES, 0)

cv2.destroyWindow(window_name)

1フレーム毎の画像として重畳させればよいので、
1フレーム抽出した後の処理や考え方は先ほどの画像の時と同じですね。

■動画重畳結果

重畳させる動画はこちらになります。

f:id:Elsammit:20201107211838g:plain


f:id:Elsammit:20201107212027g:plain

こちらsrc1、src2を重畳させるとこちらのような動画の生成が可能です!!
f:id:Elsammit:20201107214356g:plain

■最後に

OpenCVを用いてしまえば、画像や動画の重畳が簡単に実現可能ですね!!
今回は動画・画像共に2枚までしか実施していないですが、
生成された重畳画像をさらに重畳させていけば3枚以上も出来そうです!!

OpenCV使わずに実施する方法はあるのかな?
ちょっと調べてみような?
後、go言語については後でブログに載せますので、少々お待ちください。


■参考
https://peaceandhilightandpython.hatenablog.com/entry/2016/01/16/002028
Operations on Arrays — OpenCV 2.4.13.7 documentation
http://rikoubou.hatenablog.com/entry/2019/01/15/174751