pyppbox 3.3b1__tar.gz → 3.4b2__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 (92) hide show
  1. {pyppbox-3.3b1 → pyppbox-3.4b2}/GETSTARTED.md +5 -5
  2. {pyppbox-3.3b1/pyppbox.egg-info → pyppbox-3.4b2}/PKG-INFO +2 -2
  3. {pyppbox-3.3b1 → pyppbox-3.4b2}/README.md +1 -1
  4. {pyppbox-3.3b1 → pyppbox-3.4b2}/RELEASENOTES.md +20 -0
  5. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/__init__.py +1 -1
  6. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/config/unifiedstrings.py +4 -4
  7. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/detectors/yolocls/__init__.py +10 -5
  8. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/detectors/yoloult/__init__.py +12 -6
  9. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/standalone/__init__.py +16 -2
  10. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/standalone/mt.py +20 -2
  11. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/utils/evatools.py +14 -6
  12. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/utils/gttools.py +1 -1
  13. pyppbox-3.4b2/pyppbox/utils/mot2pyppbox.py +157 -0
  14. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/utils/persontools.py +51 -10
  15. {pyppbox-3.3b1 → pyppbox-3.4b2/pyppbox.egg-info}/PKG-INFO +2 -2
  16. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox.egg-info/SOURCES.txt +1 -0
  17. {pyppbox-3.3b1 → pyppbox-3.4b2}/LICENSE +0 -0
  18. {pyppbox-3.3b1 → pyppbox-3.4b2}/MANIFEST.in +0 -0
  19. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/config/__init__.py +0 -0
  20. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/config/cfg/cfg.7z +0 -0
  21. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/config/cfg/detectors.yaml +0 -0
  22. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/config/cfg/main.yaml +0 -0
  23. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/config/cfg/reiders.yaml +0 -0
  24. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/config/cfg/trackers.yaml +0 -0
  25. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/config/configtools.py +0 -0
  26. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/config/myconfig.py +0 -0
  27. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/config/strings/strings.yaml +0 -0
  28. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/data/datasets/.gitignore +0 -0
  29. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/data/logs/.gitignore +0 -0
  30. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/data/modules/.gitignore +0 -0
  31. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/data/res/.gitignore +0 -0
  32. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/data/res/idmap.txt +0 -0
  33. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/__init__.py +0 -0
  34. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/assets/TReID.png +0 -0
  35. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/assets/icon.ico +0 -0
  36. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/assets/settings.ico +0 -0
  37. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/guidemo.py +0 -0
  38. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/guihub.py +0 -0
  39. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/guitools.py +0 -0
  40. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/tmp/input.tmp +0 -0
  41. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/tmp/ui.tmp +0 -0
  42. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/ui_centroid.py +0 -0
  43. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/ui_deepsort.py +0 -0
  44. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/ui_facenet.py +0 -0
  45. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/ui_gt.py +0 -0
  46. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/ui_launcher.py +0 -0
  47. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/ui_sort.py +0 -0
  48. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/ui_torchreid.py +0 -0
  49. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/ui_yolocls.py +0 -0
  50. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/gui/ui_yoloult.py +0 -0
  51. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/__init__.py +0 -0
  52. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/detectors/__init__.py +0 -0
  53. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/reiders/__init__.py +0 -0
  54. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/reiders/facenet/__init__.py +0 -0
  55. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/reiders/facenet/origin/align_dataset_mtcnn.py +0 -0
  56. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/reiders/facenet/origin/detect_face.py +0 -0
  57. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/reiders/facenet/origin/facenet.py +0 -0
  58. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/reiders/torchreid/__init__.py +0 -0
  59. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/reiders/torchreid/model_dict.py +0 -0
  60. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/reiders/torchreid/model_dict.yaml +0 -0
  61. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/reiders/torchreid/utils.py +0 -0
  62. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/trackers/__init__.py +0 -0
  63. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/trackers/centroid/__init__.py +0 -0
  64. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/trackers/deepsort/__init__.py +0 -0
  65. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/trackers/deepsort/origin/detection.py +0 -0
  66. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/trackers/deepsort/origin/detection_yolo.py +0 -0
  67. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/trackers/deepsort/origin/generate_detections.py +0 -0
  68. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/trackers/deepsort/origin/iou_matching.py +0 -0
  69. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/trackers/deepsort/origin/kalman_filter.py +0 -0
  70. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/trackers/deepsort/origin/linear_assignment.py +0 -0
  71. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/trackers/deepsort/origin/nn_matching.py +0 -0
  72. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/trackers/deepsort/origin/preprocessing.py +0 -0
  73. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/trackers/deepsort/origin/track.py +0 -0
  74. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/trackers/deepsort/origin/tracker.py +0 -0
  75. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/trackers/deepsort/origin/voc_classes.txt +0 -0
  76. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/trackers/sort/__init__.py +0 -0
  77. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/modules/trackers/sort/origin/sort.py +0 -0
  78. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/utils/__init__.py +0 -0
  79. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/utils/commontools.py +0 -0
  80. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/utils/logtools.py +0 -0
  81. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/utils/restools.py +0 -0
  82. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox/utils/visualizetools.py +0 -0
  83. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox.egg-info/dependency_links.txt +0 -0
  84. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox.egg-info/requires.txt +0 -0
  85. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyppbox.egg-info/top_level.txt +0 -0
  86. {pyppbox-3.3b1 → pyppbox-3.4b2}/pyproject.toml +0 -0
  87. {pyppbox-3.3b1 → pyppbox-3.4b2}/requirements/README.md +0 -0
  88. {pyppbox-3.3b1 → pyppbox-3.4b2}/requirements/requirements.txt +0 -0
  89. {pyppbox-3.3b1 → pyppbox-3.4b2}/requirements/test_gpu.py +0 -0
  90. {pyppbox-3.3b1 → pyppbox-3.4b2}/setup.cfg +0 -0
  91. {pyppbox-3.3b1 → pyppbox-3.4b2}/setup.py +0 -0
  92. {pyppbox-3.3b1 → pyppbox-3.4b2}/setup_extra.yaml +0 -0
