diff --git a/.gitignore b/.gitignore index d9005f2..6c5bb65 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +output/ + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..9940ce4 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..fe647e7 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..82c23a9 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/video-2-3d.iml b/.idea/video-2-3d.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/.idea/video-2-3d.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/DSCN1034.MOV b/DSCN1034.MOV new file mode 100644 index 0000000..b414f5a Binary files /dev/null and b/DSCN1034.MOV differ diff --git a/main.py b/main.py new file mode 100644 index 0000000..bc7155e --- /dev/null +++ b/main.py @@ -0,0 +1,76 @@ +import os +import sys + +import cv2 +import numpy as np + +MINIMUM_SIMILARITY_THRESHOLD = 0.4 + +def process_video(video_path, min_similarity, output_folder): + cap = cv2.VideoCapture(video_path) + + if not cap.isOpened(): + print("Error opening video file") + return + + match_frame = None + prev_frame = None + + i = 0 + + while cap.isOpened(): + ret, frame = cap.read() + if not ret: break + + i += 1 + + print(f"Frame {i}: ", end='') + + if prev_frame is None: + prev_frame = frame + match_frame = frame + print("Initial frame") + continue + + cv2.imshow('Frame', frame) + + similarity = orb_similarity(match_frame, frame) + + print(f"Similarity: {similarity}, ", end='') + + if similarity < min_similarity: + match_frame = prev_frame + + if(not os.path.isdir(output_folder)): + os.mkdir(output_folder) + + cv2.imwrite(os.path.join(output_folder, os.path.basename(video_path)+"-"+str(i)+".png"), match_frame) + print("Lost continuity, new match frame") + else: + print("Skipped!") + + prev_frame = frame + + if cv2.waitKey(1) == ord('q'): break + + # Release the video capture object and close windows + cap.release() + cv2.destroyAllWindows() + + +orb = cv2.ORB_create() + +def orb_similarity(img1, img2): + kp1, des1 = orb.detectAndCompute(img1, None) + kp2, des2 = orb.detectAndCompute(img2, None) + + bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True) + matches = bf.match(des1, des2) + + similarity = len(matches) / min(len(kp1), len(kp2)) + return similarity + +if len(sys.argv) != 4: + print("Usage: python main.py