Skip to content

Commit cf6566b

Browse files
Bruno LenziBruno Lenzi
Bruno Lenzi
authored and
Bruno Lenzi
committed
style: flake8 suggestions
1 parent d8b537b commit cf6566b

File tree

2 files changed

+111
-87
lines changed

2 files changed

+111
-87
lines changed

VideoSplitter.py

+34-28
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
import os, pickle
1+
import os
2+
import pickle
23
from bisect import bisect_left, bisect_right
34
from moviepy.video.io.ffmpeg_tools import ffmpeg_extract_subclip
4-
from utils import *
5+
import cv2
6+
from utils import frame_to_string, prepareOCR, extract_coordinates
7+
import unittest
8+
59

610
class VideoSplitter:
711
"""
@@ -20,8 +24,8 @@ class VideoSplitter:
2024
frame_to_string (optional): function used to extract caption from frame
2125
extract_coordinates (optional): function used to extract coordinates from caption
2226
"""
23-
def __init__(self, fname, captions = None,
24-
acceptCloseMatches = True, max_frames = 200,
27+
def __init__(self, fname, captions=None,
28+
acceptCloseMatches=True, max_frames=200,
2529
frame_to_string=frame_to_string,
2630
img_preprocessing=prepareOCR,
2731
extract_coordinates=extract_coordinates):
@@ -36,8 +40,8 @@ def __init__(self, fname, captions = None,
3640
self.Nframes = int(self.video.get(cv2.CAP_PROP_FRAME_COUNT))
3741
self.fps = self.video.get(cv2.CAP_PROP_FPS)
3842

39-
self.captions = {} # (frame_index, caption)
40-
self.coordinates = {} # (frame_index, camera position in x,y,z) N.B.: strings, not float
43+
self.captions = {} # (frame_index, caption)
44+
self.coordinates = {} # (frame_index, camera position in x,y,z) N.B.: strings, not float
4145
# (coordinates, first frame where coordinates appeared):
4246
# represents a sorted list of frames, used for defining the start and end of sequences by bisection
4347
self.seqID = {}
@@ -69,7 +73,7 @@ def loadFrame(self, frame_index):
6973
success, frame = self.video.read()
7074
return frame if success else None
7175

72-
def processFrame(self, frame_index, ignore_caption = False):
76+
def processFrame(self, frame_index, ignore_caption=False):
7377
"""
7478
Extract and process the caption from the given frame, storing it in
7579
self.caption if not present, the coordinates in self.coordinates,
@@ -93,7 +97,7 @@ def processFrame(self, frame_index, ignore_caption = False):
9397
try:
9498
pm = self.seqID if self.acceptCloseMatches else []
9599
coordinates = self.extract_coordinates(caption, possible_matches=pm)
96-
except ValueError as error:
100+
except ValueError:
97101
coordinates = ('EXTRACTION FAILED', frame_index, caption)
98102

99103
self.coordinates[frame_index] = coordinates
@@ -112,28 +116,30 @@ def getCoordinates(self, frame_index):
112116

113117
def printCaptions(self):
114118
"Print captions"
115-
print ('Frame \t Caption')
116-
for i in sorted(x.captions.items()): print (f'{i[0]} \t {i[1]}')
119+
print('Frame \t Caption')
120+
for i in sorted(x.captions.items()):
121+
print(f'{i[0]} \t {i[1]}')
117122

118123
def __getitem__(self, item):
119124
"""
120125
Return the first frame that revealed the sequence to which the given frame belongs.
121126
This method is called by bisect to find the boundaries of the sequence
122127
"""
123-
return self.seqID[ self.getCoordinates(item) ]
128+
return self.seqID[self.getCoordinates(item)]
124129

125130
def findSequences(self):
126131
"""
127132
Fill dictionary self.sequences with coordinates, (first frame, last frame) for each sequence
128133
"""
129134
if not self.coordinates:
130135
# fill coordinates with first and last values if empty
131-
self[0], self[self.Nframes-1]
136+
self[0], self[self.Nframes - 1]
132137
while True:
133138
# Coordinates not yet analysed
134-
missing = dict((frame, coord) for (frame, coord) in self.coordinates.items() \
139+
missing = dict((frame, coord) for (frame, coord) in self.coordinates.items()
135140
if coord not in self.sequences)
136-
if not missing: return
141+
if not missing:
142+
return
137143
# Find the start and end of each sequence corresponding to each set of coordinates
138144
for (frame, coord) in missing.items():
139145
self.sequences[coord] = bisect_left(self, self[frame]), bisect_right(self, self[frame]) - 1
@@ -144,10 +150,9 @@ def printSequences(self):
144150
"""
145151
if not self.sequences:
146152
return
147-
print ('Frames \t Coordinates')
148-
for v,k in sorted((v,k) for k,v in self.sequences.items()):
149-
print (f'{v} \t {k}')
150-
153+
print('Frames \t Coordinates')
154+
for v, k in sorted((v, k) for k, v in self.sequences.items()):
155+
print(f'{v} \t {k}')
151156

152157
def writeSequences(self, outputdir, min_frames=10):
153158
"""
@@ -164,8 +169,8 @@ def writeSequences(self, outputdir, min_frames=10):
164169
valid_sequences = filter(lambda x: x[1] - x[0] >= min_frames, self.sequences.values())
165170
for (fmin, fmax) in sorted(valid_sequences):
166171
basename, ext = os.path.splitext(os.path.basename(self.fname))
167-
fname = os.path.join(outputdir, f'{basename}_seq{fmin}_{fmax}{ext}' )
168-
ffmpeg_extract_subclip(self.fname, fmin/self.fps, fmax/self.fps, fname)
172+
fname = os.path.join(outputdir, f'{basename}_seq{fmin}_{fmax}{ext}')
173+
ffmpeg_extract_subclip(self.fname, fmin / self.fps, fmax / self.fps, fname)
169174

170175
def writeInfo(self, outputdir):
171176
"""
@@ -185,18 +190,18 @@ def writeInfo(self, outputdir):
185190
with open(fname, 'wb') as pickleFile:
186191
pickle.dump(v, pickleFile)
187192

188-
189193
def __len__(self):
190194
return self.Nframes
191195

192-
import unittest
196+
193197
def setupTester(cls):
194198
"""
195199
Prepare tester class for VideoSplitter
196200
"""
197-
import urllib, yaml
201+
import urllib
202+
import yaml
198203
# Test parameters
199-
url = 'https://gist.githubusercontent.com/blenzi/82746e11119cb88a67603944869e29e2/raw' # noqa: E501
204+
url = 'https://gist.githubusercontent.com/blenzi/82746e11119cb88a67603944869e29e2/raw'
200205
cls.ref = eval(urllib.request.urlopen(url).read())
201206

202207
# Stream
@@ -223,9 +228,9 @@ def setUpClass(cls):
223228
"Setup only once for all tests"
224229
setupTester(cls)
225230
cls.splitter = VideoSplitter(cls.fname)
226-
cls.testFindSequences = False # skip finding sequences (takes about 30s)
231+
cls.testFindSequences = False # skip finding sequences (takes about 30s)
227232

228-
def a_test_loadFrame(self): # call it a_ as they are executed in alphabetical order
233+
def a_test_loadFrame(self): # call it a_ as they are executed in alphabetical order
229234
frame = self.splitter.loadFrame(self.ref['extract']['frame'])
230235
self.assertEqual(len(frame.shape), 3)
231236

@@ -243,7 +248,7 @@ def test_findSequences(self):
243248
self.maxDiff = None
244249
self.splitter.findSequences()
245250
seqs = self.splitter.sequences
246-
inv_seqs = dict(map(reversed, seqs.items())) # invert keys and values
251+
inv_seqs = dict(map(reversed, seqs.items())) # invert keys and values
247252
self.assertEqual(inv_seqs.keys(), self.ref['sequences'].keys())
248253

249254
def test_writeSequences(self):
@@ -256,7 +261,7 @@ def test_writeSequences(self):
256261
basename, ext = os.path.splitext(os.path.basename(self.splitter.fname))
257262
for fmin, fmax in self.splitter.sequences.values():
258263
fname = os.path.join(tmpdirname, f'{basename}_seq{fmin}_{fmax}{ext}')
259-
self.assertTrue( os.path.exists(fname) )
264+
self.assertTrue(os.path.exists(fname))
260265

261266
def test_writeInfo(self):
262267
"Test writing dictionaries with captions, sequences, ..."
@@ -273,6 +278,7 @@ def test_writeInfo(self):
273278
dSaved = pickle.load(pickleFile)
274279
self.assertEqual(d, dSaved)
275280

281+
276282
class VideoTesterWithCaptions(VideoTester):
277283
"""
278284
Test VideoSplitter with captions loaded externally

0 commit comments

Comments
 (0)