Skip to content

Commit 49e29b4

Browse files
committed
v1.1.9
1 parent c0e2aab commit 49e29b4

20 files changed

+39
-228
lines changed

MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
include pcv/examples/names.txt
1+
include src/pcv/examples/names.txt

build/lib/pcv/vidIO.py

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from queue import Queue
88
from threading import Thread, Event
99
from pcv.interact import DoNothing, waitKey
10+
from source import VideoSource
1011

1112

1213
class BlockingVideoWriter(cv2.VideoWriter):
@@ -137,7 +138,7 @@ def suggested_codec(cls, filename, exclude=[]):
137138

138139
@classmethod
139140
def from_camera(cls, filename, camera, fourcc=None, isColor=True,
140-
apiPreference=None, fps=-3, **kwargs):
141+
apiPreference=None, fps=-3, frameSize=None, **kwargs):
141142
''' Returns a VideoWriter based on the properties of the input camera.
142143
143144
'filename' is the name of the file to save to.
@@ -150,12 +151,16 @@ def from_camera(cls, filename, camera, fourcc=None, isColor=True,
150151
If no processing is occurring, 'camera' is suggested, otherwise
151152
it is generally best to measure the frame output.
152153
Defaults to -3, to measure over 3 frames.
154+
'frameSize' is an integer tuple of (width, height)/(cols, rows).
155+
If left as None, uses `camera.get` to retrieve width and height.
153156
'kwrags' are any additional keyword arguments for initialisation.
154157
155158
'''
156159
if fourcc is None:
157160
fourcc = cls.suggested_codec(filename)
158-
frameSize = tuple(int(camera.get(dim)) for dim in ('width','height'))
161+
if frameSize is None:
162+
frameSize = tuple(int(camera.get(dim))
163+
for dim in ('width', 'height'))
159164

160165
if fps == 'camera':
161166
fps = camera.get('fps')
@@ -302,21 +307,37 @@ def __init__(msg='User quit manually', *args, **kwargs):
302307
super().__init__(msg, *args, **kwargs)
303308

304309

305-
class ContextualVideoCapture(cv2.VideoCapture):
306-
''' A cv2.VideoCapture with a context manager for releasing. '''
310+
class OpenCVSource(cv2.VideoCapture):
311+
''' A class to provide opencv's VideoCapture as a VideoSource backend. '''
312+
# more properties + descriptions can be found in the docs:
313+
# https://docs.opencv.org/3.4/d4/d15/group__videoio__flags__base.html#gaeb8dd9c89c10a5c63c139bf7c4f5704d
307314
properties = {
308315
'fps' : cv2.CAP_PROP_FPS,
309316
'mode' : cv2.CAP_PROP_MODE,
310317
'width' : cv2.CAP_PROP_FRAME_WIDTH,
311318
'height' : cv2.CAP_PROP_FRAME_HEIGHT,
312319
'backend' : cv2.CAP_PROP_BACKEND,
313320
}
314-
# more properties + descriptions can be found in the docs:
315-
# https://docs.opencv.org/3.4/d4/d15/group__videoio__flags__base.html#gaeb8dd9c89c10a5c63c139bf7c4f5704d
316321

322+
def get(self, property):
323+
try:
324+
return super().get(self.properties.get(property, property))
325+
except TypeError: # property must be an unknown string
326+
return super().get(eval('cv2.CAP_PROP_'+property.upper()))
327+
328+
def set(self, property, value):
329+
try:
330+
return super().set(self.properties.get(property, property), value)
331+
except TypeError: # 'property' must be an unknown string
332+
return super().set(eval('cv2.CAP_PROP_'+property.upper))
333+
334+
335+
class ContextualVideoCapture(VideoSource):
336+
''' A video-capturing class with a context manager for releasing. '''
337+
317338
def __init__(self, id, *args, display='frame', delay=None, quit=ord('q'),
318339
play_pause=ord(' '), pause_effects={}, play_commands={},
319-
destroy=-1, **kwargs):
340+
destroy=-1, source=OpenCVSource, **kwargs):
320341
''' A pausable, quitable, iterable video-capture object
321342
with context management.
322343
@@ -353,9 +374,12 @@ def __init__(self, id, *args, display='frame', delay=None, quit=ord('q'),
353374
to destroy all active opencv windows, a string of a specific window
354375
name, or a list of window names to close. If left as -1, destroys
355376
the window specified in 'display'.
377+
'source' is a class which acts like a video source, by implementing at
378+
minimum the methods 'get', 'set', 'read', 'grab', 'retrieve',
379+
'open', 'isOpened', and 'release'.
356380
357381
'''
358-
super().__init__(id, *args, **kwargs)
382+
super().__init__(source, id, *args, **kwargs)
359383
self._id = id
360384
self.display = display
361385
self._delay = delay
@@ -460,7 +484,7 @@ def headless_stream(self):
460484
if not read_success: break # camera disconnected
461485