@@ -90,11 +90,11 @@ You need to install the main package which is `pyppbox` and the data for the mod
90
90
  - Download the latest from [releases](https://github.com/rathaumons/pyppbox-data/releases)
91
91
  - Or install the ones you need directly:
92
92
  ```
93
- pip install https://github.com/rathaumons/pyppbox-data/releases/download/v1.1.0/pyppbox_data_yolocls-1.1.0-py3-none-any.whl
94
- pip install https://github.com/rathaumons/pyppbox-data/releases/download/v1.1.0/pyppbox_data_yoloult-1.1.0-py3-none-any.whl
95
- pip install https://github.com/rathaumons/pyppbox-data/releases/download/v1.1.0/pyppbox_data_deepsort-1.1.0-py3-none-any.whl
96
- pip install https://github.com/rathaumons/pyppbox-data/releases/download/v1.1.0/pyppbox_data_facenet-1.1.0-py3-none-any.whl
97
- pip install https://github.com/rathaumons/pyppbox-data/releases/download/v1.1.0/pyppbox_data_torchreid-1.1.0-py3-none-any.whl
93
+ pip install https://github.com/rathaumons/pyppbox-data/releases/download/v1.1.1/pyppbox_data_yolocls-1.1.1-py3-none-any.whl
94
+ pip install https://github.com/rathaumons/pyppbox-data/releases/download/v1.1.1/pyppbox_data_yoloult-1.1.1-py3-none-any.whl
95
+ pip install https://github.com/rathaumons/pyppbox-data/releases/download/v1.1.1/pyppbox_data_deepsort-1.1.1-py3-none-any.whl
96
+ pip install https://github.com/rathaumons/pyppbox-data/releases/download/v1.1.1/pyppbox_data_facenet-1.1.1-py3-none-any.whl
97
+ pip install https://github.com/rathaumons/pyppbox-data/releases/download/v1.1.1/pyppbox_data_torchreid-1.1.1-py3-none-any.whl
98
98
  ```
99
99
 
100
100
  * Install [`pyppbox-data-gta5`](https://github.com/rathaumons/PoseTReID_DATASET#-introducing-pyppbox-data-gta5)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyppbox
3
- Version: 3.3b1
3
+ Version: 3.4b2
4
4
  Summary: Toolbox for people detecting, tracking, and re-identifying.
5
5
  Home-page: https://github.com/rathaumons/pyppbox
6
6
  Author: Ratha SIV
@@ -74,7 +74,7 @@ Requires-Dist: pyppbox-ultralytics>=8.0.218
74
74
 
75
75
  </div>
76
76
 
77
- ***pyppbox*** is an all-in-one Python toolbox which can be used for detecting, tracking, and re-identifying people with only a few lines of codes. It is originally made for [***PoseTReID framework***](https://github.com/rathaumons/PoseTReID_DATASET) which can effectively track specific/certain people across multiple cameras or video scenes in distributed contexts of people interaction spaces such as malls or amusement parks, etc.
77
+ ***pyppbox*** is an all-in-one Python toolbox which can be used for detecting, tracking, and re-identifying people with only a few lines of code. It is originally made for [***PoseTReID framework***](https://github.com/rathaumons/PoseTReID_DATASET) which can effectively track specific/certain people across multiple cameras or video scenes in distributed contexts of people interaction spaces such as malls or amusement parks, etc.
78
78
 
79
79
  * ` pyppbox = Python + People + Toolbox `
80
80
  * Design for both short and long term people detecting, tracking, and re-identifying.
@@ -12,7 +12,7 @@
12
12
 
13
13
  </div>
14
14
 
15
- ***pyppbox*** is an all-in-one Python toolbox which can be used for detecting, tracking, and re-identifying people with only a few lines of codes. It is originally made for [***PoseTReID framework***](https://github.com/rathaumons/PoseTReID_DATASET) which can effectively track specific/certain people across multiple cameras or video scenes in distributed contexts of people interaction spaces such as malls or amusement parks, etc.
15
+ ***pyppbox*** is an all-in-one Python toolbox which can be used for detecting, tracking, and re-identifying people with only a few lines of code. It is originally made for [***PoseTReID framework***](https://github.com/rathaumons/PoseTReID_DATASET) which can effectively track specific/certain people across multiple cameras or video scenes in distributed contexts of people interaction spaces such as malls or amusement parks, etc.
16
16
 
17
17
  * ` pyppbox = Python + People + Toolbox `
18
18
  * Design for both short and long term people detecting, tracking, and re-identifying.
@@ -2,6 +2,26 @@
2
2
 
3
3
  ## **pyppbox V3 - Make Simpler and Faster**
4
4
 
5
+ * `pyppbox` [v3.4b2](https://github.com/rathaumons/pyppbox/tree/v3.4b2)
6
+
7
+ - Add freedom of input video without GT (Ground-truth) in GUI demo
8
+ - Update GitHub workflows
9
+ - Update and improve documentations
10
+ - **Known issue/limitation**:
11
+ - You tell me :)
12
+
13
+ * `pyppbox` [v3.4b1](https://github.com/rathaumons/pyppbox/tree/v3.4b1)
14
+
15
+ - Remove `findRepspointList()` from `pyppbox.utils.persontools`
16
+ - Add `findRepspointBB()` and `findRepspointUP()` to `pyppbox.utils.persontools`
17
+ - Add float support for the private `convertStringToNPL()` of `pyppbox.utils.gttools`
18
+ - Add `min_width_filter` support for `detectPeople()` of `ppbox.standalone`
19
+ - Add alternative repspoint support for `detectPeople()` of `ppbox.standalone` and all detectors
20
+ - Add [MOT Challenge ground-truth](https://motchallenge.net/instructions/) converter -> `pyppbox.utils.mot2pyppbox`
21
+ - Improve documentations
22
+ - **Known issue/limitation**:
23
+ - You tell me :)
24
+
5
25
  * `pyppbox` [v3.3b1](https://github.com/rathaumons/pyppbox/tree/v3.3b1)
6
26
 
7
27
  - Remove `ontracked` and its related methods from `pyppbox.utils.persontools.Person`
@@ -47,7 +47,7 @@ from pyppbox.gui.guitools import (
47
47
  )
48
48
 
49
49
 
50
- __version__ = '3.3b1'
50
+ __version__ = '3.4b2'
51
51
  __author__ = 'Ratha SIV'
52
52
  __description__ = 'Toolbox for people detecting, tracking, and re-identifying.'
53
53
  __homepage__ = 'https://rathaumons.github.io/pyppbox'
@@ -46,9 +46,9 @@ class UnifiedStrings(object):
46
46
  gt : str, auto
47
47
  Unified string of words 'Ground-truth'.
48
48
  yolo_cls : str, auto
49
- Unified string of wordS 'Yolo Classic'.
49
+ Unified string of words 'Yolo Classic'.
50
50
  yolo_ult : str, auto
51
- Unified string of wordS 'Yolo Ultralytics'.
51
+ Unified string of words 'Yolo Ultralytics'.
52
52
  sort : str, auto
53
53
  Unified string of word 'SORT'.
54
54
  deepsort : str, auto
@@ -60,9 +60,9 @@ class UnifiedStrings(object):
60
60
  torchreid : str, auto
61
61
  Unified string of word 'Torchreid'.
62
62
  dtname_yl : str, auto
63
- Unified string of wordS 'Detector YOLO'.
63
+ Unified string of words 'Detector YOLO'.
64
64
  dtname_gt : str, auto
65
- Unified string of wordS 'Detector GT'.
65
+ Unified string of words 'Detector GT'.
66
66
  tkname_ct : str, auto
67
67
  Unified string of words 'Tracker Centroid'.
68
68
  tkname_st : str, auto
@@ -21,7 +21,7 @@
21
21
 
22
22
  import cv2
23
23
 
24
- from pyppbox.utils.persontools import Person, findRepspoint
24
+ from pyppbox.utils.persontools import Person, findRepspoint, findRepspointBB
25
25
  from pyppbox.utils.commontools import to_xyxy
26
26
 
27
27
 
@@ -108,7 +108,7 @@ class MyYOLOCLS(object):
108
108
  (box_xyxy[2], box_xyxy[3]), (255, 255, 0), 2)
109
109
  return img, pboxes_xywh, pboxes_xyxy, repspoints, confs
110
110
 
111
- def detectPeople(self, img, visual=True, min_width_filter=35):
111
+ def detectPeople(self, img, visual=True, min_width_filter=35, alt_repspoint=False, alt_repspoint_top=True):
112
112
  """Detect person(s) in a given cv :obj:`Mat` image.
113
113
 
114
114
  Parameters
@@ -116,9 +116,13 @@ class MyYOLOCLS(object):
116
116
  img : Mat
117
117
  A cv :obj:`Mat` image.
118
118
  visual : bool, default=True
119
- An indication of whether to visualize the detected objects.
119
+ An indication of whether to visualize the detected people.
120
120
  min_width_filter : int, default=35
121
- Mininum width filter of a detected object.
121
+ Mininum width filter of a detected person.
122
+ alt_repspoint : bool, default=False
123
+ An indication of whether to use the alternative :meth:`findRepspointBB`.
124
+ alt_repspoint_top : bool, default=True
125
+ A parameter passed to :obj:`prefer_top` of :meth:`findRepspointBB`.
122
126
 
123
127
  Returns
124
128
  -------
@@ -139,7 +143,8 @@ class MyYOLOCLS(object):
139
143
  if class_id == 0 and box_xywh[2] >= min_width_filter:
140
144
  box_xywh = box_xywh.astype(int)
141
145
  box_xyxy = to_xyxy(box_xywh)
142
- repspoint = findRepspoint(box_xyxy, self.cfg.repspoint_calibration)
146
+ if alt_repspoint: repspoint = findRepspointBB(box_xyxy, prefer_top=alt_repspoint_top)
147
+ else: repspoint = findRepspoint(box_xyxy, self.cfg.repspoint_calibration)
143
148
  people.append(Person(i, i, box_xywh=box_xywh, box_xyxy=box_xyxy,
144
149
  repspoint=repspoint, det_conf=float(conf)))
145
150
  i += 1
@@ -21,7 +21,7 @@
21
21
 
22
22
  import cv2
23
23
 
24
- from pyppbox.utils.persontools import Person, findRepspoint
24
+ from pyppbox.utils.persontools import Person, findRepspoint, findRepspointBB
25
25
  from pyppbox.utils.commontools import to_xywh
26
26
  from pyppbox.utils.logtools import ignore_this_logger
27
27
 
@@ -204,7 +204,7 @@ class MyYOLOULT(object):
204
204
  (box_xyxy[2], box_xyxy[3]), (255, 255, 0), 2)
205
205
  return img, pboxes_xywh, pboxes_xyxy, repspoints, keypoints, confs
206
206
 
207
- def detectPeople(self, img, visual=True, min_width_filter=35):
207
+ def detectPeople(self, img, visual=True, min_width_filter=35, alt_repspoint=False, alt_repspoint_top=True):
208
208
  """Detect person(s) in a given cv :obj:`Mat` image.
209
209
 
210
210
  Parameters
@@ -212,9 +212,13 @@ class MyYOLOULT(object):
212
212
  img : Mat
213
213
  A cv :obj:`Mat` image.
214
214
  visual : bool, default=True
215
- An indication of whether to visualize the detected objects.
215
+ An indication of whether to visualize the detected people.
216
216
  min_width_filter : int, default=35
217
- Mininum width filter of a detected object.
217
+ Mininum width filter of a detected person.
218
+ alt_repspoint : bool, default=False
219
+ An indication of whether to use the alternative :meth:`findRepspointBB`.
220
+ alt_repspoint_top : bool, default=True
221
+ A parameter passed to :obj:`prefer_top` of :meth:`findRepspointBB`.
218
222
 
219
223
  Returns
220
224
  -------
@@ -250,7 +254,8 @@ class MyYOLOULT(object):
250
254
  box_xywh = to_xywh(box_xyxy)
251
255
  if box_xywh[2] >= min_width_filter:
252
256
  keypoint = kp.data[0]
253
- repspoint = findRepspoint(box_xyxy, self.cfg.repspoint_calibration)
257
+ if alt_repspoint: repspoint = findRepspointBB(box_xyxy, prefer_top=alt_repspoint_top)
258
+ else: repspoint = findRepspoint(box_xyxy, self.cfg.repspoint_calibration)
254
259
  people.append(Person(i, i, box_xywh=box_xywh, box_xyxy=box_xyxy,
255
260
  keypoints=keypoint, repspoint=repspoint, det_conf=float(conf)))
256
261
  i += 1
@@ -266,7 +271,8 @@ class MyYOLOULT(object):
266
271
  box_xyxy = box_xyxy.astype(int)
267
272
  box_xywh = to_xywh(box_xyxy)
268
273
  if box_xywh[2] >= min_width_filter:
269
- repspoint = findRepspoint(box_xyxy, self.cfg.repspoint_calibration)
274
+ if alt_repspoint: repspoint = findRepspointBB(box_xyxy, prefer_top=alt_repspoint_top)
275
+ else: repspoint = findRepspoint(box_xyxy, self.cfg.repspoint_calibration)
270
276
  people.append(Person(i, i, box_xywh=box_xywh, box_xyxy=box_xyxy,
271
277
  repspoint=repspoint, det_conf=float(conf)))
272
278
  i += 1
@@ -91,9 +91,23 @@ def setMainDetector(detector=""):
91
91
  """See :func:`pyppbox.standalone.mt.MT.setMainDetector`"""
92
92
  __stdmt__.setMainDetector(detector=detector)
93
93
 
94
- def detectPeople(img, img_is_mat=False, visual=False, save=False, save_file=""):
94
+ def detectPeople(img,
95
+ img_is_mat=False,
96
+ visual=False,
97
+ save=False,
98
+ save_file="",
99
+ min_width_filter=35,
100
+ alt_repspoint=False,
101
+ alt_repspoint_top=True):
95
102
  """See :func:`pyppbox.standalone.mt.MT.detectPeople`"""
96
- return __stdmt__.detectPeople(img, img_is_mat=img_is_mat, visual=visual, save=save, save_file=save_file)
103
+ return __stdmt__.detectPeople(img,
104
+ img_is_mat=img_is_mat,
105
+ visual=visual,
106
+ save=save,
107
+ save_file=save_file,
108
+ min_width_filter=min_width_filter,
109
+ alt_repspoint=alt_repspoint,
110
+ alt_repspoint_top=alt_repspoint_top)
97
111
 
98
112
  def setMainTracker(tracker=""):
99
113
  """See :func:`pyppbox.standalone.mt.MT.setMainTracker`"""
@@ -409,7 +409,15 @@ class MT(object):
409
409
  else:
410
410
  add_warning_log("---PYPPBOX : detector='" + str(detector) + "' is not recognized.")
411
411
 
412
- def detectPeople(self, img, img_is_mat=False, visual=False, save=False, save_file=""):
412
+ def detectPeople(self,
413
+ img,
414
+ img_is_mat=False,
415
+ visual=False,
416
+ save=False,
417
+ save_file="",
418
+ min_width_filter=35,
419
+ alt_repspoint=False,
420
+ alt_repspoint_top=True):
413
421
  """Detect people by giving an image. :func:`setConfigDir()` or :func:`setMainDetector()` must
414
422
  be called in advance.
415
423
 
@@ -426,6 +434,12 @@ class MT(object):
426
434
  Decide whether to save the return :obj:`img` to a JPG file.
427
435
  save_file : str, default=""
428
436
  Indicate a path of where to save the processed image.
437
+ min_width_filter : int, default=35
438
+ Mininum width filter of a detected person.
439
+ alt_repspoint : bool, default=False
440
+ An indication of whether to use the alternative :meth:`findRepspointBB`.
441
+ alt_repspoint_top : bool, default=True
442
+ A parameter passed to :obj:`prefer_top` of :meth:`findRepspointBB`.
429
443
 
430
444
  Returns
431
445
  -------
@@ -440,7 +454,11 @@ class MT(object):
440
454
  if not img_is_mat: img = getCVMat(img)
441
455
  if (self.__dt_cfg__.dt_name.lower() == self.__unistrings__.yolo_cls or
442
456
  self.__dt_cfg__.dt_name.lower() == self.__unistrings__.yolo_ult):
443
- people, img = self.__dt__.detectPeople(img, visual=visual)
457
+ people, img = self.__dt__.detectPeople(img,
458
+ visual=visual,
459
+ min_width_filter=min_width_filter,
460
+ alt_repspoint=alt_repspoint,
461
+ alt_repspoint_top=alt_repspoint_top)
444
462
  elif self.__dt_cfg__.dt_name.lower() == self.__unistrings__.gt:
445
463
  people, img = self.__dt__.getPeople(img, visual=visual)
446
464
  if save:
@@ -65,6 +65,7 @@ class MyEVA(object):
65
65
  self.current_frame = 0
66
66
  self.frame_to_check = 0
67
67
  self.id_mode = "deepid"
68
+ self.no_gt = False
68
69
 
69
70
  def setGTByGTMap(self, gt_map_txt, input_video, id_mode="deepid"):
70
71
  """Set a GT (Ground-truth) text file by give the GT mapping file :obj:`gt_map_txt` and
@@ -96,8 +97,10 @@ class MyEVA(object):
96
97
  else:
97
98
  msg = ("MyEVA : setGTByGTMap() -> There is no GT file for the input '" +
98
99
  str(input_video) + "'")
99
- add_error_log(msg)
100
- raise ValueError(msg)
100
+ # add_error_log(msg)
101
+ # raise ValueError(msg)
102
+ add_warning_log(msg)
103
+ self.no_gt = True
101
104
 
102
105
 
103
106
  def setGTByKnownGTFile(self, gt_file, id_mode="deepid"):
@@ -125,8 +128,10 @@ class MyEVA(object):
125
128
  else:
126
129
  msg = ("MyEVA : setGTByKnownGTFile() -> The input gt_file='" +
127
130
  str(gt_file) + "' does not exist")
128
- add_error_log(msg)
129
- raise ValueError(msg)
131
+ # add_error_log(msg)
132
+ # raise ValueError(msg)
133
+ add_warning_log(msg)
134
+ self.no_gt = True
130
135
 
131
136
  def __checkInReID__(self):
132
137
  self.reid_count += 1
@@ -298,8 +303,11 @@ class MyEVA(object):
298
303
  score : float
299
304
  Score of the evaluation, between 0 and 1 -> (Total ID - Wrong ID - Missed Detection) / Total ID.
300
305
  """
301
- self.score = float((self.gt_interpreter.total_detections - self.diff_count -
302
- self.missed_detect) / self.gt_interpreter.total_detections)
306
+ if self.no_gt:
307
+ self.score = 0.0
308
+ else:
309
+ self.score = float((self.gt_interpreter.total_detections - self.diff_count -
310
+ self.missed_detect) / self.gt_interpreter.total_detections)
303
311
  if print_summary:
304
312
  msg = ("\n#####################################################################\n\n" +
305
313
  " Summary: \n\n" +
@@ -326,7 +326,7 @@ def convertStringToNPL(input):
326
326
  input = input.replace("[", "")
327
327
  input = input.replace("]", "")
328
328
  input = " ".join(input.split())
329
- input_list = list(map(int, input.split()))
329
+ input_list = list(map(float, input.split()))
330
330
  return np.array(input_list).astype(int)
331
331
 
332
332
  def formatLineInGTMap(line, splitter=':'):
@@ -0,0 +1,157 @@
1
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
2
+ # #
3
+ # pyppbox: Toolbox for people detecting, tracking, and re-identifying. #
4
+ # Copyright (C) 2022 UMONS-Numediart #
5
+ # #
6
+ # This program is free software: you can redistribute it and/or modify #
7
+ # it under the terms of the GNU General Public License as published by #
8
+ # the Free Software Foundation, either version 3 of the License, or #
9
+ # (at your option) any later version. #
10
+ # #
11
+ # This program is distributed in the hope that it will be useful, #
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14
+ # GNU General Public License for more details. #
15
+ # #
16
+ # You should have received a copy of the GNU General Public License #
17
+ # along with this program. If not, see <https://www.gnu.org/licenses/>. #
18
+ # #
19
+ # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
20
+
21
+
22
+ import argparse
23
+
24
+ from pyppbox.utils.gttools import convertStringToNPL
25
+ from pyppbox.utils.commontools import to_xyxy
26
+ from pyppbox.utils.persontools import findRepspoint, findRepspointBB
27
+
28
+ # step 0: filter conf
29
+ def filter_conf(input_line, splitter=',', min_conf=0.25, max_conf=1.00):
30
+ """
31
+ :meta private:
32
+ """
33
+ res = False
34
+ spl_indexs = [i for i, char in enumerate(input_line) if char == splitter]
35
+ conf = float(input_line[spl_indexs[5] + 1:spl_indexs[6]])
36
+ if conf >= min_conf and conf <= max_conf:
37
+ res = True
38
+ return res
39
+
40
+ # step 1: remove the last 4 columns (from coma 6th)
41
+ def remove_from_splitter(input_line, splitter=',', from_spl=6, with_newline=False):
42
+ """
43
+ :meta private:
44
+ """
45
+ spl_indexs = [i for i, char in enumerate(input_line) if char == splitter]
46
+ res = input_line[:spl_indexs[from_spl - 1]]
47
+ if with_newline: res = res + "\n"
48
+ return res
49
+
50
+ # step 2: replace 2nd colum with repspoint and readID
51
+ def replace_column_with(input_line, splitter=',', column_index=2, with_str="(0, 0) XXX", with_newline=False):
52
+ """
53
+ :meta private:
54
+ """
55
+ spl_indexs = [i for i, char in enumerate(input_line) if char == splitter]
56
+ res = input_line[0:spl_indexs[column_index - 2] + 1] + with_str + input_line[spl_indexs[column_index - 1]:]
57
+ if with_newline: res = res + "\n"
58
+ return res
59
+
60
+ # step 3: finalize
61
+ def finalize(input_line, splitter=',', find_repspoint=True, alt_repspoint=False, alt_repspoint_top=True, with_newline=False):
62
+ """
63
+ :meta private:
64
+ """
65
+ spl_indexs = [i for i, char in enumerate(input_line) if char == splitter]
66
+ input_line = input_line[0:spl_indexs[0]] + '\t' + input_line[spl_indexs[0] + 1:]
67
+ bbox = input_line[spl_indexs[2] + 1:]
68
+ bbox = bbox.replace(',', ' ')
69
+ bbox_xyxy_np = to_xyxy(convertStringToNPL(bbox))
70
+ res = input_line[0:spl_indexs[2]] + "\t[" + bbox + ']\t' + str(bbox_xyxy_np)
71
+ if find_repspoint:
72
+ repspoint = "(0, 0)"
73
+ if alt_repspoint: repspoint = findRepspointBB(bbox_xyxy_np, prefer_top=alt_repspoint_top)
74
+ else: repspoint = findRepspoint(bbox_xyxy_np, calibrate_weight=0.25)
75
+ res = res.replace("(0, 0)", str(repspoint))
76
+ res = res.replace(" ", " ")
77
+ res = res.replace(" ", " ")
78
+ res = res.replace(" ", " ")
79
+ res = res.replace("[ ", "[")
80
+ if with_newline: res = res + "\n"
81
+ return res
82
+
83
+ # AIO
84
+ def convert(input_file="det.txt",
85
+ output_file="det_pyppbox.txt",
86
+ splitter=',',
87
+ min_conf=0.25,
88
+ max_conf=1.00,
89
+ find_repspoint=True,
90
+ alt_repspoint=False,
91
+ alt_repspoint_top=True):
92
+ """Convert ground-truth of MOT Challenge text file to pyppbox format.
93
+
94
+ Parameters
95
+ ----------
96
+ input_file : str, default="det.txt"
97
+ Input MOT Challenge text file.
98
+ output_file : str, default="det_pyppbox.txt"
99
+ Output pyppbox text file.
100
+ splitter : str, default=','
101
+ Column or data splitter.
102
+ min_conf : float, default=0.25
103
+ Filter for minimum conf.
104
+ max_conf : float, default=1.00
105
+ Filter for maximum conf.
106
+ find_repspoint : bool, default=True
107
+ Whether to calculate repspoint.
108
+ alt_repspoint : bool, default=False
109
+ Whether to use alternative repspoint.
110
+ alt_repspoint_top : bool, default=True
111
+ Whether y is the top for alternative repspoint.
112
+ """
113
+
114
+ with open(output_file, 'w') as pyppboxtxt:
115
+ with open(input_file, 'r') as mottxt:
116
+ lines = mottxt.readlines()
117
+ for line in lines:
118
+ if filter_conf(line, splitter=splitter, min_conf=min_conf, max_conf=max_conf):
119
+ line = line.replace("\r", "")
120
+ line = line.replace("\n", "")
121
+ line = remove_from_splitter(line, splitter=splitter)
122
+ line = replace_column_with(line, splitter=splitter)
123
+ line = finalize(line,
124
+ splitter=splitter,
125
+ find_repspoint=find_repspoint,
126
+ alt_repspoint=alt_repspoint,
127
+ alt_repspoint_top=alt_repspoint_top,
128
+ with_newline=True)
129
+ pyppboxtxt.write(line)
130
+
131
+
132
+ ###################################################################################################
133
+
134
+
135
+ if __name__ == "__main__":
136
+
137
+ parser = argparse.ArgumentParser(description="Convert ground-truth of MOT Challenge text file to pyppbox format.")
138
+
139
+ parser.add_argument("--input-file", type=str, default="det.txt", help="Input MOT Challenge text file")
140
+ parser.add_argument("--output-file", type=str, default="det_pyppbox.txt", help="Output pyppbox text file")
141
+ parser.add_argument("--splitter", type=str, default=',', help="Column or data splitter")
142
+ parser.add_argument("--min-conf", type=float, default='0.25', help="Filter for minimum conf")
143
+ parser.add_argument("--max-conf", type=float, default='1.00', help="Filter for maximum conf")
144
+ parser.add_argument("--find-repspoint", type=bool, default=True, help="Whether to calculate repspoint")
145
+ parser.add_argument("--alt-repspoint", type=bool, default=False, help="Whether to use alternative repspoint")
146
+ parser.add_argument("--alt-repspoint-top", type=bool, default=True, help="Whether y is the top for alternative repspoint")
147
+
148
+ args = parser.parse_args()
149
+ convert(input_file=args.input_file,
150
+ output_file=args.output_file,
151
+ splitter=args.splitter,
152
+ min_conf=args.min_conf,
153
+ max_conf=args.max_conf,
154
+ find_repspoint=args.find_repspoint,
155
+ alt_repspoint=args.alt_repspoint,
156
+ alt_repspoint_top=args.alt_repspoint_top)
157
+
@@ -195,26 +195,67 @@ def findRepspoint(box_xyxy, calibrate_weight):
195
195
  y = int(y_start + calibrate_weight*y_dist)
196
196
  return (x, y)
197
197
 
198
- def findRepspointList(box_xyxy, calibrate_weight):
198
+
199
+ def findRepspointBB(box_xyxy, prefer_top=True):
199
200
  """Find respesented point :code:`(x, y)` of a :class:`Person` object by its bounding
200
- :code:`box_xyxy` of :code:`[x1, y1, x2, y2]`. The :obj:`calibrate_weight` indicates,
201
- in between :code:`min(y1, y2)` and :code:`max(y1, y2)`, where the :code:`y` is.
201
+ :code:`box_xyxy` of :code:`[x1, y1, x2, y2]`. :code:`x` is the middle of :code:`x1`
202
+ and :code:`x2` while :code:`y` is the min or max of :code:`(y1, y2)`.
202
203
 
203
204
  Parameters
204
205
  ----------
205
- box_xyxy : ndarray, optional
206
+ box_xyxy : ndarray
206
207
  Bounding box :code:`[x1, y1, x2, y2]`, :code:`shape=(4,)`, :code:`dtype=int`,
207
208
  :code:`ndim=1`.
208
209
  calibrate_weight : float
209
210
  Calibration weight.
211
+ prefer_top : bool, default=True
212
+ Decide whether :code:`y` is at the top or bottom of the bounding box.
210
213
 
211
214
  Returns
212
215
  -------
213
- list[int, int]
214
- Respesented 2D point :code:`[x, y]`.
216
+ tuple(int, int)
217
+ Respesented 2D point :code:`(x, y)`.
215
218
  """
216
219
  x = int((box_xyxy[0] + box_xyxy[2]) / 2)
217
- y_start = min(box_xyxy[1], box_xyxy[3])
218
- y_dist = abs(box_xyxy[1] - box_xyxy[3])
219
- y = int(y_start + calibrate_weight*y_dist)
220
- return [x, y]
220
+ y = 0
221
+ if prefer_top:
222
+ y = min(box_xyxy[1], box_xyxy[3])
223
+ else:
224
+ y = max(box_xyxy[1], box_xyxy[3])
225
+ return (x, y)
226
+
227
+
228
+ def findRepspointUP(keypoint, box_xyxy, calibrate_weight, prefer_box=True):
229
+ """Find respesented point :code:`(x, y)` of a :class:`Person` object by its
230
+ YOLOv8 pose :code:`keypoint` (17 keypoints) or by the bounding :code:`box_xyxy`
231
+ of :code:`[x1, y1, x2, y2]`. The :obj:`calibrate_weight` indicates, in between
232
+ :code:`min(y1, y2)` and :code:`max(y1, y2)`, where the :code:`y` is.
233
+
234
+ Parameters
235
+ ----------
236
+ keypoint : ndarray
237
+ 17 keypoints generated by YOLOv8 (Ultralytics).
238
+ box_xyxy : ndarray
239
+ Bounding box :code:`[x1, y1, x2, y2]`, :code:`shape=(4,)`, :code:`dtype=int`,
240
+ :code:`ndim=1`.
241
+ calibrate_weight : float
242
+ Calibration weight.
243
+ prefer_box : bool, default=True
244
+ Generate respesented point whether by :code:`box_xyxy` or :code:`keypoint`.
245
+
246
+ Returns
247
+ -------
248
+ tuple(int, int)
249
+ Respesented 2D point :code:`(x, y)`.
250
+ """
251
+ x = 0
252
+ y = 0
253
+ if len(keypoint) == 17 and not prefer_box:
254
+ lshd = keypoint[5]
255
+ rshd = keypoint[6]
256
+ x = int((lshd[0] + rshd[0]) / 2)
257
+ y = int((lshd[1] + rshd[1]) / 2)
258
+ else:
259
+ (x, y) = findRepspoint(box_xyxy, calibrate_weight)
260
+ return (x, y)
261
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyppbox
3
- Version: 3.3b1
3
+ Version: 3.4b2
4
4
  Summary: Toolbox for people detecting, tracking, and re-identifying.
5
5
  Home-page: https://github.com/rathaumons/pyppbox
6
6
  Author: Ratha SIV
@@ -74,7 +74,7 @@ Requires-Dist: pyppbox-ultralytics>=8.0.218
74
74
 
75
75
  </div>
76
76
 
77
- ***pyppbox*** is an all-in-one Python toolbox which can be used for detecting, tracking, and re-identifying people with only a few lines of codes. It is originally made for [***PoseTReID framework***](https://github.com/rathaumons/PoseTReID_DATASET) which can effectively track specific/certain people across multiple cameras or video scenes in distributed contexts of people interaction spaces such as malls or amusement parks, etc.
77
+ ***pyppbox*** is an all-in-one Python toolbox which can be used for detecting, tracking, and re-identifying people with only a few lines of code. It is originally made for [***PoseTReID framework***](https://github.com/rathaumons/PoseTReID_DATASET) which can effectively track specific/certain people across multiple cameras or video scenes in distributed contexts of people interaction spaces such as malls or amusement parks, etc.
78
78
 
79
79
  * ` pyppbox = Python + People + Toolbox `
80
80
  * Design for both short and long term people detecting, tracking, and re-identifying.
@@ -81,6 +81,7 @@ pyppbox/utils/commontools.py
81
81
  pyppbox/utils/evatools.py
82
82
  pyppbox/utils/gttools.py
83
83
  pyppbox/utils/logtools.py
84
+ pyppbox/utils/mot2pyppbox.py
84
85
  pyppbox/utils/persontools.py
85
86
  pyppbox/utils/restools.py
86
87
  pyppbox/utils/visualizetools.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes