QVideo 3.4.2__tar.gz → 3.6.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. {qvideo-3.4.2 → qvideo-3.6.0}/PKG-INFO +23 -3
  2. {qvideo-3.4.2 → qvideo-3.6.0}/QVideo.egg-info/PKG-INFO +23 -3
  3. {qvideo-3.4.2 → qvideo-3.6.0}/QVideo.egg-info/SOURCES.txt +5 -4
  4. {qvideo-3.4.2 → qvideo-3.6.0}/QVideo.egg-info/requires.txt +24 -2
  5. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Genicam/_camera.py +4 -2
  6. qvideo-3.6.0/cameras/OpenCV/__init__.py +6 -0
  7. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/OpenCV/_camera.py +84 -11
  8. qvideo-3.6.0/cameras/OpenCV/_devices.py +362 -0
  9. qvideo-3.6.0/cameras/OpenCV/_tree.py +136 -0
  10. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Picamera/_camera.py +66 -16
  11. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Picamera/_tree.py +3 -0
  12. {qvideo-3.4.2 → qvideo-3.6.0}/demos/__init__.py +7 -1
  13. qvideo-3.6.0/demos/compositedemo.py +87 -0
  14. {qvideo-3.4.2 → qvideo-3.6.0}/demos/trackpydemo.py +7 -2
  15. {qvideo-3.4.2 → qvideo-3.6.0}/demos/yolodemo.py +7 -2
  16. {qvideo-3.4.2 → qvideo-3.6.0}/dvr/QDVRWidget.py +1 -1
  17. {qvideo-3.4.2 → qvideo-3.6.0}/dvr/QHDF5Writer.py +1 -1
  18. {qvideo-3.4.2 → qvideo-3.6.0}/dvr/QOpenCVWriter.py +1 -1
  19. {qvideo-3.4.2 → qvideo-3.6.0}/filters/Median.py +1 -1
  20. {qvideo-3.4.2 → qvideo-3.6.0}/filters/MoMedian.py +1 -1
  21. {qvideo-3.4.2 → qvideo-3.6.0}/filters/Normalize.py +1 -1
  22. {qvideo-3.4.2 → qvideo-3.6.0}/filters/QBlurFilter.py +1 -1
  23. {qvideo-3.4.2 → qvideo-3.6.0}/filters/QEdgeFilter.py +1 -1
  24. {qvideo-3.4.2 → qvideo-3.6.0}/filters/QRGBFilter.py +1 -1
  25. {qvideo-3.4.2 → qvideo-3.6.0}/filters/QSampleHold.py +1 -1
  26. {qvideo-3.4.2 → qvideo-3.6.0}/filters/QYOLOFilter.py +8 -8
  27. {qvideo-3.4.2 → qvideo-3.6.0}/filters/_MedianBase.py +1 -1
  28. {qvideo-3.4.2 → qvideo-3.6.0}/lib/QCamera.py +1 -1
  29. {qvideo-3.4.2 → qvideo-3.6.0}/lib/QFPSMeter.py +1 -0
  30. {qvideo-3.4.2 → qvideo-3.6.0}/lib/QFilterBank.py +1 -1
  31. {qvideo-3.4.2 → qvideo-3.6.0}/lib/QVideoFilter.py +1 -1
  32. {qvideo-3.4.2 → qvideo-3.6.0}/lib/QVideoScreen.py +90 -13
  33. {qvideo-3.4.2 → qvideo-3.6.0}/lib/QVideoSource.py +8 -1
  34. {qvideo-3.4.2 → qvideo-3.6.0}/lib/QVideoWriter.py +3 -1
  35. {qvideo-3.4.2 → qvideo-3.6.0}/lib/__init__.py +1 -3
  36. {qvideo-3.4.2 → qvideo-3.6.0}/lib/chooser.py +1 -5
  37. {qvideo-3.4.2 → qvideo-3.6.0}/overlays/trackpy.py +84 -33
  38. {qvideo-3.4.2 → qvideo-3.6.0}/overlays/yolo.py +28 -24
  39. {qvideo-3.4.2 → qvideo-3.6.0}/pyproject.toml +6 -6
  40. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_chooser.py +4 -36
  41. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qopencvcamera.py +104 -26
  42. qvideo-3.6.0/tests/test_qopencvdevices.py +306 -0
  43. qvideo-3.6.0/tests/test_qopencvtree.py +230 -0
  44. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qpicamera.py +47 -26
  45. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qvideoscreen.py +100 -1
  46. qvideo-3.6.0/tests/test_qyolofilter.py +148 -0
  47. qvideo-3.6.0/tests/test_resolutions.py +348 -0
  48. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_trackpy_overlay.py +116 -25
  49. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_yolo_overlay.py +8 -18
  50. qvideo-3.4.2/cameras/OpenCV/__init__.py +0 -6
  51. qvideo-3.4.2/cameras/OpenCV/_resolution_tree.py +0 -155
  52. qvideo-3.4.2/cameras/OpenCV/_tree.py +0 -61
  53. qvideo-3.4.2/lib/resolutions.py +0 -49
  54. qvideo-3.4.2/tests/test_qopencvresolutiontree.py +0 -225
  55. qvideo-3.4.2/tests/test_qopencvtree.py +0 -94
  56. qvideo-3.4.2/tests/test_resolutions.py +0 -118
  57. {qvideo-3.4.2 → qvideo-3.6.0}/LICENSE.md +0 -0
  58. {qvideo-3.4.2 → qvideo-3.6.0}/QCamcorder.py +0 -0
  59. {qvideo-3.4.2 → qvideo-3.6.0}/QVideo.egg-info/dependency_links.txt +0 -0
  60. {qvideo-3.4.2 → qvideo-3.6.0}/QVideo.egg-info/top_level.txt +0 -0
  61. {qvideo-3.4.2 → qvideo-3.6.0}/README.md +0 -0
  62. {qvideo-3.4.2 → qvideo-3.6.0}/__init__.py +0 -0
  63. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Basler/__init__.py +0 -0
  64. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Basler/_camera.py +0 -0
  65. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Basler/_tree.py +0 -0
  66. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Flir/QListFlirCameras.py +0 -0
  67. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Flir/__init__.py +0 -0
  68. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Flir/_camera.py +0 -0
  69. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Flir/_tree.py +0 -0
  70. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Genicam/__init__.py +0 -0
  71. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Genicam/_tree.py +0 -0
  72. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/IDS/__init__.py +0 -0
  73. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/IDS/_camera.py +0 -0
  74. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/IDS/_tree.py +0 -0
  75. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/MV/__init__.py +0 -0
  76. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/MV/_camera.py +0 -0
  77. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/MV/_tree.py +0 -0
  78. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Noise/__init__.py +0 -0
  79. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Noise/_camera.py +0 -0
  80. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Noise/_tree.py +0 -0
  81. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/OpenCV/QListCVCameras.py +0 -0
  82. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Picamera/__init__.py +0 -0
  83. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Vimbax/__init__.py +0 -0
  84. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Vimbax/_camera.py +0 -0
  85. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/Vimbax/_tree.py +0 -0
  86. {qvideo-3.4.2 → qvideo-3.6.0}/cameras/__init__.py +0 -0
  87. {qvideo-3.4.2 → qvideo-3.6.0}/demos/ROIdemo.py +0 -0
  88. {qvideo-3.4.2 → qvideo-3.6.0}/demos/demo.py +0 -0
  89. {qvideo-3.4.2 → qvideo-3.6.0}/demos/filterdemo.py +0 -0
  90. {qvideo-3.4.2 → qvideo-3.6.0}/dvr/QHDF5Reader.py +0 -0
  91. {qvideo-3.4.2 → qvideo-3.6.0}/dvr/QOpenCVReader.py +0 -0
  92. {qvideo-3.4.2 → qvideo-3.6.0}/dvr/__init__.py +0 -0
  93. {qvideo-3.4.2 → qvideo-3.6.0}/dvr/icons_rc.py +0 -0
  94. {qvideo-3.4.2 → qvideo-3.6.0}/filters/__init__.py +0 -0
  95. {qvideo-3.4.2 → qvideo-3.6.0}/lib/QCameraTree.py +0 -0
  96. {qvideo-3.4.2 → qvideo-3.6.0}/lib/QListCameras.py +0 -0
  97. {qvideo-3.4.2 → qvideo-3.6.0}/lib/QVideoReader.py +0 -0
  98. {qvideo-3.4.2 → qvideo-3.6.0}/lib/clickable.py +0 -0
  99. /qvideo-3.4.2/lib/types.py → /qvideo-3.6.0/lib/videotypes.py +0 -0
  100. {qvideo-3.4.2 → qvideo-3.6.0}/overlays/__init__.py +0 -0
  101. {qvideo-3.4.2 → qvideo-3.6.0}/setup.cfg +0 -0
  102. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_clickable.py +0 -0
  103. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_demo.py +0 -0
  104. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_filterdemo.py +0 -0
  105. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_icons_rc.py +0 -0
  106. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_median.py +0 -0
  107. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_momedian.py +0 -0
  108. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_normalize.py +0 -0
  109. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qbaslercamera.py +0 -0
  110. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qblurfilter.py +0 -0
  111. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qcamcorder.py +0 -0
  112. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qcamera.py +0 -0
  113. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qcameratree.py +0 -0
  114. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qdvrwidget.py +0 -0
  115. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qedgefilter.py +0 -0
  116. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qfilterbank.py +0 -0
  117. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qflircamera.py +0 -0
  118. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qfpsmeter.py +0 -0
  119. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qgenicamcamera.py +0 -0
  120. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qgenicamtree.py +0 -0
  121. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qhdf5reader.py +0 -0
  122. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qhdf5writer.py +0 -0
  123. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qidscamera.py +0 -0
  124. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qlistcameras.py +0 -0
  125. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qlistcvcameras.py +0 -0
  126. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qmvcamera.py +0 -0
  127. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qnoisecamera.py +0 -0
  128. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qnoisetree.py +0 -0
  129. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qopencvreader.py +0 -0
  130. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qopencvwriter.py +0 -0
  131. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qrgbfilter.py +0 -0
  132. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qsamplehold.py +0 -0
  133. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qvideoreader.py +0 -0
  134. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qvideosource.py +0 -0
  135. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qvideowriter.py +0 -0
  136. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_qvimbaxcamera.py +0 -0
  137. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_roidemo.py +0 -0
  138. {qvideo-3.4.2 → qvideo-3.6.0}/tests/test_videofilter.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: QVideo
