OpenCV

Capture to the score frame in streaming video game (Template Match) for Python

박민혀기 2023. 12. 20. 00:29

현재 폴더에 있는 특정 동영상 포멧(mp4, avi, mkv)을 모두 가져와서  추출하고자 하는 이미지가 노출시 현재 동영상 재생 시간으로(시_분_초.jpg) 저장된다.

 

셋팅값 조정 필요

Proto type source code

import os
import glob
import cv2
import numpy as np

def create_folder(folder_path):
    try:
        os.makedirs(folder_path)
        #print(f"폴더 {folder_path}가 생성되었습니다.")
    except FileExistsError:
        print(f"폴더 {folder_path}는 이미 존재합니다.")

def extract_info_from_filename(file_name):
    file_name_without_extension = os.path.splitext(file_name)[0]
    return file_name_without_extension

def get_video_files(directory="."):
    video_files = (glob.glob(os.path.join(directory, '*.mp4')) + 
        glob.glob(os.path.join(directory, '*.avi')) + 
        glob.glob(os.path.join(directory, '*.mkv')))

    return video_files

def current_time(cap):
    fps = cap.get(cv2.CAP_PROP_FPS)
    current_seconds = int(cap.get(cv2.CAP_PROP_POS_FRAMES) / fps)
    current_hours = int(current_seconds // 3600)
    current_minutes = int((current_seconds % 3600) // 60)
    current_seconds = int(current_seconds % 60)

    file_name = f"water_{current_hours:02d}_{current_minutes:02d}_{current_seconds:02d}.jpg"
    return file_name

#CV method setting
threshold = 0.88
resize_ratio = 1/5

#Score image load
template_path = 'Watermelon_Score_ROI.PNG'
template = cv2.imread(template_path, cv2.IMREAD_COLOR)
if template is None:
    print("Could't find or open image")
    exit()

#Score image resize & TR grayscale
template = cv2.resize(template, None, fx=resize_ratio, fy=resize_ratio)
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)

#Get the names of video files
video_files = get_video_files()

last_save_frame = template

for video_file in video_files:
    extracted_info = extract_info_from_filename(video_file)
    
    if extracted_info:
        create_folder(extracted_info)
        extracted_info = os.path.basename(extracted_info)
        print(extracted_info, " processing!!")
        
    cap = cv2.VideoCapture(video_file)
    if not cap.isOpened():
        print(f"{extracted_info} 비디오를 열거나 찾을 수 없습니다.")
        break
    else:
        while True:

            ret, frame = cap.read()
            if not ret:
                #print("Video end.")
                break

            frame = cv2.resize(frame, None, fx=resize_ratio, fy=resize_ratio)
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

            result = cv2.matchTemplate(frame, template, cv2.TM_CCORR_NORMED)
            min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

            if max_val > threshold:                
                result = cv2.matchTemplate(last_save_frame, frame, cv2.TM_CCORR_NORMED)
                min_val, max_val_1, min_loc, max_loc = cv2.minMaxLoc(result)                
                if max_val_1 > 0.99:
                    #print("draw : ", max_val_1)
                    continue
                else:
                    #print("Image Found! : ", max_val)
                    file_name = current_time(cap)
                    extracted_info = os.path.basename(extracted_info)
                    file_name = './' + extracted_info + '/' + file_name
                    #print(file_name)

                    cv2.imwrite(file_name, frame)
                    last_save_frame = frame.copy()


            #cv2.imshow("frame", frame)
            #if cv2.waitKey(1) & 0xFF == ord('q'):
            #    break

        cap.release()
        cv2.destroyAllWindows()