-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
164 lines (117 loc) · 5.19 KB
/
Copy pathmain.py
File metadata and controls
164 lines (117 loc) · 5.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# Written by Prgckwb
import argparse
import glob
import math
import os
import time
import PyPDF2
import cv2
import numpy as np
from PIL import Image, ImageFile
from tqdm import tqdm
from features import calc_distances, extract_dcnn_data
ImageFile.LOAD_TRUNCATED_IMAGES = True
# Function to retrieve command line arguments
def init_argument():
parser = argparse.ArgumentParser()
parser.add_argument("input_file", help="File name of the video to be converted")
parser.add_argument("-f", "--frame", type=int, default=60, help="Number of frames to be cut from the video.", )
parser.add_argument("-t", "--threshold", type=int, default=100, help="Threshold used to determine image similarity")
argument = parser.parse_args()
return argument
# 動画ファイルからdframeごとに画像を抽出する
def cut_images(video_name, dframe):
images = []
video_capture = cv2.VideoCapture(video_name)
# 動画の全フレーム数
max_frame = int(video_capture.get(cv2.CAP_PROP_FRAME_COUNT))
# 動画の全フレームからdframeごとに画像を切り出す
for frame_count in tqdm(range(max_frame), desc="[Extract images from video]"):
if frame_count % dframe == 0:
ret, current_frame = video_capture.read()
if ret and (frame_count == 0 or cv2.PSNR(images[-1], current_frame) < 25):
images.append(current_frame)
else:
# dframe番目でないときは高速化のためフレーム画像を読み込まない
ret = video_capture.grab()
video_capture.release()
return images
# Function to detect image duplicates and remove them.
# To detect duplicates in a double loop, use the image list once the duplicates of adjacent frames are removed.
def remove_duplicate_psnr(imgs):
delete_index = set()
imgs_length = len(imgs)
for i in tqdm(range(imgs_length - 1), desc="[Remove duplicate images]"):
for j in tqdm(range(i + 1, imgs_length), leave=False):
if cv2.PSNR(imgs[i], imgs[j]) > 25:
delete_index.add(j)
delete_index = sorted(list(delete_index))
delete_index.reverse()
for i in delete_index:
imgs.pop(i)
return imgs
def remove_duplicate(images, data_dir, video_name, frame, threshold):
data_path = f"{data_dir}/{video_name}_f{frame}.npy"
if os.path.exists(data_path):
data = np.load(data_path)
else:
data = extract_dcnn_data(images=images, video_name=video_name,
frame=frame, data_dir=data_dir, can_save=True)
delete_index = set()
n = len(images)
for i in tqdm(range(n - 1, 1, -1), desc="[Remove duplicate images]"):
for j in tqdm(range(i - 1, 0, -1), leave=False):
if calc_distances(data, i, j) < threshold:
delete_index.add(j)
delete_index = sorted(list(delete_index))
delete_index.reverse()
for i in delete_index:
images.pop(i)
return images
# Convert a numpy array to an Image array in the Pillow module to generate individual PDF files.
def convert_img2pdf(images, output_dir, img_filename):
out_dir_name = f"{output_dir}/{img_filename}"
os.makedirs(out_dir_name, exist_ok=True)
# 画像の枚数が10の何乗か?
images_num = math.floor(math.log10(len(images)))
for i, image in enumerate(tqdm(images, desc="[Generate split PDF files]")):
file_name_count = str(i).zfill(images_num + 1)
filename = f'{out_dir_name}/{img_filename}_{file_name_count}.pdf'
img = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
img.convert("RGB").save(filename)
# Merge disparate PDF files into one PDF file
def merge_pdfs(output_dir, img_filename):
out_dir_name = f"{output_dir}/{img_filename}"
file_list = sorted(glob.glob(f"{out_dir_name}/{img_filename}*.pdf"))
merger = PyPDF2.PdfFileMerger()
for pdf_file in tqdm(file_list, desc="[Combine into a single PDF file]"):
merger.append(pdf_file)
merger.write(f'{img_filename}.pdf')
print(f'\nFile: {output_dir}/{img_filename}_*.pdf has been created.')
print(f'File: {img_filename}.pdf has been created.')
merger.close()
def main():
# Start point for measurement of execution time
start = time.perf_counter()
# Getting command line arguments
args = init_argument()
video_file = args.input_file
frame = args.frame
threshold = args.threshold
output_dir = './output'
dcnn_data_dir = "./data"
video_filename = video_file.split('.')[0]
# If the directory specified as the output destination does not exist, create it.
os.makedirs(output_dir, exist_ok=True)
# images: A list of images extracted from the video.
images = cut_images(video_file, frame)
# Recheck for duplicate images and delete them if they exist.
images = remove_duplicate(images=images, video_name=video_filename,
data_dir=dcnn_data_dir, frame=frame, threshold=threshold)
convert_img2pdf(images, output_dir, video_filename)
merge_pdfs(output_dir, video_filename)
# End point for measurement of execution time
end = time.perf_counter()
print('Execution time: {:.3f}s'.format(end - start))
if __name__ == '__main__':
main()