3
- Version: 3.4.2
3
+ Version: 3.6.0
4
4
  Summary: PyQt-based framework for integrating video cameras into research applications
5
5
  Author-email: "David G. Grier" <david.grier@nyu.edu>
6
6
  License: GPL-3.0-or-later
@@ -21,16 +21,21 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
21
  Requires-Python: >=3.10
22
22
  Description-Content-Type: text/markdown
23
23
  License-File: LICENSE.md
24
- Requires-Dist: h5py
25
24
  Requires-Dist: numpy
26
25
  Requires-Dist: opencv-python
27
- Requires-Dist: pandas
28
26
  Requires-Dist: pyqtgraph
29
27
  Provides-Extra: pyqt5
30
28
  Requires-Dist: PyQt5; extra == "pyqt5"
31
29
  Requires-Dist: PyQt5-sip; extra == "pyqt5"
32
30
  Provides-Extra: pyqt6
33
31
  Requires-Dist: PyQt6; extra == "pyqt6"
32
+ Provides-Extra: dvr
33
+ Requires-Dist: h5py; extra == "dvr"
34
+ Provides-Extra: overlays
35
+ Requires-Dist: pandas; extra == "overlays"
36
+ Requires-Dist: trackpy; extra == "overlays"
37
+ Requires-Dist: numba; extra == "overlays"
38
+ Requires-Dist: ultralytics; extra == "overlays"
34
39
  Provides-Extra: genicam
