Edited at

SECCON 2018 Online CTF Needle in a haystack テンプレートマッチングで照明点灯判定を自動化する

こちらの方の記事を参考に、テンプレートマッチングでも照明点灯判定を自動化してみました。

https://qiita.com/deko2369/items/85c98d71d13f5d6e95f9

手法は単純で、切り取った領域の

1分前の画像:テンプレート画像

1分後の画像:探索画像

これでcv2.TM_CCORR_NORMEDでテンプレートマッチングを行い、一致率が98%より大きかったら照明が切り替わってない、98%以下であったら照明が切り替わったと判定します。

# -*- coding: utf-8 -*-

import cv2

def main():
cap = cv2.VideoCapture('Needle in a haystack.mp4')

frame_count = cap.get(cv2.CAP_PROP_FRAME_COUNT)
fps = cap.get(cv2.CAP_PROP_FPS)
print(f'frame {frame_count}, fps: {fps}')
c = int(fps * 30)
step = int(fps * 60)
illumi = 0

while(cap.isOpened()):
cap.set(cv2.CAP_PROP_POS_FRAMES, c)
try:
frame = cap.read()[1]
except:
break

trim = frame[586:592,1142:1148]

#前のフレームの画像、capture.pngをテンプレート画像に設定する
#最初の場合のみcapture0.pngをテンプレート画像に設定する
if c == 900:
img = cv2.imread("capture0.png",1)
else:
img = cv2.imread("capture.png", 1)
cv2.imwrite("capture.png",trim)

#今回のフレームの画像、capture.pngを探索画像に設定する
temp = cv2.imread("capture.png", 1)
#マッチングテンプレートを実行
#比較方法はcv2.TM_CCORR_NORMEDを選択
result = cv2.matchTemplate(img, temp, cv2.TM_CCORR_NORMED)
#検出結果からマッチング率等を取得
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
if max_val > 0.98:
illumi = illumi
else:
illumi = illumi ^ 1

print(illumi, end='')
c += step

cap.release()
cv2.destroyAllWindows()

if __name__ == '__main__':
main()

実際の結果を上記ブログの方と差分比較すると、途中極一部が異なった以外はほぼ一致しました。

frame 981074.0, fps: 30.0

010101000100011101011101000111010111010001110111011100011101000111010111011101000101010
001110111011100011101110001000111000101000111011100010001010100011101010101011100010111
000111010101010111000101010001000111010111010001011101000100011100011101010101011100011
101110001000101010001010100010111000111011101000100011101010101011100011101010100010111
010001110111011100010111000111010100011101011101000101110000000000000000010101000111010
101010111000111010101000111011101110001011101010001110101000101110101000111010111011100
01110101110111010111000