462486
def record_stream(self, filename, show=True, mouse_handler=DoNothing(),
463-
writer=VideoWriter):
487+
writer=VideoWriter, **kwargs):
464488
''' Capture and record stream, with optional display.
465489
466490
'filename' is the file to save to.
@@ -474,7 +498,7 @@ def record_stream(self, filename, show=True, mouse_handler=DoNothing(),
474498
to better ensure a consistent output framerate.
475499
476500
'''
477-
with writer.from_camera(filename, self) as writer, mouse_handler:
501+
with writer.from_camera(filename, self, **kwargs) as writer, mouse_handler:
478502
for read_success, frame in self:
479503
if read_success:
480504
if show:
@@ -483,20 +507,6 @@ def record_stream(self, filename, show=True, mouse_handler=DoNothing(),
483507
else:
484508
break # camera disconnected
485509

486-
def get(self, property):
487-
''' Return the value of 'property' if it exists, else 0.0. '''
488-
try:
489-
return super().get(self.properties.get(property, property))
490-
except TypeError: # property must be an unknown string
491-
return super().get(eval('cv2.CAP_PROP_'+property.upper()))
492-
493-
def set(self, property, value):
494-
''' Attempts to set 'property' to 'value', returning success. '''
495-
try:
496-
return super().set(self.properties.get(property, property), value)
497-
except TypeError: # 'property' must be an unknown string
498-
return super().set(eval('cv2.CAP_PROP_'+property.upper))
499-
500510
def read(self, image=None):
501511
if image is not None:
502512
status, image = super().read(image)
@@ -537,7 +547,7 @@ def measure_framerate(self, frames):
537547
return count / (perf_counter() - start)
538548

539549
def __repr__(self):
540-
return f"{self.__class__.__name__}(camera_id={repr(self._id)})"
550+
return f"{self.__class__.__name__}(camera_id={self._id!r})"
541551

542552

543553
class Camera(SlowCamera):
@@ -687,7 +697,7 @@ def read(self, image=None):
687697
class VideoReader(LockedCamera):
688698
''' A class for reading video files. '''
689699
properties = {
690-
**ContextualVideoCapture.properties,
700+
**OpenCVSource.properties,
691701
'frame' : cv2.CAP_PROP_POS_FRAMES,
692702
'codec' : cv2.CAP_PROP_FOURCC,
693703
'timestamp' : cv2.CAP_PROP_POS_MSEC,

dist/pythonic-cv-1.1.8.tar.gz

-29.1 KB
Binary file not shown.
-27.6 KB
Binary file not shown.

pythonic_cv.egg-info/PKG-INFO

Lines changed: 0 additions & 184 deletions
This file was deleted.

pythonic_cv.egg-info/SOURCES.txt

Lines changed: 0 additions & 13 deletions
This file was deleted.

pythonic_cv.egg-info/dependency_links.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

pythonic_cv.egg-info/top_level.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

setup.cfg

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ classifiers =
1313

1414
[options]
1515
package_dir =
16-
= pcv
16+
= src
1717
packages = find:
1818
python_requires = >=3.6
1919

2020
[options.packages.find]
21-
where = pcv
21+
where = src
File renamed without changes.

0 commit comments

Comments
 (0)