35
40
  Requires-Dist: harvesters; extra == "genicam"
36
41
  Requires-Dist: genicam; extra == "genicam"
@@ -41,15 +46,30 @@ Requires-Dist: PyQt5; extra == "dev-pyqt5"
41
46
  Requires-Dist: PyQt5-sip; extra == "dev-pyqt5"
42
47
  Requires-Dist: pytest; extra == "dev-pyqt5"
43
48
  Requires-Dist: pytest-cov; extra == "dev-pyqt5"
49
+ Requires-Dist: h5py; extra == "dev-pyqt5"
50
+ Requires-Dist: pandas; extra == "dev-pyqt5"
51
+ Requires-Dist: trackpy; extra == "dev-pyqt5"
52
+ Requires-Dist: numba; extra == "dev-pyqt5"
53
+ Requires-Dist: ultralytics; extra == "dev-pyqt5"
44
54
  Provides-Extra: dev-pyqt6
45
55
  Requires-Dist: PyQt6; extra == "dev-pyqt6"
46
56
  Requires-Dist: pytest; extra == "dev-pyqt6"
47
57
  Requires-Dist: pytest-cov; extra == "dev-pyqt6"
58
+ Requires-Dist: h5py; extra == "dev-pyqt6"
59
+ Requires-Dist: pandas; extra == "dev-pyqt6"
60
+ Requires-Dist: trackpy; extra == "dev-pyqt6"
61
+ Requires-Dist: numba; extra == "dev-pyqt6"
62
+ Requires-Dist: ultralytics; extra == "dev-pyqt6"
48
63
  Provides-Extra: dev
49
64
  Requires-Dist: PyQt5; extra == "dev"
50
65
  Requires-Dist: PyQt5-sip; extra == "dev"
51
66
  Requires-Dist: pytest; extra == "dev"
52
67
  Requires-Dist: pytest-cov; extra == "dev"
68
+ Requires-Dist: h5py; extra == "dev"
69
+ Requires-Dist: pandas; extra == "dev"
70
+ Requires-Dist: trackpy; extra == "dev"
71
+ Requires-Dist: numba; extra == "dev"
72
+ Requires-Dist: ultralytics; extra == "dev"
53
73
  Provides-Extra: docs
54
74
  Requires-Dist: pydata-sphinx-theme; extra == "docs"
55
75
  Requires-Dist: sphinx; extra == "docs"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: QVideo
3
- Version: 3.4.2
3
+ Version: 3.6.0
4
4
  Summary: PyQt-based framework for integrating video cameras into research applications
5
5
  Author-email: "David G. Grier" <david.grier@nyu.edu>
6
6
  License: GPL-3.0-or-later
@@ -21,16 +21,21 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
21
  Requires-Python: >=3.10
22
22
  Description-Content-Type: text/markdown
23
23
  License-File: LICENSE.md
24
- Requires-Dist: h5py
25
24
  Requires-Dist: numpy
26
25
  Requires-Dist: opencv-python
27
- Requires-Dist: pandas
28
26
  Requires-Dist: pyqtgraph
29
27
  Provides-Extra: pyqt5
30
28
  Requires-Dist: PyQt5; extra == "pyqt5"
31
29
  Requires-Dist: PyQt5-sip; extra == "pyqt5"
32
30
  Provides-Extra: pyqt6
33
31
  Requires-Dist: PyQt6; extra == "pyqt6"
32
+ Provides-Extra: dvr
33
+ Requires-Dist: h5py; extra == "dvr"
34
+ Provides-Extra: overlays
35
+ Requires-Dist: pandas; extra == "overlays"
36
+ Requires-Dist: trackpy; extra == "overlays"
37
+ Requires-Dist: numba; extra == "overlays"
38
+ Requires-Dist: ultralytics; extra == "overlays"
34
39
  Provides-Extra: genicam
35
40
  Requires-Dist: harvesters; extra == "genicam"
36
41
  Requires-Dist: genicam; extra == "genicam"
@@ -41,15 +46,30 @@ Requires-Dist: PyQt5; extra == "dev-pyqt5"
41
46
  Requires-Dist: PyQt5-sip; extra == "dev-pyqt5"
42
47
  Requires-Dist: pytest; extra == "dev-pyqt5"
43
48
  Requires-Dist: pytest-cov; extra == "dev-pyqt5"
49
+ Requires-Dist: h5py; extra == "dev-pyqt5"
50
+ Requires-Dist: pandas; extra == "dev-pyqt5"
51
+ Requires-Dist: trackpy; extra == "dev-pyqt5"
52
+ Requires-Dist: numba; extra == "dev-pyqt5"
53
+ Requires-Dist: ultralytics; extra == "dev-pyqt5"
44
54
  Provides-Extra: dev-pyqt6
45
55
  Requires-Dist: PyQt6; extra == "dev-pyqt6"
46
56
  Requires-Dist: pytest; extra == "dev-pyqt6"
47
57
  Requires-Dist: pytest-cov; extra == "dev-pyqt6"
58
+ Requires-Dist: h5py; extra == "dev-pyqt6"
59
+ Requires-Dist: pandas; extra == "dev-pyqt6"
60
+ Requires-Dist: trackpy; extra == "dev-pyqt6"
61
+ Requires-Dist: numba; extra == "dev-pyqt6"
62
+ Requires-Dist: ultralytics; extra == "dev-pyqt6"
48
63
  Provides-Extra: dev
49
64
  Requires-Dist: PyQt5; extra == "dev"
50
65
  Requires-Dist: PyQt5-sip; extra == "dev"
51
66
  Requires-Dist: pytest; extra == "dev"
52
67
  Requires-Dist: pytest-cov; extra == "dev"
68
+ Requires-Dist: h5py; extra == "dev"
69
+ Requires-Dist: pandas; extra == "dev"
70
+ Requires-Dist: trackpy; extra == "dev"
71
+ Requires-Dist: numba; extra == "dev"
72
+ Requires-Dist: ultralytics; extra == "dev"
53
73
  Provides-Extra: docs
54
74
  Requires-Dist: pydata-sphinx-theme; extra == "docs"
55
75
  Requires-Dist: sphinx; extra == "docs"
@@ -33,7 +33,7 @@ cameras/Noise/_tree.py
33
33
  cameras/OpenCV/QListCVCameras.py
34
34
  cameras/OpenCV/__init__.py
35
35
  cameras/OpenCV/_camera.py
36
- cameras/OpenCV/_resolution_tree.py
36
+ cameras/OpenCV/_devices.py
37
37
  cameras/OpenCV/_tree.py
38
38
  cameras/Picamera/__init__.py
39
39
  cameras/Picamera/_camera.py
@@ -43,6 +43,7 @@ cameras/Vimbax/_camera.py
43
43
  cameras/Vimbax/_tree.py
44
44
  demos/ROIdemo.py
45
45
  demos/__init__.py
46
+ demos/compositedemo.py
46
47
  demos/demo.py
47
48
  demos/filterdemo.py
48
49
  demos/trackpydemo.py
@@ -77,8 +78,7 @@ lib/QVideoWriter.py
77
78
  lib/__init__.py
78
79
  lib/chooser.py
79
80
  lib/clickable.py
80
- lib/resolutions.py
81
- lib/types.py
81
+ lib/videotypes.py
82
82
  overlays/__init__.py
83
83
  overlays/trackpy.py
84
84
  overlays/yolo.py
@@ -111,8 +111,8 @@ tests/test_qmvcamera.py
111
111
  tests/test_qnoisecamera.py
112
112
  tests/test_qnoisetree.py
113
113
  tests/test_qopencvcamera.py
114
+ tests/test_qopencvdevices.py
114
115
  tests/test_qopencvreader.py
115
- tests/test_qopencvresolutiontree.py
116
116
  tests/test_qopencvtree.py
117
117
  tests/test_qopencvwriter.py
118
118
  tests/test_qpicamera.py
@@ -123,6 +123,7 @@ tests/test_qvideoscreen.py
123
123
  tests/test_qvideosource.py
124
124
  tests/test_qvideowriter.py
125
125
  tests/test_qvimbaxcamera.py
126
+ tests/test_qyolofilter.py
126
127
  tests/test_resolutions.py
127
128
  tests/test_roidemo.py
128
129
  tests/test_trackpy_overlay.py
@@ -1,7 +1,5 @@
1
- h5py
2
1
  numpy
3
2
  opencv-python
4
- pandas
5
3
  pyqtgraph
6
4
 
7
5
  [dev]
@@ -9,27 +7,51 @@ PyQt5
9
7
  PyQt5-sip
10
8
  pytest
11
9
  pytest-cov
10
+ h5py
11
+ pandas
12
+ trackpy
13
+ numba
14
+ ultralytics
12
15
 
13
16
  [dev-pyqt5]
14
17
  PyQt5
15
18
  PyQt5-sip
16
19
  pytest
17
20
  pytest-cov
21
+ h5py
22
+ pandas
23
+ trackpy
24
+ numba
25
+ ultralytics
18
26
 
19
27
  [dev-pyqt6]
20
28
  PyQt6
21
29
  pytest
22
30
  pytest-cov
31
+ h5py
32
+ pandas
33
+ trackpy
34
+ numba
35
+ ultralytics
23
36
 
24
37
  [docs]
25
38
  pydata-sphinx-theme
26
39
  sphinx
27
40
  sphinx-autodoc-typehints
28
41
 
42
+ [dvr]
43
+ h5py
44
+
29
45
  [genicam]
30
46
  harvesters
31
47
  genicam
32
48
 
49
+ [overlays]
50
+ pandas
51
+ trackpy
52
+ numba
53
+ ultralytics
54
+
33
55
  [picamera]
34
56
  picamera2
35
57
 
@@ -13,8 +13,10 @@ try:
13
13
  IProperty = (IEnumeration, IBoolean, IInteger, IFloat, IString)
14
14
  except (ImportError, ModuleNotFoundError) as exc:
15
15
  raise ImportError(
16
- "QGenicamCamera requires the 'genicam' and 'harvesters' packages. "
17
- "Install them with: pip install genicam harvesters"
16
+ f"QGenicamCamera could not import 'genicam' or 'harvesters': {exc}\n"
17
+ '\tInstall them with: pip install genicam harvesters\n'
18
+ '\tIf the packages are installed, a NumPy version mismatch may be the cause:\n'
19
+ '\t pip install "numpy<2"'
18
20
  ) from exc
19
21
 
20
22
 
@@ -0,0 +1,6 @@
1
+ from ._camera import QOpenCVCamera, QOpenCVSource
2
+ from ._tree import QOpenCVTree
3
+ from ._devices import QOpenCVDevices
4
+
5
+
6
+ __all__ = 'QOpenCVCamera QOpenCVSource QOpenCVTree QOpenCVDevices'.split()
@@ -1,5 +1,5 @@
1
1
  from QVideo.lib import QCamera, QVideoSource
2
- from pyqtgraph.Qt import QtCore
2
+ from QVideo.cameras.OpenCV._devices import configure, probe_formats
3
3
  import cv2
4
4
  import platform
5
5
  import logging
@@ -43,11 +43,31 @@ class QOpenCVCamera(QCamera):
43
43
  On Linux the V4L2 backend is selected automatically; all other
44
44
  platforms use ``CAP_ANY``.
45
45
 
46
+ Resolution and frame rate are configured once at device open time
47
+ via :func:`~QVideo.cameras.OpenCV._devices.configure`. Three modes are
48
+ supported:
49
+
50
+ - **Quality** (default): probes the device, selects the largest
51
+ supported resolution, and sets *fps* (default 30 fps).
52
+ - **Performance** (*fps* ``= None``): probes the device, selects the
53
+ smallest supported resolution, and lets the driver maximize frame
54
+ rate (slo-mo mode).
55
+ - **Explicit** (*width* and *height* both given): applies the
56
+ requested dimensions and *fps* directly.
57
+
58
+ ``width`` and ``height`` are registered as writable properties.
59
+ Changes are applied to the open device via OpenCV's V4L2 backend, which
60
+ handles the required ``VIDIOC_STREAMOFF`` / ``VIDIOC_S_FMT`` /
61
+ ``VIDIOC_STREAMON`` cycle internally. The camera mutex serialises these
62
+ writes against concurrent reads, so no source stop/restart is needed.
63
+ :class:`~QVideo.cameras.OpenCV.QOpenCVTree.QOpenCVTree` exposes them as
64
+ read-only display fields; the ``resolution`` enum in that tree changes
65
+ width, height, and fps together.
46
66
  Transform properties (``mirrored``, ``flipped``) are registered
47
- immediately on construction. Device properties (``width``,
48
- ``height``, ``color``, and any properties in :data:`_PROBED_PROPS`
49
- that the device supports) are registered inside :meth:`_initialize`
50
- once the capture device is open.
67
+ immediately on construction. Device properties (``color``, and any
68
+ properties in :data:`_PROBED_PROPS` that the device supports) are
69
+ registered inside :meth:`_initialize` once the capture device is
70
+ open.
51
71
 
52
72
  Parameters
53
73
  ----------
@@ -60,6 +80,15 @@ class QOpenCVCamera(QCamera):
60
80
  gray : bool
61
81
  Initial grayscale state. Equivalent to opening with ``color=False``.
62
82
  Default: ``False`` (color output).
83
+ width : int or None
84
+ Desired frame width [pixels]. Must be paired with *height* for
85
+ explicit mode. ``None`` triggers auto-selection. Default: ``None``.
86
+ height : int or None
87
+ Desired frame height [pixels]. Must be paired with *width* for
88
+ explicit mode. ``None`` triggers auto-selection. Default: ``None``.
89
+ fps : float or None
90
+ Desired frame rate [fps]. ``None`` selects performance mode.
91
+ Default: ``30.``.
63
92
  *args :
64
93
  Forwarded to :class:`~QVideo.lib.QCamera`.
65
94
  **kwargs :
@@ -77,12 +106,18 @@ class QOpenCVCamera(QCamera):
77
106
  mirrored: bool = False,
78
107
  flipped: bool = False,
79
108
  gray: bool = False,
109
+ width: int | None = None,
110
+ height: int | None = None,
111
+ fps: float | None = 30.,
80
112
  **kwargs) -> None:
81
113
  super().__init__(*args, **kwargs)
82
114
  self.cameraID = cameraID
83
115
  self._mirrored = bool(mirrored)
84
116
  self._flipped = bool(flipped)
85
117
  self._gray = bool(gray)
118
+ self._configWidth = width
119
+ self._configHeight = height
120
+ self._configFps = fps
86
121
  self.registerProperty('mirrored', ptype=bool)
87
122
  self.registerProperty('flipped', ptype=bool)
88
123
  self.open()
@@ -90,9 +125,12 @@ class QOpenCVCamera(QCamera):
90
125
  def _initialize(self) -> bool:
91
126
  '''Open the OpenCV VideoCapture device and register device properties.
92
127
 
93
- Registers ``width``, ``height``, and ``color`` unconditionally,
94
- then probes the device for each property in :data:`_PROBED_PROPS`
95
- and registers those it supports.
128
+ Configures resolution and frame rate via
129
+ :func:`~QVideo.cameras.OpenCV._devices.configure` using the values supplied
130
+ at construction time. Registers ``width`` and ``height`` as
131
+ writable properties, ``color`` as read-write, then probes the
132
+ device for each property in :data:`_PROBED_PROPS` and registers
133
+ those it supports.
96
134
 
97
135
  Returns
98
136
  -------
@@ -101,6 +139,13 @@ class QOpenCVCamera(QCamera):
101
139
  '''
102
140
  api = cv2.CAP_V4L2 if platform.system() == 'Linux' else cv2.CAP_ANY
103
141
  self.device = cv2.VideoCapture(self.cameraID, api)
142
+ # Probe supported resolutions and their actual maximum frame rates on
143
+ # the live device before configuring. QtMultimedia nominal fps values
144
+ # are unreliable; reading back what the V4L2 driver accepts is accurate.
145
+ self._formats = probe_formats(self.device)
146
+ resolutions = [(w, h) for w, h, *_ in self._formats] or None
147
+ configure(self.device, self._configWidth, self._configHeight,
148
+ self._configFps, resolutions=resolutions)
104
149
  for _ in range(5):
105
150
  if (ready := self.device.read()[0]):
106
151
  break
@@ -112,6 +157,7 @@ class QOpenCVCamera(QCamera):
112
157
  self.registerProperty('color', getter=self._getColor,
113
158
  setter=self._setColor, ptype=bool)
114
159
  self._probeProperties()
160
+ self.shapeChanged.emit(self.shape)
115
161
  else:
116
162
  self.device.release()
117
163
  return ready
@@ -127,10 +173,12 @@ class QOpenCVCamera(QCamera):
127
173
  for name, (prop_id, ptype) in _PROBED_PROPS.items():
128
174
  value = self.device.get(prop_id)
129
175
  if self.device.set(prop_id, value):
176
+ setter = (self._setFps if name == 'fps'
177
+ else lambda v, p=prop_id: self.device.set(p, v))
130
178
  self.registerProperty(
131
179
  name,
132
180
  getter=lambda p=prop_id, t=ptype: t(self.device.get(p)),
133
- setter=lambda v, p=prop_id: self.device.set(p, v),
181
+ setter=setter,
134
182
  ptype=ptype)
135
183
  registered.append(name)
136
184
  else:
@@ -146,16 +194,41 @@ class QOpenCVCamera(QCamera):
146
194
  return int(self.device.get(self.WIDTH))
147
195
 
148
196
  def _setWidth(self, value: int) -> None:
149
- self.device.set(self.WIDTH, value)
197
+ '''Set the frame width on the open device.
198
+
199
+ Stores the value for the next :meth:`_initialize` and writes it to
200
+ the device immediately. OpenCV's V4L2 backend handles the required
201
+ ``VIDIOC_STREAMOFF`` / ``VIDIOC_S_FMT`` / ``VIDIOC_STREAMON`` cycle
202
+ internally, so no device close/reopen is needed. The caller must not
203
+ be holding :attr:`~QVideo.lib.QCamera.QCamera.mutex` — use
204
+ :meth:`~QVideo.lib.QCamera.QCamera.set` which acquires it.
205
+ '''
206
+ self._configWidth = int(value)
207
+ self.device.set(self.WIDTH, self._configWidth)
150
208
  self.shapeChanged.emit(self.shape)
151
209
 
152
210
  def _getHeight(self) -> int:
153
211
  return int(self.device.get(self.HEIGHT))
154
212
 
155
213
  def _setHeight(self, value: int) -> None:
156
- self.device.set(self.HEIGHT, value)
214
+ '''Set the frame height on the open device.
215
+
216
+ See :meth:`_setWidth` for rationale.
217
+ '''
218
+ self._configHeight = int(value)
219
+ self.device.set(self.HEIGHT, self._configHeight)
157
220
  self.shapeChanged.emit(self.shape)
158
221
 
222
+ def _setFps(self, value: float) -> None:
223
+ '''Store the requested frame rate and apply it to the open device.
224
+
225
+ Unlike width/height, frame-rate changes in V4L2 do not require
226
+ stopping the stream, so the value is written to the device
227
+ immediately as well as stored for the next :meth:`_initialize`.
228
+ '''
229
+ self._configFps = float(value)
230
+ self.device.set(self.FPS, self._configFps)
231
+
159
232
  def _getColor(self) -> bool:
160
233
  '''Return color mode
161
234
  ``True`` if frames are delivered in color