Spaces:
Runtime error
Runtime error
update
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .gitattributes +1 -0
- .ipynb_checkpoints/app-checkpoint.py +10 -12
- .ipynb_checkpoints/requirements-checkpoint.txt +17 -0
- .ipynb_checkpoints/test-checkpoint.ipynb +113 -0
- LICENSE +201 -0
- README.md +0 -13
- app.py +8 -8
- datasets/.ipynb_checkpoints/__init__-checkpoint.py +0 -23
- datasets/.ipynb_checkpoints/coco-checkpoint.py +0 -649
- datasets/.ipynb_checkpoints/dataset-checkpoint.py +0 -44
- datasets/.ipynb_checkpoints/odvg-checkpoint.py +0 -258
- datasets/.ipynb_checkpoints/transforms-checkpoint.py +0 -285
- datasets/__init__.py +0 -23
- datasets/__pycache__/__init__.cpython-310.pyc +0 -0
- datasets/__pycache__/coco.cpython-310.pyc +0 -0
- datasets/__pycache__/coco_eval.cpython-310.pyc +0 -0
- datasets/__pycache__/cocogrounding_eval.cpython-310.pyc +0 -0
- datasets/__pycache__/data_util.cpython-310.pyc +0 -0
- datasets/__pycache__/odvg.cpython-310.pyc +0 -0
- datasets/__pycache__/panoptic_eval.cpython-310.pyc +0 -0
- datasets/__pycache__/random_crop.cpython-310.pyc +0 -0
- datasets/__pycache__/sltransform.cpython-310.pyc +0 -0
- datasets/__pycache__/transforms.cpython-310.pyc +0 -0
- datasets/coco.py +0 -649
- datasets/coco_eval.py +0 -266
- datasets/coco_panoptic.py +0 -99
- datasets/data_util.py +0 -170
- datasets/dataset.py +0 -44
- datasets/odvg.py +0 -258
- datasets/panoptic_eval.py +0 -44
- datasets/random_crop.py +0 -135
- datasets/sltransform.py +0 -247
- environment.yaml +248 -0
- groundingdino.egg-info/PKG-INFO +213 -0
- groundingdino.egg-info/SOURCES.txt +46 -0
- groundingdino.egg-info/dependency_links.txt +1 -0
- groundingdino.egg-info/requires.txt +10 -0
- groundingdino.egg-info/top_level.txt +1 -0
- groundingdino/.ipynb_checkpoints/__init__-checkpoint.py +0 -0
- groundingdino/.ipynb_checkpoints/version-checkpoint.py +1 -0
- groundingdino/__init__.py +0 -0
- groundingdino/__pycache__/__init__.cpython-310.pyc +0 -0
- groundingdino/config/.ipynb_checkpoints/GroundingDINO_SwinB_cfg-checkpoint.py +43 -0
- groundingdino/config/GroundingDINO_SwinB_cfg.py +43 -0
- groundingdino/config/GroundingDINO_SwinT_OGC.py +43 -0
- groundingdino/config/__init__.py +0 -0
- groundingdino/datasets/__init__.py +0 -0
- groundingdino/datasets/__pycache__/__init__.cpython-310.pyc +0 -0
- groundingdino/datasets/__pycache__/transforms.cpython-310.pyc +0 -0
- {datasets → groundingdino/datasets}/cocogrounding_eval.py +1 -3
.gitattributes
CHANGED
@@ -35,3 +35,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
util/ filter=lfs diff=lfs merge=lfs -text
|
37 |
models/GroundingDINO/ops/build/temp.linux-x86_64-3.10/home/jamada/jupyterlab/projects/gdino-peft/vlm4eo/Open-GroundingDino/models/GroundingDINO/ops/src/vision.o filter=lfs diff=lfs merge=lfs -text
|
|
|
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
util/ filter=lfs diff=lfs merge=lfs -text
|
37 |
models/GroundingDINO/ops/build/temp.linux-x86_64-3.10/home/jamada/jupyterlab/projects/gdino-peft/vlm4eo/Open-GroundingDino/models/GroundingDINO/ops/src/vision.o filter=lfs diff=lfs merge=lfs -text
|
38 |
+
groundingdino/_C.cpython-310-x86_64-linux-gnu.so filter=lfs diff=lfs merge=lfs -text
|
.ipynb_checkpoints/app-checkpoint.py
CHANGED
@@ -3,7 +3,6 @@ from functools import partial
|
|
3 |
import cv2
|
4 |
import requests
|
5 |
import os
|
6 |
-
import sys
|
7 |
from io import BytesIO
|
8 |
from PIL import Image
|
9 |
import numpy as np
|
@@ -17,28 +16,27 @@ import torch
|
|
17 |
# prepare the environment
|
18 |
os.system("python setup.py build develop --user")
|
19 |
os.system("pip install packaging==21.3")
|
20 |
-
os.system("pip install gradio
|
21 |
|
22 |
|
23 |
warnings.filterwarnings("ignore")
|
24 |
|
25 |
import gradio as gr
|
26 |
-
|
27 |
-
|
28 |
-
from
|
29 |
-
from util.
|
30 |
-
from util.
|
31 |
-
|
32 |
-
import datasets.transforms as T
|
33 |
|
34 |
from huggingface_hub import hf_hub_download
|
35 |
|
36 |
|
37 |
|
38 |
# Use this command for evaluate the Grounding DINO model
|
39 |
-
config_file = "
|
40 |
-
ckpt_repo_id = "
|
41 |
-
ckpt_filenmae = "
|
42 |
|
43 |
|
44 |
def load_model_hf(model_config_path, repo_id, filename, device='cpu'):
|
|
|
3 |
import cv2
|
4 |
import requests
|
5 |
import os
|
|
|
6 |
from io import BytesIO
|
7 |
from PIL import Image
|
8 |
import numpy as np
|
|
|
16 |
# prepare the environment
|
17 |
os.system("python setup.py build develop --user")
|
18 |
os.system("pip install packaging==21.3")
|
19 |
+
os.system("pip install gradio")
|
20 |
|
21 |
|
22 |
warnings.filterwarnings("ignore")
|
23 |
|
24 |
import gradio as gr
|
25 |
+
|
26 |
+
from groundingdino.models import build_model
|
27 |
+
from groundingdino.util.slconfig import SLConfig
|
28 |
+
from groundingdino.util.utils import clean_state_dict
|
29 |
+
from groundingdino.util.inference import annotate, load_image, predict
|
30 |
+
import groundingdino.datasets.transforms as T
|
|
|
31 |
|
32 |
from huggingface_hub import hf_hub_download
|
33 |
|
34 |
|
35 |
|
36 |
# Use this command for evaluate the Grounding DINO model
|
37 |
+
config_file = "groundingdino/config/GroundingDINO_SwinT_OGC.py"
|
38 |
+
ckpt_repo_id = "ShilongLiu/GroundingDINO"
|
39 |
+
ckpt_filenmae = "groundingdino_swint_ogc.pth"
|
40 |
|
41 |
|
42 |
def load_model_hf(model_config_path, repo_id, filename, device='cpu'):
|
.ipynb_checkpoints/requirements-checkpoint.txt
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
cython
|
2 |
+
submitit
|
3 |
+
scipy
|
4 |
+
termcolor
|
5 |
+
addict
|
6 |
+
yapf==0.40.1
|
7 |
+
timm
|
8 |
+
torch
|
9 |
+
torchvision
|
10 |
+
transformers
|
11 |
+
numpy
|
12 |
+
opencv-python
|
13 |
+
supervision==0.6.0
|
14 |
+
pycocotools
|
15 |
+
pyyaml>3.10
|
16 |
+
colorlog
|
17 |
+
loralib
|
.ipynb_checkpoints/test-checkpoint.ipynb
ADDED
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "code",
|
5 |
+
"execution_count": 2,
|
6 |
+
"metadata": {},
|
7 |
+
"outputs": [
|
8 |
+
{
|
9 |
+
"name": "stdout",
|
10 |
+
"output_type": "stream",
|
11 |
+
"text": [
|
12 |
+
"final text_encoder_type: bert-base-uncased\n"
|
13 |
+
]
|
14 |
+
},
|
15 |
+
{
|
16 |
+
"data": {
|
17 |
+
"application/json": {
|
18 |
+
"ascii": false,
|
19 |
+
"bar_format": null,
|
20 |
+
"colour": null,
|
21 |
+
"elapsed": 0.014210224151611328,
|
22 |
+
"initial": 0,
|
23 |
+
"n": 0,
|
24 |
+
"ncols": null,
|
25 |
+
"nrows": null,
|
26 |
+
"postfix": null,
|
27 |
+
"prefix": "Downloading model.safetensors",
|
28 |
+
"rate": null,
|
29 |
+
"total": 440449768,
|
30 |
+
"unit": "B",
|
31 |
+
"unit_divisor": 1000,
|
32 |
+
"unit_scale": true
|
33 |
+
},
|
34 |
+
"application/vnd.jupyter.widget-view+json": {
|
35 |
+
"model_id": "5922f34578364d36afa13de9f01254bd",
|
36 |
+
"version_major": 2,
|
37 |
+
"version_minor": 0
|
38 |
+
},
|
39 |
+
"text/plain": [
|
40 |
+
"Downloading model.safetensors: 0%| | 0.00/440M [00:00<?, ?B/s]"
|
41 |
+
]
|
42 |
+
},
|
43 |
+
"metadata": {},
|
44 |
+
"output_type": "display_data"
|
45 |
+
},
|
46 |
+
{
|
47 |
+
"name": "stderr",
|
48 |
+
"output_type": "stream",
|
49 |
+
"text": [
|
50 |
+
"/root/miniconda3/lib/python3.8/site-packages/transformers/modeling_utils.py:881: FutureWarning: The `device` argument is deprecated and will be removed in v5 of Transformers.\n",
|
51 |
+
" warnings.warn(\n",
|
52 |
+
"/root/miniconda3/lib/python3.8/site-packages/torch/utils/checkpoint.py:31: UserWarning: None of the inputs have requires_grad=True. Gradients will be None\n",
|
53 |
+
" warnings.warn(\"None of the inputs have requires_grad=True. Gradients will be None\")\n"
|
54 |
+
]
|
55 |
+
},
|
56 |
+
{
|
57 |
+
"data": {
|
58 |
+
"text/plain": [
|
59 |
+
"True"
|
60 |
+
]
|
61 |
+
},
|
62 |
+
"execution_count": 2,
|
63 |
+
"metadata": {},
|
64 |
+
"output_type": "execute_result"
|
65 |
+
}
|
66 |
+
],
|
67 |
+
"source": [
|
68 |
+
"from groundingdino.util.inference import load_model, load_image, predict, annotate\n",
|
69 |
+
"import cv2\n",
|
70 |
+
"\n",
|
71 |
+
"model = load_model(\"groundingdino/config/GroundingDINO_SwinT_OGC.py\", \"../04-06-segment-anything/weights/groundingdino_swint_ogc.pth\")\n",
|
72 |
+
"IMAGE_PATH = \".asset/cat_dog.jpeg\"\n",
|
73 |
+
"TEXT_PROMPT = \"chair . person . dog .\"\n",
|
74 |
+
"BOX_TRESHOLD = 0.35\n",
|
75 |
+
"TEXT_TRESHOLD = 0.25\n",
|
76 |
+
"\n",
|
77 |
+
"image_source, image = load_image(IMAGE_PATH)\n",
|
78 |
+
"\n",
|
79 |
+
"boxes, logits, phrases = predict(\n",
|
80 |
+
" model=model,\n",
|
81 |
+
" image=image,\n",
|
82 |
+
" caption=TEXT_PROMPT,\n",
|
83 |
+
" box_threshold=BOX_TRESHOLD,\n",
|
84 |
+
" text_threshold=TEXT_TRESHOLD\n",
|
85 |
+
")\n",
|
86 |
+
"\n",
|
87 |
+
"annotated_frame = annotate(image_source=image_source, boxes=boxes, logits=logits, phrases=phrases)\n",
|
88 |
+
"cv2.imwrite(\"annotated_image.jpg\", annotated_frame)"
|
89 |
+
]
|
90 |
+
}
|
91 |
+
],
|
92 |
+
"metadata": {
|
93 |
+
"kernelspec": {
|
94 |
+
"display_name": "base",
|
95 |
+
"language": "python",
|
96 |
+
"name": "python3"
|
97 |
+
},
|
98 |
+
"language_info": {
|
99 |
+
"codemirror_mode": {
|
100 |
+
"name": "ipython",
|
101 |
+
"version": 3
|
102 |
+
},
|
103 |
+
"file_extension": ".py",
|
104 |
+
"mimetype": "text/x-python",
|
105 |
+
"name": "python",
|
106 |
+
"nbconvert_exporter": "python",
|
107 |
+
"pygments_lexer": "ipython3",
|
108 |
+
"version": "3.8.10"
|
109 |
+
}
|
110 |
+
},
|
111 |
+
"nbformat": 4,
|
112 |
+
"nbformat_minor": 2
|
113 |
+
}
|
LICENSE
ADDED
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Apache License
|
2 |
+
Version 2.0, January 2004
|
3 |
+
http://www.apache.org/licenses/
|
4 |
+
|
5 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
6 |
+
|
7 |
+
1. Definitions.
|
8 |
+
|
9 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
10 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
11 |
+
|
12 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
13 |
+
the copyright owner that is granting the License.
|
14 |
+
|
15 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
16 |
+
other entities that control, are controlled by, or are under common
|
17 |
+
control with that entity. For the purposes of this definition,
|
18 |
+
"control" means (i) the power, direct or indirect, to cause the
|
19 |
+
direction or management of such entity, whether by contract or
|
20 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
21 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
22 |
+
|
23 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
24 |
+
exercising permissions granted by this License.
|
25 |
+
|
26 |
+
"Source" form shall mean the preferred form for making modifications,
|
27 |
+
including but not limited to software source code, documentation
|
28 |
+
source, and configuration files.
|
29 |
+
|
30 |
+
"Object" form shall mean any form resulting from mechanical
|
31 |
+
transformation or translation of a Source form, including but
|
32 |
+
not limited to compiled object code, generated documentation,
|
33 |
+
and conversions to other media types.
|
34 |
+
|
35 |
+
"Work" shall mean the work of authorship, whether in Source or
|
36 |
+
Object form, made available under the License, as indicated by a
|
37 |
+
copyright notice that is included in or attached to the work
|
38 |
+
(an example is provided in the Appendix below).
|
39 |
+
|
40 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
41 |
+
form, that is based on (or derived from) the Work and for which the
|
42 |
+
editorial revisions, annotations, elaborations, or other modifications
|
43 |
+
represent, as a whole, an original work of authorship. For the purposes
|
44 |
+
of this License, Derivative Works shall not include works that remain
|
45 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
46 |
+
the Work and Derivative Works thereof.
|
47 |
+
|
48 |
+
"Contribution" shall mean any work of authorship, including
|
49 |
+
the original version of the Work and any modifications or additions
|
50 |
+
to that Work or Derivative Works thereof, that is intentionally
|
51 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
52 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
53 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
54 |
+
means any form of electronic, verbal, or written communication sent
|
55 |
+
to the Licensor or its representatives, including but not limited to
|
56 |
+
communication on electronic mailing lists, source code control systems,
|
57 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
58 |
+
Licensor for the purpose of discussing and improving the Work, but
|
59 |
+
excluding communication that is conspicuously marked or otherwise
|
60 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
61 |
+
|
62 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
63 |
+
on behalf of whom a Contribution has been received by Licensor and
|
64 |
+
subsequently incorporated within the Work.
|
65 |
+
|
66 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
67 |
+
this License, each Contributor hereby grants to You a perpetual,
|
68 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
69 |
+
copyright license to reproduce, prepare Derivative Works of,
|
70 |
+
publicly display, publicly perform, sublicense, and distribute the
|
71 |
+
Work and such Derivative Works in Source or Object form.
|
72 |
+
|
73 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
74 |
+
this License, each Contributor hereby grants to You a perpetual,
|
75 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
76 |
+
(except as stated in this section) patent license to make, have made,
|
77 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
78 |
+
where such license applies only to those patent claims licensable
|
79 |
+
by such Contributor that are necessarily infringed by their
|
80 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
81 |
+
with the Work to which such Contribution(s) was submitted. If You
|
82 |
+
institute patent litigation against any entity (including a
|
83 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
84 |
+
or a Contribution incorporated within the Work constitutes direct
|
85 |
+
or contributory patent infringement, then any patent licenses
|
86 |
+
granted to You under this License for that Work shall terminate
|
87 |
+
as of the date such litigation is filed.
|
88 |
+
|
89 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
90 |
+
Work or Derivative Works thereof in any medium, with or without
|
91 |
+
modifications, and in Source or Object form, provided that You
|
92 |
+
meet the following conditions:
|
93 |
+
|
94 |
+
(a) You must give any other recipients of the Work or
|
95 |
+
Derivative Works a copy of this License; and
|
96 |
+
|
97 |
+
(b) You must cause any modified files to carry prominent notices
|
98 |
+
stating that You changed the files; and
|
99 |
+
|
100 |
+
(c) You must retain, in the Source form of any Derivative Works
|
101 |
+
that You distribute, all copyright, patent, trademark, and
|
102 |
+
attribution notices from the Source form of the Work,
|
103 |
+
excluding those notices that do not pertain to any part of
|
104 |
+
the Derivative Works; and
|
105 |
+
|
106 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
107 |
+
distribution, then any Derivative Works that You distribute must
|
108 |
+
include a readable copy of the attribution notices contained
|
109 |
+
within such NOTICE file, excluding those notices that do not
|
110 |
+
pertain to any part of the Derivative Works, in at least one
|
111 |
+
of the following places: within a NOTICE text file distributed
|
112 |
+
as part of the Derivative Works; within the Source form or
|
113 |
+
documentation, if provided along with the Derivative Works; or,
|
114 |
+
within a display generated by the Derivative Works, if and
|
115 |
+
wherever such third-party notices normally appear. The contents
|
116 |
+
of the NOTICE file are for informational purposes only and
|
117 |
+
do not modify the License. You may add Your own attribution
|
118 |
+
notices within Derivative Works that You distribute, alongside
|
119 |
+
or as an addendum to the NOTICE text from the Work, provided
|
120 |
+
that such additional attribution notices cannot be construed
|
121 |
+
as modifying the License.
|
122 |
+
|
123 |
+
You may add Your own copyright statement to Your modifications and
|
124 |
+
may provide additional or different license terms and conditions
|
125 |
+
for use, reproduction, or distribution of Your modifications, or
|
126 |
+
for any such Derivative Works as a whole, provided Your use,
|
127 |
+
reproduction, and distribution of the Work otherwise complies with
|
128 |
+
the conditions stated in this License.
|
129 |
+
|
130 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
131 |
+
any Contribution intentionally submitted for inclusion in the Work
|
132 |
+
by You to the Licensor shall be under the terms and conditions of
|
133 |
+
this License, without any additional terms or conditions.
|
134 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
135 |
+
the terms of any separate license agreement you may have executed
|
136 |
+
with Licensor regarding such Contributions.
|
137 |
+
|
138 |
+
6. Trademarks. This License does not grant permission to use the trade
|
139 |
+
names, trademarks, service marks, or product names of the Licensor,
|
140 |
+
except as required for reasonable and customary use in describing the
|
141 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
142 |
+
|
143 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
144 |
+
agreed to in writing, Licensor provides the Work (and each
|
145 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
146 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
147 |
+
implied, including, without limitation, any warranties or conditions
|
148 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
149 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
150 |
+
appropriateness of using or redistributing the Work and assume any
|
151 |
+
risks associated with Your exercise of permissions under this License.
|
152 |
+
|
153 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
154 |
+
whether in tort (including negligence), contract, or otherwise,
|
155 |
+
unless required by applicable law (such as deliberate and grossly
|
156 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
157 |
+
liable to You for damages, including any direct, indirect, special,
|
158 |
+
incidental, or consequential damages of any character arising as a
|
159 |
+
result of this License or out of the use or inability to use the
|
160 |
+
Work (including but not limited to damages for loss of goodwill,
|
161 |
+
work stoppage, computer failure or malfunction, or any and all
|
162 |
+
other commercial damages or losses), even if such Contributor
|
163 |
+
has been advised of the possibility of such damages.
|
164 |
+
|
165 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
166 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
167 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
168 |
+
or other liability obligations and/or rights consistent with this
|
169 |
+
License. However, in accepting such obligations, You may act only
|
170 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
171 |
+
of any other Contributor, and only if You agree to indemnify,
|
172 |
+
defend, and hold each Contributor harmless for any liability
|
173 |
+
incurred by, or claims asserted against, such Contributor by reason
|
174 |
+
of your accepting any such warranty or additional liability.
|
175 |
+
|
176 |
+
END OF TERMS AND CONDITIONS
|
177 |
+
|
178 |
+
APPENDIX: How to apply the Apache License to your work.
|
179 |
+
|
180 |
+
To apply the Apache License to your work, attach the following
|
181 |
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
182 |
+
replaced with your own identifying information. (Don't include
|
183 |
+
the brackets!) The text should be enclosed in the appropriate
|
184 |
+
comment syntax for the file format. We also recommend that a
|
185 |
+
file or class name and description of purpose be included on the
|
186 |
+
same "printed page" as the copyright notice for easier
|
187 |
+
identification within third-party archives.
|
188 |
+
|
189 |
+
Copyright 2023 - present, IDEA Research.
|
190 |
+
|
191 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
192 |
+
you may not use this file except in compliance with the License.
|
193 |
+
You may obtain a copy of the License at
|
194 |
+
|
195 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
196 |
+
|
197 |
+
Unless required by applicable law or agreed to in writing, software
|
198 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
199 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
200 |
+
See the License for the specific language governing permissions and
|
201 |
+
limitations under the License.
|
README.md
DELETED
@@ -1,13 +0,0 @@
|
|
1 |
-
---
|
2 |
-
title: Peft GroundingDINO
|
3 |
-
emoji: 🐢
|
4 |
-
colorFrom: indigo
|
5 |
-
colorTo: purple
|
6 |
-
sdk: gradio
|
7 |
-
sdk_version: 4.36.1
|
8 |
-
app_file: app.py
|
9 |
-
pinned: false
|
10 |
-
license: mit
|
11 |
-
---
|
12 |
-
|
13 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app.py
CHANGED
@@ -3,7 +3,6 @@ from functools import partial
|
|
3 |
import cv2
|
4 |
import requests
|
5 |
import os
|
6 |
-
import sys
|
7 |
from io import BytesIO
|
8 |
from PIL import Image
|
9 |
import numpy as np
|
@@ -17,24 +16,25 @@ import torch
|
|
17 |
# prepare the environment
|
18 |
os.system("python setup.py build develop --user")
|
19 |
os.system("pip install packaging==21.3")
|
20 |
-
os.system("pip install gradio
|
21 |
|
22 |
|
23 |
warnings.filterwarnings("ignore")
|
24 |
|
25 |
import gradio as gr
|
26 |
-
|
27 |
-
from
|
28 |
-
from util.
|
29 |
-
from util.
|
30 |
-
|
|
|
31 |
|
32 |
from huggingface_hub import hf_hub_download
|
33 |
|
34 |
|
35 |
|
36 |
# Use this command for evaluate the Grounding DINO model
|
37 |
-
config_file = "
|
38 |
ckpt_repo_id = "Hasanmog/Peft-GroundingDINO"
|
39 |
ckpt_filenmae = "Best.pth"
|
40 |
|
|
|
3 |
import cv2
|
4 |
import requests
|
5 |
import os
|
|
|
6 |
from io import BytesIO
|
7 |
from PIL import Image
|
8 |
import numpy as np
|
|
|
16 |
# prepare the environment
|
17 |
os.system("python setup.py build develop --user")
|
18 |
os.system("pip install packaging==21.3")
|
19 |
+
os.system("pip install gradio")
|
20 |
|
21 |
|
22 |
warnings.filterwarnings("ignore")
|
23 |
|
24 |
import gradio as gr
|
25 |
+
|
26 |
+
from groundingdino.models import build_model
|
27 |
+
from groundingdino.util.slconfig import SLConfig
|
28 |
+
from groundingdino.util.utils import clean_state_dict
|
29 |
+
from groundingdino.util.inference import annotate, load_image, predict
|
30 |
+
import groundingdino.datasets.transforms as T
|
31 |
|
32 |
from huggingface_hub import hf_hub_download
|
33 |
|
34 |
|
35 |
|
36 |
# Use this command for evaluate the Grounding DINO model
|
37 |
+
config_file = "groundingdino/config/GroundingDINO_SwinB_OGC.py"
|
38 |
ckpt_repo_id = "Hasanmog/Peft-GroundingDINO"
|
39 |
ckpt_filenmae = "Best.pth"
|
40 |
|
datasets/.ipynb_checkpoints/__init__-checkpoint.py
DELETED
@@ -1,23 +0,0 @@
|
|
1 |
-
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
|
2 |
-
import torch.utils.data
|
3 |
-
import torchvision
|
4 |
-
from .coco import build as build_coco
|
5 |
-
|
6 |
-
|
7 |
-
def get_coco_api_from_dataset(dataset):
|
8 |
-
for _ in range(10):
|
9 |
-
# if isinstance(dataset, torchvision.datasets.CocoDetection):
|
10 |
-
# break
|
11 |
-
if isinstance(dataset, torch.utils.data.Subset):
|
12 |
-
dataset = dataset.dataset
|
13 |
-
if isinstance(dataset, torchvision.datasets.CocoDetection):
|
14 |
-
return dataset.coco
|
15 |
-
|
16 |
-
|
17 |
-
def build_dataset(image_set, args, datasetinfo):
|
18 |
-
if datasetinfo["dataset_mode"] == 'coco':
|
19 |
-
return build_coco(image_set, args, datasetinfo)
|
20 |
-
if datasetinfo["dataset_mode"] == 'odvg':
|
21 |
-
from .odvg import build_odvg
|
22 |
-
return build_odvg(image_set, args, datasetinfo)
|
23 |
-
raise ValueError(f'dataset {args.dataset_file} not supported')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/.ipynb_checkpoints/coco-checkpoint.py
DELETED
@@ -1,649 +0,0 @@
|
|
1 |
-
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
|
2 |
-
"""
|
3 |
-
COCO dataset which returns image_id for evaluation.
|
4 |
-
|
5 |
-
Mostly copy-paste from https://github.com/pytorch/vision/blob/13b35ff/references/detection/coco_utils.py
|
6 |
-
"""
|
7 |
-
if __name__=="__main__":
|
8 |
-
# for debug only
|
9 |
-
import os, sys
|
10 |
-
sys.path.append(os.path.dirname(sys.path[0]))
|
11 |
-
from torchvision.datasets.vision import VisionDataset
|
12 |
-
|
13 |
-
import json
|
14 |
-
from pathlib import Path
|
15 |
-
import random
|
16 |
-
import os
|
17 |
-
from typing import Any, Callable, List, Optional, Tuple
|
18 |
-
|
19 |
-
from PIL import Image
|
20 |
-
|
21 |
-
import torch
|
22 |
-
import torch.utils.data
|
23 |
-
import torchvision
|
24 |
-
from pycocotools import mask as coco_mask
|
25 |
-
|
26 |
-
from datasets.data_util import preparing_dataset
|
27 |
-
import datasets.transforms as T
|
28 |
-
from util.box_ops import box_cxcywh_to_xyxy, box_iou
|
29 |
-
|
30 |
-
__all__ = ['build']
|
31 |
-
|
32 |
-
|
33 |
-
class label2compat():
|
34 |
-
def __init__(self) -> None:
|
35 |
-
self.category_map_str = {"1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10, "11": 11, "13": 12, "14": 13, "15": 14, "16": 15, "17": 16, "18": 17, "19": 18, "20": 19, "21": 20, "22": 21, "23": 22, "24": 23, "25": 24, "27": 25, "28": 26, "31": 27, "32": 28, "33": 29, "34": 30, "35": 31, "36": 32, "37": 33, "38": 34, "39": 35, "40": 36, "41": 37, "42": 38, "43": 39, "44": 40, "46": 41, "47": 42, "48": 43, "49": 44, "50": 45, "51": 46, "52": 47, "53": 48, "54": 49, "55": 50, "56": 51, "57": 52, "58": 53, "59": 54, "60": 55, "61": 56, "62": 57, "63": 58, "64": 59, "65": 60, "67": 61, "70": 62, "72": 63, "73": 64, "74": 65, "75": 66, "76": 67, "77": 68, "78": 69, "79": 70, "80": 71, "81": 72, "82": 73, "84": 74, "85": 75, "86": 76, "87": 77, "88": 78, "89": 79, "90": 80}
|
36 |
-
self.category_map = {int(k):v for k,v in self.category_map_str.items()}
|
37 |
-
|
38 |
-
def __call__(self, target, img=None):
|
39 |
-
labels = target['labels']
|
40 |
-
res = torch.zeros(labels.shape, dtype=labels.dtype)
|
41 |
-
for idx, item in enumerate(labels):
|
42 |
-
res[idx] = self.category_map[item.item()] - 1
|
43 |
-
target['label_compat'] = res
|
44 |
-
if img is not None:
|
45 |
-
return target, img
|
46 |
-
else:
|
47 |
-
return target
|
48 |
-
|
49 |
-
|
50 |
-
class label_compat2onehot():
|
51 |
-
def __init__(self, num_class=80, num_output_objs=1):
|
52 |
-
self.num_class = num_class
|
53 |
-
self.num_output_objs = num_output_objs
|
54 |
-
if num_output_objs != 1:
|
55 |
-
raise DeprecationWarning("num_output_objs!=1, which is only used for comparison")
|
56 |
-
|
57 |
-
def __call__(self, target, img=None):
|
58 |
-
labels = target['label_compat']
|
59 |
-
place_dict = {k:0 for k in range(self.num_class)}
|
60 |
-
if self.num_output_objs == 1:
|
61 |
-
res = torch.zeros(self.num_class)
|
62 |
-
for i in labels:
|
63 |
-
itm = i.item()
|
64 |
-
res[itm] = 1.0
|
65 |
-
else:
|
66 |
-
# compat with baseline
|
67 |
-
res = torch.zeros(self.num_class, self.num_output_objs)
|
68 |
-
for i in labels:
|
69 |
-
itm = i.item()
|
70 |
-
res[itm][place_dict[itm]] = 1.0
|
71 |
-
place_dict[itm] += 1
|
72 |
-
target['label_compat_onehot'] = res
|
73 |
-
if img is not None:
|
74 |
-
return target, img
|
75 |
-
else:
|
76 |
-
return target
|
77 |
-
|
78 |
-
|
79 |
-
class box_label_catter():
|
80 |
-
def __init__(self):
|
81 |
-
pass
|
82 |
-
|
83 |
-
def __call__(self, target, img=None):
|
84 |
-
labels = target['label_compat']
|
85 |
-
boxes = target['boxes']
|
86 |
-
box_label = torch.cat((boxes, labels.unsqueeze(-1)), 1)
|
87 |
-
target['box_label'] = box_label
|
88 |
-
if img is not None:
|
89 |
-
return target, img
|
90 |
-
else:
|
91 |
-
return target
|
92 |
-
|
93 |
-
|
94 |
-
class RandomSelectBoxlabels():
|
95 |
-
def __init__(self, num_classes, leave_one_out=False, blank_prob=0.8,
|
96 |
-
prob_first_item = 0.0,
|
97 |
-
prob_random_item = 0.0,
|
98 |
-
prob_last_item = 0.8,
|
99 |
-
prob_stop_sign = 0.2
|
100 |
-
) -> None:
|
101 |
-
self.num_classes = num_classes
|
102 |
-
self.leave_one_out = leave_one_out
|
103 |
-
self.blank_prob = blank_prob
|
104 |
-
|
105 |
-
self.set_state(prob_first_item, prob_random_item, prob_last_item, prob_stop_sign)
|
106 |
-
|
107 |
-
|
108 |
-
def get_state(self):
|
109 |
-
return [self.prob_first_item, self.prob_random_item, self.prob_last_item, self.prob_stop_sign]
|
110 |
-
|
111 |
-
def set_state(self, prob_first_item, prob_random_item, prob_last_item, prob_stop_sign):
|
112 |
-
sum_prob = prob_first_item + prob_random_item + prob_last_item + prob_stop_sign
|
113 |
-
assert sum_prob - 1 < 1e-6, \
|
114 |
-
f"Sum up all prob = {sum_prob}. prob_first_item:{prob_first_item}" \
|
115 |
-
+ f"prob_random_item:{prob_random_item}, prob_last_item:{prob_last_item}" \
|
116 |
-
+ f"prob_stop_sign:{prob_stop_sign}"
|
117 |
-
|
118 |
-
self.prob_first_item = prob_first_item
|
119 |
-
self.prob_random_item = prob_random_item
|
120 |
-
self.prob_last_item = prob_last_item
|
121 |
-
self.prob_stop_sign = prob_stop_sign
|
122 |
-
|
123 |
-
|
124 |
-
def sample_for_pred_first_item(self, box_label: torch.FloatTensor):
|
125 |
-
box_label_known = torch.Tensor(0,5)
|
126 |
-
box_label_unknown = box_label
|
127 |
-
return box_label_known, box_label_unknown
|
128 |
-
|
129 |
-
def sample_for_pred_random_item(self, box_label: torch.FloatTensor):
|
130 |
-
n_select = int(random.random() * box_label.shape[0])
|
131 |
-
box_label = box_label[torch.randperm(box_label.shape[0])]
|
132 |
-
box_label_known = box_label[:n_select]
|
133 |
-
box_label_unknown = box_label[n_select:]
|
134 |
-
return box_label_known, box_label_unknown
|
135 |
-
|
136 |
-
def sample_for_pred_last_item(self, box_label: torch.FloatTensor):
|
137 |
-
box_label_perm = box_label[torch.randperm(box_label.shape[0])]
|
138 |
-
known_label_list = []
|
139 |
-
box_label_known = []
|
140 |
-
box_label_unknown = []
|
141 |
-
for item in box_label_perm:
|
142 |
-
label_i = item[4].item()
|
143 |
-
if label_i in known_label_list:
|
144 |
-
box_label_known.append(item)
|
145 |
-
else:
|
146 |
-
# first item
|
147 |
-
box_label_unknown.append(item)
|
148 |
-
known_label_list.append(label_i)
|
149 |
-
box_label_known = torch.stack(box_label_known) if len(box_label_known) > 0 else torch.Tensor(0,5)
|
150 |
-
box_label_unknown = torch.stack(box_label_unknown) if len(box_label_unknown) > 0 else torch.Tensor(0,5)
|
151 |
-
return box_label_known, box_label_unknown
|
152 |
-
|
153 |
-
def sample_for_pred_stop_sign(self, box_label: torch.FloatTensor):
|
154 |
-
box_label_unknown = torch.Tensor(0,5)
|
155 |
-
box_label_known = box_label
|
156 |
-
return box_label_known, box_label_unknown
|
157 |
-
|
158 |
-
def __call__(self, target, img=None):
|
159 |
-
box_label = target['box_label'] # K, 5
|
160 |
-
|
161 |
-
dice_number = random.random()
|
162 |
-
|
163 |
-
if dice_number < self.prob_first_item:
|
164 |
-
box_label_known, box_label_unknown = self.sample_for_pred_first_item(box_label)
|
165 |
-
elif dice_number < self.prob_first_item + self.prob_random_item:
|
166 |
-
box_label_known, box_label_unknown = self.sample_for_pred_random_item(box_label)
|
167 |
-
elif dice_number < self.prob_first_item + self.prob_random_item + self.prob_last_item:
|
168 |
-
box_label_known, box_label_unknown = self.sample_for_pred_last_item(box_label)
|
169 |
-
else:
|
170 |
-
box_label_known, box_label_unknown = self.sample_for_pred_stop_sign(box_label)
|
171 |
-
|
172 |
-
target['label_onehot_known'] = label2onehot(box_label_known[:,-1], self.num_classes)
|
173 |
-
target['label_onehot_unknown'] = label2onehot(box_label_unknown[:, -1], self.num_classes)
|
174 |
-
target['box_label_known'] = box_label_known
|
175 |
-
target['box_label_unknown'] = box_label_unknown
|
176 |
-
|
177 |
-
return target, img
|
178 |
-
|
179 |
-
|
180 |
-
class RandomDrop():
|
181 |
-
def __init__(self, p=0.2) -> None:
|
182 |
-
self.p = p
|
183 |
-
|
184 |
-
def __call__(self, target, img=None):
|
185 |
-
known_box = target['box_label_known']
|
186 |
-
num_known_box = known_box.size(0)
|
187 |
-
idxs = torch.rand(num_known_box)
|
188 |
-
# indices = torch.randperm(num_known_box)[:int((1-self).p*num_known_box + 0.5 + random.random())]
|
189 |
-
target['box_label_known'] = known_box[idxs > self.p]
|
190 |
-
return target, img
|
191 |
-
|
192 |
-
|
193 |
-
class BboxPertuber():
|
194 |
-
def __init__(self, max_ratio = 0.02, generate_samples = 1000) -> None:
|
195 |
-
self.max_ratio = max_ratio
|
196 |
-
self.generate_samples = generate_samples
|
197 |
-
self.samples = self.generate_pertube_samples()
|
198 |
-
self.idx = 0
|
199 |
-
|
200 |
-
def generate_pertube_samples(self):
|
201 |
-
import torch
|
202 |
-
samples = (torch.rand(self.generate_samples, 5) - 0.5) * 2 * self.max_ratio
|
203 |
-
return samples
|
204 |
-
|
205 |
-
def __call__(self, target, img):
|
206 |
-
known_box = target['box_label_known'] # Tensor(K,5), K known bbox
|
207 |
-
K = known_box.shape[0]
|
208 |
-
known_box_pertube = torch.zeros(K, 6) # 4:bbox, 1:prob, 1:label
|
209 |
-
if K == 0:
|
210 |
-
pass
|
211 |
-
else:
|
212 |
-
if self.idx + K > self.generate_samples:
|
213 |
-
self.idx = 0
|
214 |
-
delta = self.samples[self.idx: self.idx + K, :]
|
215 |
-
known_box_pertube[:, :4] = known_box[:, :4] + delta[:, :4]
|
216 |
-
iou = (torch.diag(box_iou(box_cxcywh_to_xyxy(known_box[:, :4]), box_cxcywh_to_xyxy(known_box_pertube[:, :4]))[0])) * (1 + delta[:, -1])
|
217 |
-
known_box_pertube[:, 4].copy_(iou)
|
218 |
-
known_box_pertube[:, -1].copy_(known_box[:, -1])
|
219 |
-
|
220 |
-
target['box_label_known_pertube'] = known_box_pertube
|
221 |
-
return target, img
|
222 |
-
|
223 |
-
|
224 |
-
class RandomCutout():
|
225 |
-
def __init__(self, factor=0.5) -> None:
|
226 |
-
self.factor = factor
|
227 |
-
|
228 |
-
def __call__(self, target, img=None):
|
229 |
-
unknown_box = target['box_label_unknown'] # Ku, 5
|
230 |
-
known_box = target['box_label_known_pertube'] # Kk, 6
|
231 |
-
Ku = unknown_box.size(0)
|
232 |
-
|
233 |
-
known_box_add = torch.zeros(Ku, 6) # Ku, 6
|
234 |
-
known_box_add[:, :5] = unknown_box
|
235 |
-
known_box_add[:, 5].uniform_(0.5, 1)
|
236 |
-
|
237 |
-
|
238 |
-
known_box_add[:, :2] += known_box_add[:, 2:4] * (torch.rand(Ku, 2) - 0.5) / 2
|
239 |
-
known_box_add[:, 2:4] /= 2
|
240 |
-
|
241 |
-
target['box_label_known_pertube'] = torch.cat((known_box, known_box_add))
|
242 |
-
return target, img
|
243 |
-
|
244 |
-
|
245 |
-
class RandomSelectBoxes():
|
246 |
-
def __init__(self, num_class=80) -> None:
|
247 |
-
Warning("This is such a slow function and will be deprecated soon!!!")
|
248 |
-
self.num_class = num_class
|
249 |
-
|
250 |
-
def __call__(self, target, img=None):
|
251 |
-
boxes = target['boxes']
|
252 |
-
labels = target['label_compat']
|
253 |
-
|
254 |
-
# transform to list of tensors
|
255 |
-
boxs_list = [[] for i in range(self.num_class)]
|
256 |
-
for idx, item in enumerate(boxes):
|
257 |
-
label = labels[idx].item()
|
258 |
-
boxs_list[label].append(item)
|
259 |
-
boxs_list_tensor = [torch.stack(i) if len(i) > 0 else torch.Tensor(0,4) for i in boxs_list]
|
260 |
-
|
261 |
-
# random selection
|
262 |
-
box_known = []
|
263 |
-
box_unknown = []
|
264 |
-
for idx, item in enumerate(boxs_list_tensor):
|
265 |
-
ncnt = item.shape[0]
|
266 |
-
nselect = int(random.random() * ncnt) # close in both sides, much faster than random.randint
|
267 |
-
|
268 |
-
item = item[torch.randperm(ncnt)]
|
269 |
-
# random.shuffle(item)
|
270 |
-
box_known.append(item[:nselect])
|
271 |
-
box_unknown.append(item[nselect:])
|
272 |
-
|
273 |
-
# box_known_tensor = [torch.stack(i) if len(i) > 0 else torch.Tensor(0,4) for i in box_known]
|
274 |
-
# box_unknown_tensor = [torch.stack(i) if len(i) > 0 else torch.Tensor(0,4) for i in box_unknown]
|
275 |
-
# print('box_unknown_tensor:', box_unknown_tensor)
|
276 |
-
target['known_box'] = box_known
|
277 |
-
target['unknown_box'] = box_unknown
|
278 |
-
return target, img
|
279 |
-
|
280 |
-
|
281 |
-
def label2onehot(label, num_classes):
|
282 |
-
"""
|
283 |
-
label: Tensor(K)
|
284 |
-
"""
|
285 |
-
res = torch.zeros(num_classes)
|
286 |
-
for i in label:
|
287 |
-
itm = int(i.item())
|
288 |
-
res[itm] = 1.0
|
289 |
-
return res
|
290 |
-
|
291 |
-
|
292 |
-
class MaskCrop():
|
293 |
-
def __init__(self) -> None:
|
294 |
-
pass
|
295 |
-
|
296 |
-
def __call__(self, target, img):
|
297 |
-
known_box = target['known_box']
|
298 |
-
h,w = img.shape[1:] # h,w
|
299 |
-
# imgsize = target['orig_size'] # h,w
|
300 |
-
|
301 |
-
scale = torch.Tensor([w, h, w, h])
|
302 |
-
|
303 |
-
# _cnt = 0
|
304 |
-
for boxes in known_box:
|
305 |
-
if boxes.shape[0] == 0:
|
306 |
-
continue
|
307 |
-
box_xyxy = box_cxcywh_to_xyxy(boxes) * scale
|
308 |
-
for box in box_xyxy:
|
309 |
-
x1, y1, x2, y2 = [int(i) for i in box.tolist()]
|
310 |
-
img[:, y1:y2, x1:x2] = 0
|
311 |
-
# _cnt += 1
|
312 |
-
# print("_cnt:", _cnt)
|
313 |
-
return target, img
|
314 |
-
|
315 |
-
|
316 |
-
dataset_hook_register = {
|
317 |
-
'label2compat': label2compat,
|
318 |
-
'label_compat2onehot': label_compat2onehot,
|
319 |
-
'box_label_catter': box_label_catter,
|
320 |
-
'RandomSelectBoxlabels': RandomSelectBoxlabels,
|
321 |
-
'RandomSelectBoxes': RandomSelectBoxes,
|
322 |
-
'MaskCrop': MaskCrop,
|
323 |
-
'BboxPertuber': BboxPertuber,
|
324 |
-
}
|
325 |
-
|
326 |
-
|
327 |
-
class CocoDetection(torchvision.datasets.CocoDetection):
|
328 |
-
def __init__(self, img_folder, ann_file, transforms, return_masks, aux_target_hacks=None):
|
329 |
-
super(CocoDetection, self).__init__(img_folder, ann_file)
|
330 |
-
self._transforms = transforms
|
331 |
-
self.prepare = ConvertCocoPolysToMask(return_masks)
|
332 |
-
self.aux_target_hacks = aux_target_hacks
|
333 |
-
|
334 |
-
def change_hack_attr(self, hackclassname, attrkv_dict):
|
335 |
-
target_class = dataset_hook_register[hackclassname]
|
336 |
-
for item in self.aux_target_hacks:
|
337 |
-
if isinstance(item, target_class):
|
338 |
-
for k,v in attrkv_dict.items():
|
339 |
-
setattr(item, k, v)
|
340 |
-
|
341 |
-
def get_hack(self, hackclassname):
|
342 |
-
target_class = dataset_hook_register[hackclassname]
|
343 |
-
for item in self.aux_target_hacks:
|
344 |
-
if isinstance(item, target_class):
|
345 |
-
return item
|
346 |
-
|
347 |
-
def _load_image(self, id: int) -> Image.Image:
|
348 |
-
path = self.coco.loadImgs(id)[0]["file_name"]
|
349 |
-
abs_path = os.path.join(self.root, path)
|
350 |
-
return Image.open(abs_path).convert("RGB")
|
351 |
-
|
352 |
-
def __getitem__(self, idx):
|
353 |
-
"""
|
354 |
-
Output:
|
355 |
-
- target: dict of multiple items
|
356 |
-
- boxes: Tensor[num_box, 4]. \
|
357 |
-
Init type: x0,y0,x1,y1. unnormalized data.
|
358 |
-
Final type: cx,cy,w,h. normalized data.
|
359 |
-
"""
|
360 |
-
try:
|
361 |
-
img, target = super(CocoDetection, self).__getitem__(idx)
|
362 |
-
except:
|
363 |
-
print("Error idx: {}".format(idx))
|
364 |
-
idx += 1
|
365 |
-
img, target = super(CocoDetection, self).__getitem__(idx)
|
366 |
-
image_id = self.ids[idx]
|
367 |
-
target = {'image_id': image_id, 'annotations': target}
|
368 |
-
img, target = self.prepare(img, target)
|
369 |
-
|
370 |
-
if self._transforms is not None:
|
371 |
-
img, target = self._transforms(img, target)
|
372 |
-
|
373 |
-
# convert to needed format
|
374 |
-
if self.aux_target_hacks is not None:
|
375 |
-
for hack_runner in self.aux_target_hacks:
|
376 |
-
target, img = hack_runner(target, img=img)
|
377 |
-
|
378 |
-
return img, target
|
379 |
-
|
380 |
-
|
381 |
-
def convert_coco_poly_to_mask(segmentations, height, width):
|
382 |
-
masks = []
|
383 |
-
for polygons in segmentations:
|
384 |
-
rles = coco_mask.frPyObjects(polygons, height, width)
|
385 |
-
mask = coco_mask.decode(rles)
|
386 |
-
if len(mask.shape) < 3:
|
387 |
-
mask = mask[..., None]
|
388 |
-
mask = torch.as_tensor(mask, dtype=torch.uint8)
|
389 |
-
mask = mask.any(dim=2)
|
390 |
-
masks.append(mask)
|
391 |
-
if masks:
|
392 |
-
masks = torch.stack(masks, dim=0)
|
393 |
-
else:
|
394 |
-
masks = torch.zeros((0, height, width), dtype=torch.uint8)
|
395 |
-
return masks
|
396 |
-
|
397 |
-
|
398 |
-
class ConvertCocoPolysToMask(object):
|
399 |
-
def __init__(self, return_masks=False):
|
400 |
-
self.return_masks = return_masks
|
401 |
-
|
402 |
-
def __call__(self, image, target):
|
403 |
-
w, h = image.size
|
404 |
-
|
405 |
-
image_id = target["image_id"]
|
406 |
-
image_id = torch.tensor([image_id])
|
407 |
-
|
408 |
-
anno = target["annotations"]
|
409 |
-
|
410 |
-
anno = [obj for obj in anno if 'iscrowd' not in obj or obj['iscrowd'] == 0]
|
411 |
-
|
412 |
-
boxes = [obj["bbox"] for obj in anno]
|
413 |
-
# guard against no boxes via resizing
|
414 |
-
boxes = torch.as_tensor(boxes, dtype=torch.float32).reshape(-1, 4)
|
415 |
-
boxes[:, 2:] += boxes[:, :2]
|
416 |
-
boxes[:, 0::2].clamp_(min=0, max=w)
|
417 |
-
boxes[:, 1::2].clamp_(min=0, max=h)
|
418 |
-
|
419 |
-
classes = [obj["category_id"] for obj in anno]
|
420 |
-
classes = torch.tensor(classes, dtype=torch.int64)
|
421 |
-
|
422 |
-
if self.return_masks:
|
423 |
-
segmentations = [obj["segmentation"] for obj in anno]
|
424 |
-
masks = convert_coco_poly_to_mask(segmentations, h, w)
|
425 |
-
|
426 |
-
keypoints = None
|
427 |
-
if anno and "keypoints" in anno[0]:
|
428 |
-
keypoints = [obj["keypoints"] for obj in anno]
|
429 |
-
keypoints = torch.as_tensor(keypoints, dtype=torch.float32)
|
430 |
-
num_keypoints = keypoints.shape[0]
|
431 |
-
if num_keypoints:
|
432 |
-
keypoints = keypoints.view(num_keypoints, -1, 3)
|
433 |
-
|
434 |
-
keep = (boxes[:, 3] > boxes[:, 1]) & (boxes[:, 2] > boxes[:, 0])
|
435 |
-
boxes = boxes[keep]
|
436 |
-
classes = classes[keep]
|
437 |
-
if self.return_masks:
|
438 |
-
masks = masks[keep]
|
439 |
-
if keypoints is not None:
|
440 |
-
keypoints = keypoints[keep]
|
441 |
-
|
442 |
-
target = {}
|
443 |
-
target["boxes"] = boxes
|
444 |
-
target["labels"] = classes
|
445 |
-
if self.return_masks:
|
446 |
-
target["masks"] = masks
|
447 |
-
target["image_id"] = image_id
|
448 |
-
if keypoints is not None:
|
449 |
-
target["keypoints"] = keypoints
|
450 |
-
|
451 |
-
# for conversion to coco api
|
452 |
-
area = torch.tensor([obj["area"] for obj in anno])
|
453 |
-
iscrowd = torch.tensor([obj["iscrowd"] if "iscrowd" in obj else 0 for obj in anno])
|
454 |
-
target["area"] = area[keep]
|
455 |
-
target["iscrowd"] = iscrowd[keep]
|
456 |
-
|
457 |
-
target["orig_size"] = torch.as_tensor([int(h), int(w)])
|
458 |
-
target["size"] = torch.as_tensor([int(h), int(w)])
|
459 |
-
|
460 |
-
return image, target
|
461 |
-
|
462 |
-
|
463 |
-
def make_coco_transforms(image_set, fix_size=False, strong_aug=False, args=None):
|
464 |
-
|
465 |
-
normalize = T.Compose([
|
466 |
-
T.ToTensor(),
|
467 |
-
T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
|
468 |
-
])
|
469 |
-
|
470 |
-
# config the params for data aug
|
471 |
-
scales = [480, 512, 544, 576, 608, 640, 672, 704, 736, 768, 800]
|
472 |
-
max_size = 1333
|
473 |
-
scales2_resize = [400, 500, 600]
|
474 |
-
scales2_crop = [384, 600]
|
475 |
-
|
476 |
-
# update args from config files
|
477 |
-
scales = getattr(args, 'data_aug_scales', scales)
|
478 |
-
max_size = getattr(args, 'data_aug_max_size', max_size)
|
479 |
-
scales2_resize = getattr(args, 'data_aug_scales2_resize', scales2_resize)
|
480 |
-
scales2_crop = getattr(args, 'data_aug_scales2_crop', scales2_crop)
|
481 |
-
|
482 |
-
# resize them
|
483 |
-
data_aug_scale_overlap = getattr(args, 'data_aug_scale_overlap', None)
|
484 |
-
if data_aug_scale_overlap is not None and data_aug_scale_overlap > 0:
|
485 |
-
data_aug_scale_overlap = float(data_aug_scale_overlap)
|
486 |
-
scales = [int(i*data_aug_scale_overlap) for i in scales]
|
487 |
-
max_size = int(max_size*data_aug_scale_overlap)
|
488 |
-
scales2_resize = [int(i*data_aug_scale_overlap) for i in scales2_resize]
|
489 |
-
scales2_crop = [int(i*data_aug_scale_overlap) for i in scales2_crop]
|
490 |
-
|
491 |
-
datadict_for_print = {
|
492 |
-
'scales': scales,
|
493 |
-
'max_size': max_size,
|
494 |
-
'scales2_resize': scales2_resize,
|
495 |
-
'scales2_crop': scales2_crop
|
496 |
-
}
|
497 |
-
# print("data_aug_params:", json.dumps(datadict_for_print, indent=2))
|
498 |
-
|
499 |
-
if image_set == 'train':
|
500 |
-
if fix_size:
|
501 |
-
return T.Compose([
|
502 |
-
T.RandomHorizontalFlip(),
|
503 |
-
T.RandomResize([(max_size, max(scales))]),
|
504 |
-
# T.RandomResize([(512, 512)]),
|
505 |
-
normalize,
|
506 |
-
])
|
507 |
-
|
508 |
-
if strong_aug:
|
509 |
-
import datasets.sltransform as SLT
|
510 |
-
|
511 |
-
return T.Compose([
|
512 |
-
T.RandomHorizontalFlip(),
|
513 |
-
T.RandomSelect(
|
514 |
-
T.RandomResize(scales, max_size=max_size),
|
515 |
-
T.Compose([
|
516 |
-
T.RandomResize(scales2_resize),
|
517 |
-
T.RandomSizeCrop(*scales2_crop),
|
518 |
-
T.RandomResize(scales, max_size=max_size),
|
519 |
-
])
|
520 |
-
),
|
521 |
-
SLT.RandomSelectMulti([
|
522 |
-
SLT.RandomCrop(),
|
523 |
-
SLT.LightingNoise(),
|
524 |
-
SLT.AdjustBrightness(2),
|
525 |
-
SLT.AdjustContrast(2),
|
526 |
-
]),
|
527 |
-
normalize,
|
528 |
-
])
|
529 |
-
|
530 |
-
return T.Compose([
|
531 |
-
T.RandomHorizontalFlip(),
|
532 |
-
T.RandomSelect(
|
533 |
-
T.RandomResize(scales, max_size=max_size),
|
534 |
-
T.Compose([
|
535 |
-
T.RandomResize(scales2_resize),
|
536 |
-
T.RandomSizeCrop(*scales2_crop),
|
537 |
-
T.RandomResize(scales, max_size=max_size),
|
538 |
-
])
|
539 |
-
),
|
540 |
-
normalize,
|
541 |
-
])
|
542 |
-
|
543 |
-
if image_set in ['val', 'eval_debug', 'train_reg', 'test']:
|
544 |
-
|
545 |
-
if os.environ.get("GFLOPS_DEBUG_SHILONG", False) == 'INFO':
|
546 |
-
print("Under debug mode for flops calculation only!!!!!!!!!!!!!!!!")
|
547 |
-
return T.Compose([
|
548 |
-
T.ResizeDebug((1280, 800)),
|
549 |
-
normalize,
|
550 |
-
])
|
551 |
-
|
552 |
-
return T.Compose([
|
553 |
-
T.RandomResize([max(scales)], max_size=max_size),
|
554 |
-
normalize,
|
555 |
-
])
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
raise ValueError(f'unknown {image_set}')
|
560 |
-
|
561 |
-
|
562 |
-
def get_aux_target_hacks_list(image_set, args):
|
563 |
-
if args.modelname in ['q2bs_mask', 'q2bs']:
|
564 |
-
aux_target_hacks_list = [
|
565 |
-
label2compat(),
|
566 |
-
label_compat2onehot(),
|
567 |
-
RandomSelectBoxes(num_class=args.num_classes)
|
568 |
-
]
|
569 |
-
if args.masked_data and image_set == 'train':
|
570 |
-
# aux_target_hacks_list.append()
|
571 |
-
aux_target_hacks_list.append(MaskCrop())
|
572 |
-
elif args.modelname in ['q2bm_v2', 'q2bs_ce', 'q2op', 'q2ofocal', 'q2opclip', 'q2ocqonly']:
|
573 |
-
aux_target_hacks_list = [
|
574 |
-
label2compat(),
|
575 |
-
label_compat2onehot(),
|
576 |
-
box_label_catter(),
|
577 |
-
RandomSelectBoxlabels(num_classes=args.num_classes,
|
578 |
-
prob_first_item=args.prob_first_item,
|
579 |
-
prob_random_item=args.prob_random_item,
|
580 |
-
prob_last_item=args.prob_last_item,
|
581 |
-
prob_stop_sign=args.prob_stop_sign,
|
582 |
-
),
|
583 |
-
BboxPertuber(max_ratio=0.02, generate_samples=1000),
|
584 |
-
]
|
585 |
-
elif args.modelname in ['q2omask', 'q2osa']:
|
586 |
-
if args.coco_aug:
|
587 |
-
aux_target_hacks_list = [
|
588 |
-
label2compat(),
|
589 |
-
label_compat2onehot(),
|
590 |
-
box_label_catter(),
|
591 |
-
RandomSelectBoxlabels(num_classes=args.num_classes,
|
592 |
-
prob_first_item=args.prob_first_item,
|
593 |
-
prob_random_item=args.prob_random_item,
|
594 |
-
prob_last_item=args.prob_last_item,
|
595 |
-
prob_stop_sign=args.prob_stop_sign,
|
596 |
-
),
|
597 |
-
RandomDrop(p=0.2),
|
598 |
-
BboxPertuber(max_ratio=0.02, generate_samples=1000),
|
599 |
-
RandomCutout(factor=0.5)
|
600 |
-
]
|
601 |
-
else:
|
602 |
-
aux_target_hacks_list = [
|
603 |
-
label2compat(),
|
604 |
-
label_compat2onehot(),
|
605 |
-
box_label_catter(),
|
606 |
-
RandomSelectBoxlabels(num_classes=args.num_classes,
|
607 |
-
prob_first_item=args.prob_first_item,
|
608 |
-
prob_random_item=args.prob_random_item,
|
609 |
-
prob_last_item=args.prob_last_item,
|
610 |
-
prob_stop_sign=args.prob_stop_sign,
|
611 |
-
),
|
612 |
-
BboxPertuber(max_ratio=0.02, generate_samples=1000),
|
613 |
-
]
|
614 |
-
else:
|
615 |
-
aux_target_hacks_list = None
|
616 |
-
|
617 |
-
return aux_target_hacks_list
|
618 |
-
|
619 |
-
|
620 |
-
def build(image_set, args, datasetinfo):
|
621 |
-
img_folder = datasetinfo["root"]
|
622 |
-
ann_file = datasetinfo["anno"]
|
623 |
-
|
624 |
-
# copy to local path
|
625 |
-
if os.environ.get('DATA_COPY_SHILONG') == 'INFO':
|
626 |
-
preparing_dataset(dict(img_folder=img_folder, ann_file=ann_file), image_set, args)
|
627 |
-
|
628 |
-
try:
|
629 |
-
strong_aug = args.strong_aug
|
630 |
-
except:
|
631 |
-
strong_aug = False
|
632 |
-
print(img_folder, ann_file)
|
633 |
-
dataset = CocoDetection(img_folder, ann_file,
|
634 |
-
transforms=make_coco_transforms(image_set, fix_size=args.fix_size, strong_aug=strong_aug, args=args),
|
635 |
-
return_masks=args.masks,
|
636 |
-
aux_target_hacks=None,
|
637 |
-
)
|
638 |
-
return dataset
|
639 |
-
|
640 |
-
|
641 |
-
if __name__ == "__main__":
|
642 |
-
# Objects365 Val example
|
643 |
-
dataset_o365 = CocoDetection(
|
644 |
-
'/path/Objects365/train/',
|
645 |
-
"/path/Objects365/slannos/anno_preprocess_train_v2.json",
|
646 |
-
transforms=None,
|
647 |
-
return_masks=False,
|
648 |
-
)
|
649 |
-
print('len(dataset_o365):', len(dataset_o365))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/.ipynb_checkpoints/dataset-checkpoint.py
DELETED
@@ -1,44 +0,0 @@
|
|
1 |
-
from __future__ import print_function
|
2 |
-
|
3 |
-
import torch
|
4 |
-
import torchvision.datasets as datasets
|
5 |
-
from torch.utils.data import Dataset
|
6 |
-
from PIL import Image
|
7 |
-
from .tsv_io import TSVFile
|
8 |
-
import numpy as np
|
9 |
-
import base64
|
10 |
-
import io
|
11 |
-
|
12 |
-
|
13 |
-
class TSVDataset(Dataset):
|
14 |
-
""" TSV dataset for ImageNet 1K training
|
15 |
-
"""
|
16 |
-
def __init__(self, tsv_file, transform=None, target_transform=None):
|
17 |
-
self.tsv = TSVFile(tsv_file)
|
18 |
-
self.transform = transform
|
19 |
-
self.target_transform = target_transform
|
20 |
-
|
21 |
-
def __getitem__(self, index):
|
22 |
-
"""
|
23 |
-
Args:
|
24 |
-
index (int): Index
|
25 |
-
Returns:
|
26 |
-
tuple: (image, target) where target is class_index of the target class.
|
27 |
-
"""
|
28 |
-
row = self.tsv.seek(index)
|
29 |
-
image_data = base64.b64decode(row[-1])
|
30 |
-
image = Image.open(io.BytesIO(image_data))
|
31 |
-
image = image.convert('RGB')
|
32 |
-
target = int(row[1])
|
33 |
-
|
34 |
-
if self.transform is not None:
|
35 |
-
img = self.transform(image)
|
36 |
-
else:
|
37 |
-
img = image
|
38 |
-
if self.target_transform is not None:
|
39 |
-
target = self.target_transform(target)
|
40 |
-
|
41 |
-
return img, target
|
42 |
-
|
43 |
-
def __len__(self):
|
44 |
-
return self.tsv.num_rows()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/.ipynb_checkpoints/odvg-checkpoint.py
DELETED
@@ -1,258 +0,0 @@
|
|
1 |
-
from torchvision.datasets.vision import VisionDataset
|
2 |
-
import os.path
|
3 |
-
from typing import Callable, Optional
|
4 |
-
import json
|
5 |
-
from PIL import Image
|
6 |
-
import torch
|
7 |
-
import random
|
8 |
-
import os, sys
|
9 |
-
sys.path.append(os.path.dirname(sys.path[0]))
|
10 |
-
|
11 |
-
import datasets.transforms as T
|
12 |
-
|
13 |
-
class ODVGDataset(VisionDataset):
|
14 |
-
"""
|
15 |
-
Args:
|
16 |
-
root (string): Root directory where images are downloaded to.
|
17 |
-
anno (string): Path to json annotation file.
|
18 |
-
label_map_anno (string): Path to json label mapping file. Only for Object Detection
|
19 |
-
transform (callable, optional): A function/transform that takes in an PIL image
|
20 |
-
and returns a transformed version. E.g, ``transforms.PILToTensor``
|
21 |
-
target_transform (callable, optional): A function/transform that takes in the
|
22 |
-
target and transforms it.
|
23 |
-
transforms (callable, optional): A function/transform that takes input sample and its target as entry
|
24 |
-
and returns a transformed version.
|
25 |
-
"""
|
26 |
-
|
27 |
-
def __init__(
|
28 |
-
self,
|
29 |
-
root: str,
|
30 |
-
anno: str,
|
31 |
-
label_map_anno: str = None,
|
32 |
-
max_labels: int = 80,
|
33 |
-
transform: Optional[Callable] = None,
|
34 |
-
target_transform: Optional[Callable] = None,
|
35 |
-
transforms: Optional[Callable] = None,
|
36 |
-
) -> None:
|
37 |
-
super().__init__(root, transforms, transform, target_transform)
|
38 |
-
self.root = root
|
39 |
-
self.dataset_mode = "OD" if label_map_anno else "VG"
|
40 |
-
self.max_labels = max_labels
|
41 |
-
if self.dataset_mode == "OD":
|
42 |
-
self.load_label_map(label_map_anno)
|
43 |
-
self._load_metas(anno)
|
44 |
-
self.get_dataset_info()
|
45 |
-
|
46 |
-
def load_label_map(self, label_map_anno):
|
47 |
-
with open(label_map_anno, 'r') as file:
|
48 |
-
self.label_map = json.load(file)
|
49 |
-
self.label_index = set(self.label_map.keys())
|
50 |
-
|
51 |
-
def _load_metas(self, anno):
|
52 |
-
with open(anno, 'r') as f:
|
53 |
-
self.metas = json.load(f)
|
54 |
-
|
55 |
-
|
56 |
-
def get_dataset_info(self):
|
57 |
-
print(f" == total images: {len(self)}")
|
58 |
-
if self.dataset_mode == "OD":
|
59 |
-
print(f" == total labels: {len(self.label_map)}")
|
60 |
-
|
61 |
-
def __getitem__(self, index: int):
|
62 |
-
meta = self.metas[index]
|
63 |
-
rel_path = meta["filename"]
|
64 |
-
abs_path = os.path.join(self.root, rel_path)
|
65 |
-
if not os.path.exists(abs_path):
|
66 |
-
raise FileNotFoundError(f"{abs_path} not found.")
|
67 |
-
image = Image.open(abs_path).convert('RGB')
|
68 |
-
w, h = image.size
|
69 |
-
if self.dataset_mode == "OD":
|
70 |
-
anno = meta["detection"]
|
71 |
-
instances = [obj for obj in anno["instances"]]
|
72 |
-
boxes = [obj["bbox"] for obj in instances]
|
73 |
-
# generate vg_labels
|
74 |
-
# pos bbox labels
|
75 |
-
ori_classes = [str(obj["label"]) for obj in instances]
|
76 |
-
pos_labels = set(ori_classes)
|
77 |
-
# neg bbox labels
|
78 |
-
neg_labels = self.label_index.difference(pos_labels)
|
79 |
-
|
80 |
-
vg_labels = list(pos_labels)
|
81 |
-
num_to_add = min(len(neg_labels), self.max_labels-len(pos_labels))
|
82 |
-
if num_to_add > 0:
|
83 |
-
vg_labels.extend(random.sample(neg_labels, num_to_add))
|
84 |
-
|
85 |
-
# shuffle
|
86 |
-
for i in range(len(vg_labels)-1, 0, -1):
|
87 |
-
j = random.randint(0, i)
|
88 |
-
vg_labels[i], vg_labels[j] = vg_labels[j], vg_labels[i]
|
89 |
-
|
90 |
-
caption_list = [self.label_map[lb] for lb in vg_labels]
|
91 |
-
caption_dict = {item:index for index, item in enumerate(caption_list)}
|
92 |
-
|
93 |
-
caption = ' . '.join(caption_list) + ' .'
|
94 |
-
classes = [caption_dict[self.label_map[str(obj["label"])]] for obj in instances]
|
95 |
-
boxes = torch.as_tensor(boxes, dtype=torch.float32).reshape(-1, 4)
|
96 |
-
classes = torch.tensor(classes, dtype=torch.int64)
|
97 |
-
elif self.dataset_mode == "VG":
|
98 |
-
anno = meta["Grounding"]
|
99 |
-
instances = [obj for obj in anno["regions"]]
|
100 |
-
boxes = [obj["bbox"] for obj in instances]
|
101 |
-
caption_list = [obj["phrase"] for obj in instances]
|
102 |
-
c = list(zip(boxes, caption_list))
|
103 |
-
random.shuffle(c)
|
104 |
-
boxes[:], caption_list[:] = zip(*c)
|
105 |
-
uni_caption_list = list(set(caption_list))
|
106 |
-
label_map = {}
|
107 |
-
for idx in range(len(uni_caption_list)):
|
108 |
-
label_map[uni_caption_list[idx]] = idx
|
109 |
-
classes = [label_map[cap] for cap in caption_list]
|
110 |
-
caption = ' . '.join(uni_caption_list) + ' .'
|
111 |
-
boxes = torch.as_tensor(boxes, dtype=torch.float32).reshape(-1, 4)
|
112 |
-
classes = torch.tensor(classes, dtype=torch.int64)
|
113 |
-
caption_list = uni_caption_list
|
114 |
-
# print("caption_list" , caption_list)
|
115 |
-
# print("caption" , caption)
|
116 |
-
# print("boxes" , boxes)
|
117 |
-
target = {}
|
118 |
-
target["image_id"] = rel_path.strip(".jpg")
|
119 |
-
target["size"] = torch.as_tensor([int(h), int(w)])
|
120 |
-
target["cap_list"] = caption_list
|
121 |
-
target["caption"] = caption
|
122 |
-
target["boxes"] = boxes
|
123 |
-
target["labels"] = classes
|
124 |
-
# print(" image_id " , target["image_id"])
|
125 |
-
# size, cap_list, caption, bboxes, labels
|
126 |
-
|
127 |
-
if self.transforms is not None:
|
128 |
-
image, target = self.transforms(image, target)
|
129 |
-
|
130 |
-
return image, target
|
131 |
-
|
132 |
-
|
133 |
-
def __len__(self) -> int:
|
134 |
-
return len(self.metas)
|
135 |
-
|
136 |
-
|
137 |
-
def make_coco_transforms(image_set, fix_size=False, strong_aug=False, args=None):
|
138 |
-
|
139 |
-
normalize = T.Compose([
|
140 |
-
T.ToTensor(),
|
141 |
-
T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
|
142 |
-
])
|
143 |
-
|
144 |
-
# config the params for data aug
|
145 |
-
scales = [480, 512, 544, 576, 608, 640, 672, 704, 736, 768, 800]
|
146 |
-
max_size = 1333
|
147 |
-
scales2_resize = [400, 500, 600]
|
148 |
-
scales2_crop = [384, 600]
|
149 |
-
|
150 |
-
# update args from config files
|
151 |
-
scales = getattr(args, 'data_aug_scales', scales)
|
152 |
-
max_size = getattr(args, 'data_aug_max_size', max_size)
|
153 |
-
scales2_resize = getattr(args, 'data_aug_scales2_resize', scales2_resize)
|
154 |
-
scales2_crop = getattr(args, 'data_aug_scales2_crop', scales2_crop)
|
155 |
-
|
156 |
-
# resize them
|
157 |
-
data_aug_scale_overlap = getattr(args, 'data_aug_scale_overlap', None)
|
158 |
-
if data_aug_scale_overlap is not None and data_aug_scale_overlap > 0:
|
159 |
-
data_aug_scale_overlap = float(data_aug_scale_overlap)
|
160 |
-
scales = [int(i*data_aug_scale_overlap) for i in scales]
|
161 |
-
max_size = int(max_size*data_aug_scale_overlap)
|
162 |
-
scales2_resize = [int(i*data_aug_scale_overlap) for i in scales2_resize]
|
163 |
-
scales2_crop = [int(i*data_aug_scale_overlap) for i in scales2_crop]
|
164 |
-
|
165 |
-
# datadict_for_print = {
|
166 |
-
# 'scales': scales,
|
167 |
-
# 'max_size': max_size,
|
168 |
-
# 'scales2_resize': scales2_resize,
|
169 |
-
# 'scales2_crop': scales2_crop
|
170 |
-
# }
|
171 |
-
# print("data_aug_params:", json.dumps(datadict_for_print, indent=2))
|
172 |
-
|
173 |
-
if image_set == 'train':
|
174 |
-
if fix_size:
|
175 |
-
return T.Compose([
|
176 |
-
T.RandomHorizontalFlip(),
|
177 |
-
T.RandomResize([(max_size, max(scales))]),
|
178 |
-
normalize,
|
179 |
-
])
|
180 |
-
|
181 |
-
if strong_aug:
|
182 |
-
import datasets.sltransform as SLT
|
183 |
-
|
184 |
-
return T.Compose([
|
185 |
-
T.RandomHorizontalFlip(),
|
186 |
-
T.RandomSelect(
|
187 |
-
T.RandomResize(scales, max_size=max_size),
|
188 |
-
T.Compose([
|
189 |
-
T.RandomResize(scales2_resize),
|
190 |
-
T.RandomSizeCrop(*scales2_crop),
|
191 |
-
T.RandomResize(scales, max_size=max_size),
|
192 |
-
])
|
193 |
-
),
|
194 |
-
SLT.RandomSelectMulti([
|
195 |
-
SLT.RandomCrop(),
|
196 |
-
SLT.LightingNoise(),
|
197 |
-
SLT.AdjustBrightness(2),
|
198 |
-
SLT.AdjustContrast(2),
|
199 |
-
]),
|
200 |
-
normalize,
|
201 |
-
])
|
202 |
-
|
203 |
-
return T.Compose([
|
204 |
-
T.RandomHorizontalFlip(),
|
205 |
-
T.RandomSelect(
|
206 |
-
T.RandomResize(scales, max_size=max_size),
|
207 |
-
T.Compose([
|
208 |
-
T.RandomResize(scales2_resize),
|
209 |
-
T.RandomSizeCrop(*scales2_crop),
|
210 |
-
T.RandomResize(scales, max_size=max_size),
|
211 |
-
])
|
212 |
-
),
|
213 |
-
normalize,
|
214 |
-
])
|
215 |
-
|
216 |
-
if image_set in ['val', 'eval_debug', 'train_reg', 'test']:
|
217 |
-
|
218 |
-
if os.environ.get("GFLOPS_DEBUG_SHILONG", False) == 'INFO':
|
219 |
-
print("Under debug mode for flops calculation only!!!!!!!!!!!!!!!!")
|
220 |
-
return T.Compose([
|
221 |
-
T.ResizeDebug((1280, 800)),
|
222 |
-
normalize,
|
223 |
-
])
|
224 |
-
|
225 |
-
return T.Compose([
|
226 |
-
T.RandomResize([max(scales)], max_size=max_size),
|
227 |
-
normalize,
|
228 |
-
])
|
229 |
-
|
230 |
-
raise ValueError(f'unknown {image_set}')
|
231 |
-
|
232 |
-
def build_odvg(image_set, args, datasetinfo):
|
233 |
-
img_folder = datasetinfo["root"]
|
234 |
-
ann_file = datasetinfo["anno"]
|
235 |
-
label_map = datasetinfo["label_map"] if "label_map" in datasetinfo else None
|
236 |
-
try:
|
237 |
-
strong_aug = args.strong_aug
|
238 |
-
except:
|
239 |
-
strong_aug = False # False originally
|
240 |
-
print(img_folder, ann_file, label_map)
|
241 |
-
dataset = ODVGDataset(img_folder, ann_file, label_map, max_labels=args.max_labels,
|
242 |
-
transforms=make_coco_transforms(image_set, fix_size=args.fix_size, strong_aug=strong_aug, args=args),
|
243 |
-
)
|
244 |
-
return dataset
|
245 |
-
|
246 |
-
|
247 |
-
if __name__=="__main__":
|
248 |
-
dataset_vg = ODVGDataset("path/GRIT-20M/data/","path/GRIT-20M/anno/grit_odvg_10k.jsonl",)
|
249 |
-
print(len(dataset_vg))
|
250 |
-
data = dataset_vg[random.randint(0, 100)]
|
251 |
-
print(data)
|
252 |
-
dataset_od = ODVGDataset("pathl/V3Det/",
|
253 |
-
"path/V3Det/annotations/v3det_2023_v1_all_odvg.jsonl",
|
254 |
-
"path/V3Det/annotations/v3det_label_map.json",
|
255 |
-
)
|
256 |
-
print(len(dataset_od))
|
257 |
-
data = dataset_od[random.randint(0, 100)]
|
258 |
-
print(data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/.ipynb_checkpoints/transforms-checkpoint.py
DELETED
@@ -1,285 +0,0 @@
|
|
1 |
-
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
|
2 |
-
"""
|
3 |
-
Transforms and data augmentation for both image + bbox.
|
4 |
-
"""
|
5 |
-
import random
|
6 |
-
|
7 |
-
import PIL
|
8 |
-
import torch
|
9 |
-
import torchvision.transforms as T
|
10 |
-
import torchvision.transforms.functional as F
|
11 |
-
|
12 |
-
from util.box_ops import box_xyxy_to_cxcywh
|
13 |
-
from util.misc import interpolate
|
14 |
-
|
15 |
-
|
16 |
-
def crop(image, target, region):
|
17 |
-
cropped_image = F.crop(image, *region)
|
18 |
-
|
19 |
-
target = target.copy()
|
20 |
-
i, j, h, w = region
|
21 |
-
|
22 |
-
# should we do something wrt the original size?
|
23 |
-
target["size"] = torch.tensor([h, w])
|
24 |
-
|
25 |
-
fields = ["labels", "area"]
|
26 |
-
|
27 |
-
if "boxes" in target:
|
28 |
-
boxes = target["boxes"]
|
29 |
-
max_size = torch.as_tensor([w, h], dtype=torch.float32)
|
30 |
-
cropped_boxes = boxes - torch.as_tensor([j, i, j, i])
|
31 |
-
cropped_boxes = torch.min(cropped_boxes.reshape(-1, 2, 2), max_size)
|
32 |
-
cropped_boxes = cropped_boxes.clamp(min=0)
|
33 |
-
area = (cropped_boxes[:, 1, :] - cropped_boxes[:, 0, :]).prod(dim=1)
|
34 |
-
target["boxes"] = cropped_boxes.reshape(-1, 4)
|
35 |
-
target["area"] = area
|
36 |
-
fields.append("boxes")
|
37 |
-
|
38 |
-
if "masks" in target:
|
39 |
-
# FIXME should we update the area here if there are no boxes?
|
40 |
-
target['masks'] = target['masks'][:, i:i + h, j:j + w]
|
41 |
-
fields.append("masks")
|
42 |
-
|
43 |
-
|
44 |
-
# remove elements for which the boxes or masks that have zero area
|
45 |
-
if "boxes" in target or "masks" in target:
|
46 |
-
# favor boxes selection when defining which elements to keep
|
47 |
-
# this is compatible with previous implementation
|
48 |
-
if "boxes" in target:
|
49 |
-
cropped_boxes = target['boxes'].reshape(-1, 2, 2)
|
50 |
-
keep = torch.all(cropped_boxes[:, 1, :] > cropped_boxes[:, 0, :], dim=1)
|
51 |
-
else:
|
52 |
-
keep = target['masks'].flatten(1).any(1)
|
53 |
-
|
54 |
-
for field in fields:
|
55 |
-
target[field] = target[field][keep]
|
56 |
-
|
57 |
-
return cropped_image, target
|
58 |
-
|
59 |
-
|
60 |
-
def hflip(image, target):
|
61 |
-
flipped_image = F.hflip(image)
|
62 |
-
|
63 |
-
w, h = image.size
|
64 |
-
|
65 |
-
target = target.copy()
|
66 |
-
if "boxes" in target:
|
67 |
-
boxes = target["boxes"]
|
68 |
-
boxes = boxes[:, [2, 1, 0, 3]] * torch.as_tensor([-1, 1, -1, 1]) + torch.as_tensor([w, 0, w, 0])
|
69 |
-
target["boxes"] = boxes
|
70 |
-
|
71 |
-
if "masks" in target:
|
72 |
-
target['masks'] = target['masks'].flip(-1)
|
73 |
-
|
74 |
-
return flipped_image, target
|
75 |
-
|
76 |
-
|
77 |
-
def resize(image, target, size, max_size=None):
|
78 |
-
# size can be min_size (scalar) or (w, h) tuple
|
79 |
-
|
80 |
-
def get_size_with_aspect_ratio(image_size, size, max_size=None):
|
81 |
-
w, h = image_size
|
82 |
-
if max_size is not None:
|
83 |
-
min_original_size = float(min((w, h)))
|
84 |
-
max_original_size = float(max((w, h)))
|
85 |
-
if max_original_size / min_original_size * size > max_size:
|
86 |
-
size = int(round(max_size * min_original_size / max_original_size))
|
87 |
-
|
88 |
-
if (w <= h and w == size) or (h <= w and h == size):
|
89 |
-
return (h, w)
|
90 |
-
|
91 |
-
if w < h:
|
92 |
-
ow = size
|
93 |
-
oh = int(size * h / w)
|
94 |
-
else:
|
95 |
-
oh = size
|
96 |
-
ow = int(size * w / h)
|
97 |
-
|
98 |
-
return (oh, ow)
|
99 |
-
|
100 |
-
def get_size(image_size, size, max_size=None):
|
101 |
-
if isinstance(size, (list, tuple)):
|
102 |
-
return size[::-1]
|
103 |
-
else:
|
104 |
-
return get_size_with_aspect_ratio(image_size, size, max_size)
|
105 |
-
|
106 |
-
size = get_size(image.size, size, max_size)
|
107 |
-
rescaled_image = F.resize(image, size)
|
108 |
-
|
109 |
-
if target is None:
|
110 |
-
return rescaled_image, None
|
111 |
-
|
112 |
-
ratios = tuple(float(s) / float(s_orig) for s, s_orig in zip(rescaled_image.size, image.size))
|
113 |
-
ratio_width, ratio_height = ratios
|
114 |
-
|
115 |
-
target = target.copy()
|
116 |
-
if "boxes" in target:
|
117 |
-
boxes = target["boxes"]
|
118 |
-
scaled_boxes = boxes * torch.as_tensor([ratio_width, ratio_height, ratio_width, ratio_height])
|
119 |
-
target["boxes"] = scaled_boxes
|
120 |
-
|
121 |
-
if "area" in target:
|
122 |
-
area = target["area"]
|
123 |
-
scaled_area = area * (ratio_width * ratio_height)
|
124 |
-
target["area"] = scaled_area
|
125 |
-
|
126 |
-
h, w = size
|
127 |
-
target["size"] = torch.tensor([h, w])
|
128 |
-
|
129 |
-
if "masks" in target:
|
130 |
-
target['masks'] = interpolate(
|
131 |
-
target['masks'][:, None].float(), size, mode="nearest")[:, 0] > 0.5
|
132 |
-
|
133 |
-
return rescaled_image, target
|
134 |
-
|
135 |
-
|
136 |
-
def pad(image, target, padding):
|
137 |
-
# assumes that we only pad on the bottom right corners
|
138 |
-
padded_image = F.pad(image, (0, 0, padding[0], padding[1]))
|
139 |
-
if target is None:
|
140 |
-
return padded_image, None
|
141 |
-
target = target.copy()
|
142 |
-
# should we do something wrt the original size?
|
143 |
-
target["size"] = torch.tensor(padded_image.size[::-1])
|
144 |
-
if "masks" in target:
|
145 |
-
target['masks'] = torch.nn.functional.pad(target['masks'], (0, padding[0], 0, padding[1]))
|
146 |
-
return padded_image, target
|
147 |
-
|
148 |
-
|
149 |
-
class ResizeDebug(object):
|
150 |
-
def __init__(self, size):
|
151 |
-
self.size = size
|
152 |
-
|
153 |
-
def __call__(self, img, target):
|
154 |
-
return resize(img, target, self.size)
|
155 |
-
|
156 |
-
|
157 |
-
class RandomCrop(object):
|
158 |
-
def __init__(self, size):
|
159 |
-
self.size = size
|
160 |
-
|
161 |
-
def __call__(self, img, target):
|
162 |
-
region = T.RandomCrop.get_params(img, self.size)
|
163 |
-
return crop(img, target, region)
|
164 |
-
|
165 |
-
|
166 |
-
class RandomSizeCrop(object):
|
167 |
-
def __init__(self, min_size: int, max_size: int):
|
168 |
-
self.min_size = min_size
|
169 |
-
self.max_size = max_size
|
170 |
-
|
171 |
-
def __call__(self, img: PIL.Image.Image, target: dict):
|
172 |
-
w = random.randint(self.min_size, min(img.width, self.max_size))
|
173 |
-
h = random.randint(self.min_size, min(img.height, self.max_size))
|
174 |
-
region = T.RandomCrop.get_params(img, [h, w])
|
175 |
-
return crop(img, target, region)
|
176 |
-
|
177 |
-
|
178 |
-
class CenterCrop(object):
|
179 |
-
def __init__(self, size):
|
180 |
-
self.size = size
|
181 |
-
|
182 |
-
def __call__(self, img, target):
|
183 |
-
image_width, image_height = img.size
|
184 |
-
crop_height, crop_width = self.size
|
185 |
-
crop_top = int(round((image_height - crop_height) / 2.))
|
186 |
-
crop_left = int(round((image_width - crop_width) / 2.))
|
187 |
-
return crop(img, target, (crop_top, crop_left, crop_height, crop_width))
|
188 |
-
|
189 |
-
|
190 |
-
class RandomHorizontalFlip(object):
|
191 |
-
def __init__(self, p=0.5):
|
192 |
-
self.p = p
|
193 |
-
|
194 |
-
def __call__(self, img, target):
|
195 |
-
if random.random() < self.p:
|
196 |
-
return hflip(img, target)
|
197 |
-
return img, target
|
198 |
-
|
199 |
-
|
200 |
-
class RandomResize(object):
|
201 |
-
def __init__(self, sizes, max_size=None):
|
202 |
-
assert isinstance(sizes, (list, tuple))
|
203 |
-
self.sizes = sizes
|
204 |
-
self.max_size = max_size
|
205 |
-
|
206 |
-
def __call__(self, img, target=None):
|
207 |
-
size = random.choice(self.sizes)
|
208 |
-
return resize(img, target, size, self.max_size)
|
209 |
-
|
210 |
-
|
211 |
-
class RandomPad(object):
|
212 |
-
def __init__(self, max_pad):
|
213 |
-
self.max_pad = max_pad
|
214 |
-
|
215 |
-
def __call__(self, img, target):
|
216 |
-
pad_x = random.randint(0, self.max_pad)
|
217 |
-
pad_y = random.randint(0, self.max_pad)
|
218 |
-
return pad(img, target, (pad_x, pad_y))
|
219 |
-
|
220 |
-
|
221 |
-
class RandomSelect(object):
|
222 |
-
"""
|
223 |
-
Randomly selects between transforms1 and transforms2,
|
224 |
-
with probability p for transforms1 and (1 - p) for transforms2
|
225 |
-
"""
|
226 |
-
def __init__(self, transforms1, transforms2, p=0.5):
|
227 |
-
self.transforms1 = transforms1
|
228 |
-
self.transforms2 = transforms2
|
229 |
-
self.p = p
|
230 |
-
|
231 |
-
def __call__(self, img, target):
|
232 |
-
if random.random() < self.p:
|
233 |
-
return self.transforms1(img, target)
|
234 |
-
return self.transforms2(img, target)
|
235 |
-
|
236 |
-
|
237 |
-
class ToTensor(object):
|
238 |
-
def __call__(self, img, target):
|
239 |
-
return F.to_tensor(img), target
|
240 |
-
|
241 |
-
|
242 |
-
class RandomErasing(object):
|
243 |
-
|
244 |
-
def __init__(self, *args, **kwargs):
|
245 |
-
self.eraser = T.RandomErasing(*args, **kwargs)
|
246 |
-
|
247 |
-
def __call__(self, img, target):
|
248 |
-
return self.eraser(img), target
|
249 |
-
|
250 |
-
|
251 |
-
class Normalize(object):
|
252 |
-
def __init__(self, mean, std):
|
253 |
-
self.mean = mean
|
254 |
-
self.std = std
|
255 |
-
|
256 |
-
def __call__(self, image, target=None):
|
257 |
-
image = F.normalize(image, mean=self.mean, std=self.std)
|
258 |
-
if target is None:
|
259 |
-
return image, None
|
260 |
-
target = target.copy()
|
261 |
-
h, w = image.shape[-2:]
|
262 |
-
if "boxes" in target:
|
263 |
-
boxes = target["boxes"]
|
264 |
-
boxes = box_xyxy_to_cxcywh(boxes)
|
265 |
-
boxes = boxes / torch.tensor([w, h, w, h], dtype=torch.float32)
|
266 |
-
target["boxes"] = boxes
|
267 |
-
return image, target
|
268 |
-
|
269 |
-
|
270 |
-
class Compose(object):
|
271 |
-
def __init__(self, transforms):
|
272 |
-
self.transforms = transforms
|
273 |
-
|
274 |
-
def __call__(self, image, target):
|
275 |
-
for t in self.transforms:
|
276 |
-
image, target = t(image, target)
|
277 |
-
return image, target
|
278 |
-
|
279 |
-
def __repr__(self):
|
280 |
-
format_string = self.__class__.__name__ + "("
|
281 |
-
for t in self.transforms:
|
282 |
-
format_string += "\n"
|
283 |
-
format_string += " {0}".format(t)
|
284 |
-
format_string += "\n)"
|
285 |
-
return format_string
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/__init__.py
DELETED
@@ -1,23 +0,0 @@
|
|
1 |
-
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
|
2 |
-
import torch.utils.data
|
3 |
-
import torchvision
|
4 |
-
from .coco import build as build_coco
|
5 |
-
|
6 |
-
|
7 |
-
def get_coco_api_from_dataset(dataset):
|
8 |
-
for _ in range(10):
|
9 |
-
# if isinstance(dataset, torchvision.datasets.CocoDetection):
|
10 |
-
# break
|
11 |
-
if isinstance(dataset, torch.utils.data.Subset):
|
12 |
-
dataset = dataset.dataset
|
13 |
-
if isinstance(dataset, torchvision.datasets.CocoDetection):
|
14 |
-
return dataset.coco
|
15 |
-
|
16 |
-
|
17 |
-
def build_dataset(image_set, args, datasetinfo):
|
18 |
-
if datasetinfo["dataset_mode"] == 'coco':
|
19 |
-
return build_coco(image_set, args, datasetinfo)
|
20 |
-
if datasetinfo["dataset_mode"] == 'odvg':
|
21 |
-
from .odvg import build_odvg
|
22 |
-
return build_odvg(image_set, args, datasetinfo)
|
23 |
-
raise ValueError(f'dataset {args.dataset_file} not supported')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/__pycache__/__init__.cpython-310.pyc
DELETED
Binary file (899 Bytes)
|
|
datasets/__pycache__/coco.cpython-310.pyc
DELETED
Binary file (20.2 kB)
|
|
datasets/__pycache__/coco_eval.cpython-310.pyc
DELETED
Binary file (7.42 kB)
|
|
datasets/__pycache__/cocogrounding_eval.cpython-310.pyc
DELETED
Binary file (7.44 kB)
|
|
datasets/__pycache__/data_util.cpython-310.pyc
DELETED
Binary file (4.55 kB)
|
|
datasets/__pycache__/odvg.cpython-310.pyc
DELETED
Binary file (8.21 kB)
|
|
datasets/__pycache__/panoptic_eval.cpython-310.pyc
DELETED
Binary file (1.87 kB)
|
|
datasets/__pycache__/random_crop.cpython-310.pyc
DELETED
Binary file (3.69 kB)
|
|
datasets/__pycache__/sltransform.cpython-310.pyc
DELETED
Binary file (7.68 kB)
|
|
datasets/__pycache__/transforms.cpython-310.pyc
DELETED
Binary file (9.53 kB)
|
|
datasets/coco.py
DELETED
@@ -1,649 +0,0 @@
|
|
1 |
-
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
|
2 |
-
"""
|
3 |
-
COCO dataset which returns image_id for evaluation.
|
4 |
-
|
5 |
-
Mostly copy-paste from https://github.com/pytorch/vision/blob/13b35ff/references/detection/coco_utils.py
|
6 |
-
"""
|
7 |
-
if __name__=="__main__":
|
8 |
-
# for debug only
|
9 |
-
import os, sys
|
10 |
-
sys.path.append(os.path.dirname(sys.path[0]))
|
11 |
-
from torchvision.datasets.vision import VisionDataset
|
12 |
-
|
13 |
-
import json
|
14 |
-
from pathlib import Path
|
15 |
-
import random
|
16 |
-
import os
|
17 |
-
from typing import Any, Callable, List, Optional, Tuple
|
18 |
-
|
19 |
-
from PIL import Image
|
20 |
-
|
21 |
-
import torch
|
22 |
-
import torch.utils.data
|
23 |
-
import torchvision
|
24 |
-
from pycocotools import mask as coco_mask
|
25 |
-
|
26 |
-
from datasets.data_util import preparing_dataset
|
27 |
-
import datasets.transforms as T
|
28 |
-
from util.box_ops import box_cxcywh_to_xyxy, box_iou
|
29 |
-
|
30 |
-
__all__ = ['build']
|
31 |
-
|
32 |
-
|
33 |
-
class label2compat():
|
34 |
-
def __init__(self) -> None:
|
35 |
-
self.category_map_str = {"1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "10": 10, "11": 11, "13": 12, "14": 13, "15": 14, "16": 15, "17": 16, "18": 17, "19": 18, "20": 19, "21": 20, "22": 21, "23": 22, "24": 23, "25": 24, "27": 25, "28": 26, "31": 27, "32": 28, "33": 29, "34": 30, "35": 31, "36": 32, "37": 33, "38": 34, "39": 35, "40": 36, "41": 37, "42": 38, "43": 39, "44": 40, "46": 41, "47": 42, "48": 43, "49": 44, "50": 45, "51": 46, "52": 47, "53": 48, "54": 49, "55": 50, "56": 51, "57": 52, "58": 53, "59": 54, "60": 55, "61": 56, "62": 57, "63": 58, "64": 59, "65": 60, "67": 61, "70": 62, "72": 63, "73": 64, "74": 65, "75": 66, "76": 67, "77": 68, "78": 69, "79": 70, "80": 71, "81": 72, "82": 73, "84": 74, "85": 75, "86": 76, "87": 77, "88": 78, "89": 79, "90": 80}
|
36 |
-
self.category_map = {int(k):v for k,v in self.category_map_str.items()}
|
37 |
-
|
38 |
-
def __call__(self, target, img=None):
|
39 |
-
labels = target['labels']
|
40 |
-
res = torch.zeros(labels.shape, dtype=labels.dtype)
|
41 |
-
for idx, item in enumerate(labels):
|
42 |
-
res[idx] = self.category_map[item.item()] - 1
|
43 |
-
target['label_compat'] = res
|
44 |
-
if img is not None:
|
45 |
-
return target, img
|
46 |
-
else:
|
47 |
-
return target
|
48 |
-
|
49 |
-
|
50 |
-
class label_compat2onehot():
|
51 |
-
def __init__(self, num_class=80, num_output_objs=1):
|
52 |
-
self.num_class = num_class
|
53 |
-
self.num_output_objs = num_output_objs
|
54 |
-
if num_output_objs != 1:
|
55 |
-
raise DeprecationWarning("num_output_objs!=1, which is only used for comparison")
|
56 |
-
|
57 |
-
def __call__(self, target, img=None):
|
58 |
-
labels = target['label_compat']
|
59 |
-
place_dict = {k:0 for k in range(self.num_class)}
|
60 |
-
if self.num_output_objs == 1:
|
61 |
-
res = torch.zeros(self.num_class)
|
62 |
-
for i in labels:
|
63 |
-
itm = i.item()
|
64 |
-
res[itm] = 1.0
|
65 |
-
else:
|
66 |
-
# compat with baseline
|
67 |
-
res = torch.zeros(self.num_class, self.num_output_objs)
|
68 |
-
for i in labels:
|
69 |
-
itm = i.item()
|
70 |
-
res[itm][place_dict[itm]] = 1.0
|
71 |
-
place_dict[itm] += 1
|
72 |
-
target['label_compat_onehot'] = res
|
73 |
-
if img is not None:
|
74 |
-
return target, img
|
75 |
-
else:
|
76 |
-
return target
|
77 |
-
|
78 |
-
|
79 |
-
class box_label_catter():
|
80 |
-
def __init__(self):
|
81 |
-
pass
|
82 |
-
|
83 |
-
def __call__(self, target, img=None):
|
84 |
-
labels = target['label_compat']
|
85 |
-
boxes = target['boxes']
|
86 |
-
box_label = torch.cat((boxes, labels.unsqueeze(-1)), 1)
|
87 |
-
target['box_label'] = box_label
|
88 |
-
if img is not None:
|
89 |
-
return target, img
|
90 |
-
else:
|
91 |
-
return target
|
92 |
-
|
93 |
-
|
94 |
-
class RandomSelectBoxlabels():
|
95 |
-
def __init__(self, num_classes, leave_one_out=False, blank_prob=0.8,
|
96 |
-
prob_first_item = 0.0,
|
97 |
-
prob_random_item = 0.0,
|
98 |
-
prob_last_item = 0.8,
|
99 |
-
prob_stop_sign = 0.2
|
100 |
-
) -> None:
|
101 |
-
self.num_classes = num_classes
|
102 |
-
self.leave_one_out = leave_one_out
|
103 |
-
self.blank_prob = blank_prob
|
104 |
-
|
105 |
-
self.set_state(prob_first_item, prob_random_item, prob_last_item, prob_stop_sign)
|
106 |
-
|
107 |
-
|
108 |
-
def get_state(self):
|
109 |
-
return [self.prob_first_item, self.prob_random_item, self.prob_last_item, self.prob_stop_sign]
|
110 |
-
|
111 |
-
def set_state(self, prob_first_item, prob_random_item, prob_last_item, prob_stop_sign):
|
112 |
-
sum_prob = prob_first_item + prob_random_item + prob_last_item + prob_stop_sign
|
113 |
-
assert sum_prob - 1 < 1e-6, \
|
114 |
-
f"Sum up all prob = {sum_prob}. prob_first_item:{prob_first_item}" \
|
115 |
-
+ f"prob_random_item:{prob_random_item}, prob_last_item:{prob_last_item}" \
|
116 |
-
+ f"prob_stop_sign:{prob_stop_sign}"
|
117 |
-
|
118 |
-
self.prob_first_item = prob_first_item
|
119 |
-
self.prob_random_item = prob_random_item
|
120 |
-
self.prob_last_item = prob_last_item
|
121 |
-
self.prob_stop_sign = prob_stop_sign
|
122 |
-
|
123 |
-
|
124 |
-
def sample_for_pred_first_item(self, box_label: torch.FloatTensor):
|
125 |
-
box_label_known = torch.Tensor(0,5)
|
126 |
-
box_label_unknown = box_label
|
127 |
-
return box_label_known, box_label_unknown
|
128 |
-
|
129 |
-
def sample_for_pred_random_item(self, box_label: torch.FloatTensor):
|
130 |
-
n_select = int(random.random() * box_label.shape[0])
|
131 |
-
box_label = box_label[torch.randperm(box_label.shape[0])]
|
132 |
-
box_label_known = box_label[:n_select]
|
133 |
-
box_label_unknown = box_label[n_select:]
|
134 |
-
return box_label_known, box_label_unknown
|
135 |
-
|
136 |
-
def sample_for_pred_last_item(self, box_label: torch.FloatTensor):
|
137 |
-
box_label_perm = box_label[torch.randperm(box_label.shape[0])]
|
138 |
-
known_label_list = []
|
139 |
-
box_label_known = []
|
140 |
-
box_label_unknown = []
|
141 |
-
for item in box_label_perm:
|
142 |
-
label_i = item[4].item()
|
143 |
-
if label_i in known_label_list:
|
144 |
-
box_label_known.append(item)
|
145 |
-
else:
|
146 |
-
# first item
|
147 |
-
box_label_unknown.append(item)
|
148 |
-
known_label_list.append(label_i)
|
149 |
-
box_label_known = torch.stack(box_label_known) if len(box_label_known) > 0 else torch.Tensor(0,5)
|
150 |
-
box_label_unknown = torch.stack(box_label_unknown) if len(box_label_unknown) > 0 else torch.Tensor(0,5)
|
151 |
-
return box_label_known, box_label_unknown
|
152 |
-
|
153 |
-
def sample_for_pred_stop_sign(self, box_label: torch.FloatTensor):
|
154 |
-
box_label_unknown = torch.Tensor(0,5)
|
155 |
-
box_label_known = box_label
|
156 |
-
return box_label_known, box_label_unknown
|
157 |
-
|
158 |
-
def __call__(self, target, img=None):
|
159 |
-
box_label = target['box_label'] # K, 5
|
160 |
-
|
161 |
-
dice_number = random.random()
|
162 |
-
|
163 |
-
if dice_number < self.prob_first_item:
|
164 |
-
box_label_known, box_label_unknown = self.sample_for_pred_first_item(box_label)
|
165 |
-
elif dice_number < self.prob_first_item + self.prob_random_item:
|
166 |
-
box_label_known, box_label_unknown = self.sample_for_pred_random_item(box_label)
|
167 |
-
elif dice_number < self.prob_first_item + self.prob_random_item + self.prob_last_item:
|
168 |
-
box_label_known, box_label_unknown = self.sample_for_pred_last_item(box_label)
|
169 |
-
else:
|
170 |
-
box_label_known, box_label_unknown = self.sample_for_pred_stop_sign(box_label)
|
171 |
-
|
172 |
-
target['label_onehot_known'] = label2onehot(box_label_known[:,-1], self.num_classes)
|
173 |
-
target['label_onehot_unknown'] = label2onehot(box_label_unknown[:, -1], self.num_classes)
|
174 |
-
target['box_label_known'] = box_label_known
|
175 |
-
target['box_label_unknown'] = box_label_unknown
|
176 |
-
|
177 |
-
return target, img
|
178 |
-
|
179 |
-
|
180 |
-
class RandomDrop():
|
181 |
-
def __init__(self, p=0.2) -> None:
|
182 |
-
self.p = p
|
183 |
-
|
184 |
-
def __call__(self, target, img=None):
|
185 |
-
known_box = target['box_label_known']
|
186 |
-
num_known_box = known_box.size(0)
|
187 |
-
idxs = torch.rand(num_known_box)
|
188 |
-
# indices = torch.randperm(num_known_box)[:int((1-self).p*num_known_box + 0.5 + random.random())]
|
189 |
-
target['box_label_known'] = known_box[idxs > self.p]
|
190 |
-
return target, img
|
191 |
-
|
192 |
-
|
193 |
-
class BboxPertuber():
|
194 |
-
def __init__(self, max_ratio = 0.02, generate_samples = 1000) -> None:
|
195 |
-
self.max_ratio = max_ratio
|
196 |
-
self.generate_samples = generate_samples
|
197 |
-
self.samples = self.generate_pertube_samples()
|
198 |
-
self.idx = 0
|
199 |
-
|
200 |
-
def generate_pertube_samples(self):
|
201 |
-
import torch
|
202 |
-
samples = (torch.rand(self.generate_samples, 5) - 0.5) * 2 * self.max_ratio
|
203 |
-
return samples
|
204 |
-
|
205 |
-
def __call__(self, target, img):
|
206 |
-
known_box = target['box_label_known'] # Tensor(K,5), K known bbox
|
207 |
-
K = known_box.shape[0]
|
208 |
-
known_box_pertube = torch.zeros(K, 6) # 4:bbox, 1:prob, 1:label
|
209 |
-
if K == 0:
|
210 |
-
pass
|
211 |
-
else:
|
212 |
-
if self.idx + K > self.generate_samples:
|
213 |
-
self.idx = 0
|
214 |
-
delta = self.samples[self.idx: self.idx + K, :]
|
215 |
-
known_box_pertube[:, :4] = known_box[:, :4] + delta[:, :4]
|
216 |
-
iou = (torch.diag(box_iou(box_cxcywh_to_xyxy(known_box[:, :4]), box_cxcywh_to_xyxy(known_box_pertube[:, :4]))[0])) * (1 + delta[:, -1])
|
217 |
-
known_box_pertube[:, 4].copy_(iou)
|
218 |
-
known_box_pertube[:, -1].copy_(known_box[:, -1])
|
219 |
-
|
220 |
-
target['box_label_known_pertube'] = known_box_pertube
|
221 |
-
return target, img
|
222 |
-
|
223 |
-
|
224 |
-
class RandomCutout():
|
225 |
-
def __init__(self, factor=0.5) -> None:
|
226 |
-
self.factor = factor
|
227 |
-
|
228 |
-
def __call__(self, target, img=None):
|
229 |
-
unknown_box = target['box_label_unknown'] # Ku, 5
|
230 |
-
known_box = target['box_label_known_pertube'] # Kk, 6
|
231 |
-
Ku = unknown_box.size(0)
|
232 |
-
|
233 |
-
known_box_add = torch.zeros(Ku, 6) # Ku, 6
|
234 |
-
known_box_add[:, :5] = unknown_box
|
235 |
-
known_box_add[:, 5].uniform_(0.5, 1)
|
236 |
-
|
237 |
-
|
238 |
-
known_box_add[:, :2] += known_box_add[:, 2:4] * (torch.rand(Ku, 2) - 0.5) / 2
|
239 |
-
known_box_add[:, 2:4] /= 2
|
240 |
-
|
241 |
-
target['box_label_known_pertube'] = torch.cat((known_box, known_box_add))
|
242 |
-
return target, img
|
243 |
-
|
244 |
-
|
245 |
-
class RandomSelectBoxes():
|
246 |
-
def __init__(self, num_class=80) -> None:
|
247 |
-
Warning("This is such a slow function and will be deprecated soon!!!")
|
248 |
-
self.num_class = num_class
|
249 |
-
|
250 |
-
def __call__(self, target, img=None):
|
251 |
-
boxes = target['boxes']
|
252 |
-
labels = target['label_compat']
|
253 |
-
|
254 |
-
# transform to list of tensors
|
255 |
-
boxs_list = [[] for i in range(self.num_class)]
|
256 |
-
for idx, item in enumerate(boxes):
|
257 |
-
label = labels[idx].item()
|
258 |
-
boxs_list[label].append(item)
|
259 |
-
boxs_list_tensor = [torch.stack(i) if len(i) > 0 else torch.Tensor(0,4) for i in boxs_list]
|
260 |
-
|
261 |
-
# random selection
|
262 |
-
box_known = []
|
263 |
-
box_unknown = []
|
264 |
-
for idx, item in enumerate(boxs_list_tensor):
|
265 |
-
ncnt = item.shape[0]
|
266 |
-
nselect = int(random.random() * ncnt) # close in both sides, much faster than random.randint
|
267 |
-
|
268 |
-
item = item[torch.randperm(ncnt)]
|
269 |
-
# random.shuffle(item)
|
270 |
-
box_known.append(item[:nselect])
|
271 |
-
box_unknown.append(item[nselect:])
|
272 |
-
|
273 |
-
# box_known_tensor = [torch.stack(i) if len(i) > 0 else torch.Tensor(0,4) for i in box_known]
|
274 |
-
# box_unknown_tensor = [torch.stack(i) if len(i) > 0 else torch.Tensor(0,4) for i in box_unknown]
|
275 |
-
# print('box_unknown_tensor:', box_unknown_tensor)
|
276 |
-
target['known_box'] = box_known
|
277 |
-
target['unknown_box'] = box_unknown
|
278 |
-
return target, img
|
279 |
-
|
280 |
-
|
281 |
-
def label2onehot(label, num_classes):
|
282 |
-
"""
|
283 |
-
label: Tensor(K)
|
284 |
-
"""
|
285 |
-
res = torch.zeros(num_classes)
|
286 |
-
for i in label:
|
287 |
-
itm = int(i.item())
|
288 |
-
res[itm] = 1.0
|
289 |
-
return res
|
290 |
-
|
291 |
-
|
292 |
-
class MaskCrop():
|
293 |
-
def __init__(self) -> None:
|
294 |
-
pass
|
295 |
-
|
296 |
-
def __call__(self, target, img):
|
297 |
-
known_box = target['known_box']
|
298 |
-
h,w = img.shape[1:] # h,w
|
299 |
-
# imgsize = target['orig_size'] # h,w
|
300 |
-
|
301 |
-
scale = torch.Tensor([w, h, w, h])
|
302 |
-
|
303 |
-
# _cnt = 0
|
304 |
-
for boxes in known_box:
|
305 |
-
if boxes.shape[0] == 0:
|
306 |
-
continue
|
307 |
-
box_xyxy = box_cxcywh_to_xyxy(boxes) * scale
|
308 |
-
for box in box_xyxy:
|
309 |
-
x1, y1, x2, y2 = [int(i) for i in box.tolist()]
|
310 |
-
img[:, y1:y2, x1:x2] = 0
|
311 |
-
# _cnt += 1
|
312 |
-
# print("_cnt:", _cnt)
|
313 |
-
return target, img
|
314 |
-
|
315 |
-
|
316 |
-
dataset_hook_register = {
|
317 |
-
'label2compat': label2compat,
|
318 |
-
'label_compat2onehot': label_compat2onehot,
|
319 |
-
'box_label_catter': box_label_catter,
|
320 |
-
'RandomSelectBoxlabels': RandomSelectBoxlabels,
|
321 |
-
'RandomSelectBoxes': RandomSelectBoxes,
|
322 |
-
'MaskCrop': MaskCrop,
|
323 |
-
'BboxPertuber': BboxPertuber,
|
324 |
-
}
|
325 |
-
|
326 |
-
|
327 |
-
class CocoDetection(torchvision.datasets.CocoDetection):
|
328 |
-
def __init__(self, img_folder, ann_file, transforms, return_masks, aux_target_hacks=None):
|
329 |
-
super(CocoDetection, self).__init__(img_folder, ann_file)
|
330 |
-
self._transforms = transforms
|
331 |
-
self.prepare = ConvertCocoPolysToMask(return_masks)
|
332 |
-
self.aux_target_hacks = aux_target_hacks
|
333 |
-
|
334 |
-
def change_hack_attr(self, hackclassname, attrkv_dict):
|
335 |
-
target_class = dataset_hook_register[hackclassname]
|
336 |
-
for item in self.aux_target_hacks:
|
337 |
-
if isinstance(item, target_class):
|
338 |
-
for k,v in attrkv_dict.items():
|
339 |
-
setattr(item, k, v)
|
340 |
-
|
341 |
-
def get_hack(self, hackclassname):
|
342 |
-
target_class = dataset_hook_register[hackclassname]
|
343 |
-
for item in self.aux_target_hacks:
|
344 |
-
if isinstance(item, target_class):
|
345 |
-
return item
|
346 |
-
|
347 |
-
def _load_image(self, id: int) -> Image.Image:
|
348 |
-
path = self.coco.loadImgs(id)[0]["file_name"]
|
349 |
-
abs_path = os.path.join(self.root, path)
|
350 |
-
return Image.open(abs_path).convert("RGB")
|
351 |
-
|
352 |
-
def __getitem__(self, idx):
|
353 |
-
"""
|
354 |
-
Output:
|
355 |
-
- target: dict of multiple items
|
356 |
-
- boxes: Tensor[num_box, 4]. \
|
357 |
-
Init type: x0,y0,x1,y1. unnormalized data.
|
358 |
-
Final type: cx,cy,w,h. normalized data.
|
359 |
-
"""
|
360 |
-
try:
|
361 |
-
img, target = super(CocoDetection, self).__getitem__(idx)
|
362 |
-
except:
|
363 |
-
print("Error idx: {}".format(idx))
|
364 |
-
idx += 1
|
365 |
-
img, target = super(CocoDetection, self).__getitem__(idx)
|
366 |
-
image_id = self.ids[idx]
|
367 |
-
target = {'image_id': image_id, 'annotations': target}
|
368 |
-
img, target = self.prepare(img, target)
|
369 |
-
|
370 |
-
if self._transforms is not None:
|
371 |
-
img, target = self._transforms(img, target)
|
372 |
-
|
373 |
-
# convert to needed format
|
374 |
-
if self.aux_target_hacks is not None:
|
375 |
-
for hack_runner in self.aux_target_hacks:
|
376 |
-
target, img = hack_runner(target, img=img)
|
377 |
-
|
378 |
-
return img, target
|
379 |
-
|
380 |
-
|
381 |
-
def convert_coco_poly_to_mask(segmentations, height, width):
|
382 |
-
masks = []
|
383 |
-
for polygons in segmentations:
|
384 |
-
rles = coco_mask.frPyObjects(polygons, height, width)
|
385 |
-
mask = coco_mask.decode(rles)
|
386 |
-
if len(mask.shape) < 3:
|
387 |
-
mask = mask[..., None]
|
388 |
-
mask = torch.as_tensor(mask, dtype=torch.uint8)
|
389 |
-
mask = mask.any(dim=2)
|
390 |
-
masks.append(mask)
|
391 |
-
if masks:
|
392 |
-
masks = torch.stack(masks, dim=0)
|
393 |
-
else:
|
394 |
-
masks = torch.zeros((0, height, width), dtype=torch.uint8)
|
395 |
-
return masks
|
396 |
-
|
397 |
-
|
398 |
-
class ConvertCocoPolysToMask(object):
|
399 |
-
def __init__(self, return_masks=False):
|
400 |
-
self.return_masks = return_masks
|
401 |
-
|
402 |
-
def __call__(self, image, target):
|
403 |
-
w, h = image.size
|
404 |
-
|
405 |
-
image_id = target["image_id"]
|
406 |
-
image_id = torch.tensor([image_id])
|
407 |
-
|
408 |
-
anno = target["annotations"]
|
409 |
-
|
410 |
-
anno = [obj for obj in anno if 'iscrowd' not in obj or obj['iscrowd'] == 0]
|
411 |
-
|
412 |
-
boxes = [obj["bbox"] for obj in anno]
|
413 |
-
# guard against no boxes via resizing
|
414 |
-
boxes = torch.as_tensor(boxes, dtype=torch.float32).reshape(-1, 4)
|
415 |
-
boxes[:, 2:] += boxes[:, :2]
|
416 |
-
boxes[:, 0::2].clamp_(min=0, max=w)
|
417 |
-
boxes[:, 1::2].clamp_(min=0, max=h)
|
418 |
-
|
419 |
-
classes = [obj["category_id"] for obj in anno]
|
420 |
-
classes = torch.tensor(classes, dtype=torch.int64)
|
421 |
-
|
422 |
-
if self.return_masks:
|
423 |
-
segmentations = [obj["segmentation"] for obj in anno]
|
424 |
-
masks = convert_coco_poly_to_mask(segmentations, h, w)
|
425 |
-
|
426 |
-
keypoints = None
|
427 |
-
if anno and "keypoints" in anno[0]:
|
428 |
-
keypoints = [obj["keypoints"] for obj in anno]
|
429 |
-
keypoints = torch.as_tensor(keypoints, dtype=torch.float32)
|
430 |
-
num_keypoints = keypoints.shape[0]
|
431 |
-
if num_keypoints:
|
432 |
-
keypoints = keypoints.view(num_keypoints, -1, 3)
|
433 |
-
|
434 |
-
keep = (boxes[:, 3] > boxes[:, 1]) & (boxes[:, 2] > boxes[:, 0])
|
435 |
-
boxes = boxes[keep]
|
436 |
-
classes = classes[keep]
|
437 |
-
if self.return_masks:
|
438 |
-
masks = masks[keep]
|
439 |
-
if keypoints is not None:
|
440 |
-
keypoints = keypoints[keep]
|
441 |
-
|
442 |
-
target = {}
|
443 |
-
target["boxes"] = boxes
|
444 |
-
target["labels"] = classes
|
445 |
-
if self.return_masks:
|
446 |
-
target["masks"] = masks
|
447 |
-
target["image_id"] = image_id
|
448 |
-
if keypoints is not None:
|
449 |
-
target["keypoints"] = keypoints
|
450 |
-
|
451 |
-
# for conversion to coco api
|
452 |
-
area = torch.tensor([obj["area"] for obj in anno])
|
453 |
-
iscrowd = torch.tensor([obj["iscrowd"] if "iscrowd" in obj else 0 for obj in anno])
|
454 |
-
target["area"] = area[keep]
|
455 |
-
target["iscrowd"] = iscrowd[keep]
|
456 |
-
|
457 |
-
target["orig_size"] = torch.as_tensor([int(h), int(w)])
|
458 |
-
target["size"] = torch.as_tensor([int(h), int(w)])
|
459 |
-
|
460 |
-
return image, target
|
461 |
-
|
462 |
-
|
463 |
-
def make_coco_transforms(image_set, fix_size=False, strong_aug=False, args=None):
|
464 |
-
|
465 |
-
normalize = T.Compose([
|
466 |
-
T.ToTensor(),
|
467 |
-
T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
|
468 |
-
])
|
469 |
-
|
470 |
-
# config the params for data aug
|
471 |
-
scales = [480, 512, 544, 576, 608, 640, 672, 704, 736, 768, 800]
|
472 |
-
max_size = 1333
|
473 |
-
scales2_resize = [400, 500, 600]
|
474 |
-
scales2_crop = [384, 600]
|
475 |
-
|
476 |
-
# update args from config files
|
477 |
-
scales = getattr(args, 'data_aug_scales', scales)
|
478 |
-
max_size = getattr(args, 'data_aug_max_size', max_size)
|
479 |
-
scales2_resize = getattr(args, 'data_aug_scales2_resize', scales2_resize)
|
480 |
-
scales2_crop = getattr(args, 'data_aug_scales2_crop', scales2_crop)
|
481 |
-
|
482 |
-
# resize them
|
483 |
-
data_aug_scale_overlap = getattr(args, 'data_aug_scale_overlap', None)
|
484 |
-
if data_aug_scale_overlap is not None and data_aug_scale_overlap > 0:
|
485 |
-
data_aug_scale_overlap = float(data_aug_scale_overlap)
|
486 |
-
scales = [int(i*data_aug_scale_overlap) for i in scales]
|
487 |
-
max_size = int(max_size*data_aug_scale_overlap)
|
488 |
-
scales2_resize = [int(i*data_aug_scale_overlap) for i in scales2_resize]
|
489 |
-
scales2_crop = [int(i*data_aug_scale_overlap) for i in scales2_crop]
|
490 |
-
|
491 |
-
datadict_for_print = {
|
492 |
-
'scales': scales,
|
493 |
-
'max_size': max_size,
|
494 |
-
'scales2_resize': scales2_resize,
|
495 |
-
'scales2_crop': scales2_crop
|
496 |
-
}
|
497 |
-
# print("data_aug_params:", json.dumps(datadict_for_print, indent=2))
|
498 |
-
|
499 |
-
if image_set == 'train':
|
500 |
-
if fix_size:
|
501 |
-
return T.Compose([
|
502 |
-
T.RandomHorizontalFlip(),
|
503 |
-
T.RandomResize([(max_size, max(scales))]),
|
504 |
-
# T.RandomResize([(512, 512)]),
|
505 |
-
normalize,
|
506 |
-
])
|
507 |
-
|
508 |
-
if strong_aug:
|
509 |
-
import datasets.sltransform as SLT
|
510 |
-
|
511 |
-
return T.Compose([
|
512 |
-
T.RandomHorizontalFlip(),
|
513 |
-
T.RandomSelect(
|
514 |
-
T.RandomResize(scales, max_size=max_size),
|
515 |
-
T.Compose([
|
516 |
-
T.RandomResize(scales2_resize),
|
517 |
-
T.RandomSizeCrop(*scales2_crop),
|
518 |
-
T.RandomResize(scales, max_size=max_size),
|
519 |
-
])
|
520 |
-
),
|
521 |
-
SLT.RandomSelectMulti([
|
522 |
-
SLT.RandomCrop(),
|
523 |
-
SLT.LightingNoise(),
|
524 |
-
SLT.AdjustBrightness(2),
|
525 |
-
SLT.AdjustContrast(2),
|
526 |
-
]),
|
527 |
-
normalize,
|
528 |
-
])
|
529 |
-
|
530 |
-
return T.Compose([
|
531 |
-
T.RandomHorizontalFlip(),
|
532 |
-
T.RandomSelect(
|
533 |
-
T.RandomResize(scales, max_size=max_size),
|
534 |
-
T.Compose([
|
535 |
-
T.RandomResize(scales2_resize),
|
536 |
-
T.RandomSizeCrop(*scales2_crop),
|
537 |
-
T.RandomResize(scales, max_size=max_size),
|
538 |
-
])
|
539 |
-
),
|
540 |
-
normalize,
|
541 |
-
])
|
542 |
-
|
543 |
-
if image_set in ['val', 'eval_debug', 'train_reg', 'test']:
|
544 |
-
|
545 |
-
if os.environ.get("GFLOPS_DEBUG_SHILONG", False) == 'INFO':
|
546 |
-
print("Under debug mode for flops calculation only!!!!!!!!!!!!!!!!")
|
547 |
-
return T.Compose([
|
548 |
-
T.ResizeDebug((1280, 800)),
|
549 |
-
normalize,
|
550 |
-
])
|
551 |
-
|
552 |
-
return T.Compose([
|
553 |
-
T.RandomResize([max(scales)], max_size=max_size),
|
554 |
-
normalize,
|
555 |
-
])
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
raise ValueError(f'unknown {image_set}')
|
560 |
-
|
561 |
-
|
562 |
-
def get_aux_target_hacks_list(image_set, args):
|
563 |
-
if args.modelname in ['q2bs_mask', 'q2bs']:
|
564 |
-
aux_target_hacks_list = [
|
565 |
-
label2compat(),
|
566 |
-
label_compat2onehot(),
|
567 |
-
RandomSelectBoxes(num_class=args.num_classes)
|
568 |
-
]
|
569 |
-
if args.masked_data and image_set == 'train':
|
570 |
-
# aux_target_hacks_list.append()
|
571 |
-
aux_target_hacks_list.append(MaskCrop())
|
572 |
-
elif args.modelname in ['q2bm_v2', 'q2bs_ce', 'q2op', 'q2ofocal', 'q2opclip', 'q2ocqonly']:
|
573 |
-
aux_target_hacks_list = [
|
574 |
-
label2compat(),
|
575 |
-
label_compat2onehot(),
|
576 |
-
box_label_catter(),
|
577 |
-
RandomSelectBoxlabels(num_classes=args.num_classes,
|
578 |
-
prob_first_item=args.prob_first_item,
|
579 |
-
prob_random_item=args.prob_random_item,
|
580 |
-
prob_last_item=args.prob_last_item,
|
581 |
-
prob_stop_sign=args.prob_stop_sign,
|
582 |
-
),
|
583 |
-
BboxPertuber(max_ratio=0.02, generate_samples=1000),
|
584 |
-
]
|
585 |
-
elif args.modelname in ['q2omask', 'q2osa']:
|
586 |
-
if args.coco_aug:
|
587 |
-
aux_target_hacks_list = [
|
588 |
-
label2compat(),
|
589 |
-
label_compat2onehot(),
|
590 |
-
box_label_catter(),
|
591 |
-
RandomSelectBoxlabels(num_classes=args.num_classes,
|
592 |
-
prob_first_item=args.prob_first_item,
|
593 |
-
prob_random_item=args.prob_random_item,
|
594 |
-
prob_last_item=args.prob_last_item,
|
595 |
-
prob_stop_sign=args.prob_stop_sign,
|
596 |
-
),
|
597 |
-
RandomDrop(p=0.2),
|
598 |
-
BboxPertuber(max_ratio=0.02, generate_samples=1000),
|
599 |
-
RandomCutout(factor=0.5)
|
600 |
-
]
|
601 |
-
else:
|
602 |
-
aux_target_hacks_list = [
|
603 |
-
label2compat(),
|
604 |
-
label_compat2onehot(),
|
605 |
-
box_label_catter(),
|
606 |
-
RandomSelectBoxlabels(num_classes=args.num_classes,
|
607 |
-
prob_first_item=args.prob_first_item,
|
608 |
-
prob_random_item=args.prob_random_item,
|
609 |
-
prob_last_item=args.prob_last_item,
|
610 |
-
prob_stop_sign=args.prob_stop_sign,
|
611 |
-
),
|
612 |
-
BboxPertuber(max_ratio=0.02, generate_samples=1000),
|
613 |
-
]
|
614 |
-
else:
|
615 |
-
aux_target_hacks_list = None
|
616 |
-
|
617 |
-
return aux_target_hacks_list
|
618 |
-
|
619 |
-
|
620 |
-
def build(image_set, args, datasetinfo):
|
621 |
-
img_folder = datasetinfo["root"]
|
622 |
-
ann_file = datasetinfo["anno"]
|
623 |
-
|
624 |
-
# copy to local path
|
625 |
-
if os.environ.get('DATA_COPY_SHILONG') == 'INFO':
|
626 |
-
preparing_dataset(dict(img_folder=img_folder, ann_file=ann_file), image_set, args)
|
627 |
-
|
628 |
-
try:
|
629 |
-
strong_aug = args.strong_aug
|
630 |
-
except:
|
631 |
-
strong_aug = False
|
632 |
-
print(img_folder, ann_file)
|
633 |
-
dataset = CocoDetection(img_folder, ann_file,
|
634 |
-
transforms=make_coco_transforms(image_set, fix_size=args.fix_size, strong_aug=strong_aug, args=args),
|
635 |
-
return_masks=args.masks,
|
636 |
-
aux_target_hacks=None,
|
637 |
-
)
|
638 |
-
return dataset
|
639 |
-
|
640 |
-
|
641 |
-
if __name__ == "__main__":
|
642 |
-
# Objects365 Val example
|
643 |
-
dataset_o365 = CocoDetection(
|
644 |
-
'/path/Objects365/train/',
|
645 |
-
"/path/Objects365/slannos/anno_preprocess_train_v2.json",
|
646 |
-
transforms=None,
|
647 |
-
return_masks=False,
|
648 |
-
)
|
649 |
-
print('len(dataset_o365):', len(dataset_o365))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/coco_eval.py
DELETED
@@ -1,266 +0,0 @@
|
|
1 |
-
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
|
2 |
-
"""
|
3 |
-
COCO evaluator that works in distributed mode.
|
4 |
-
|
5 |
-
Mostly copy-paste from https://github.com/pytorch/vision/blob/edfd5a7/references/detection/coco_eval.py
|
6 |
-
The difference is that there is less copy-pasting from pycocotools
|
7 |
-
in the end of the file, as python3 can suppress prints with contextlib
|
8 |
-
"""
|
9 |
-
import os
|
10 |
-
import contextlib
|
11 |
-
import copy
|
12 |
-
import numpy as np
|
13 |
-
import torch
|
14 |
-
|
15 |
-
from pycocotools.cocoeval import COCOeval
|
16 |
-
from pycocotools.coco import COCO
|
17 |
-
import pycocotools.mask as mask_util
|
18 |
-
|
19 |
-
from util.misc import all_gather
|
20 |
-
|
21 |
-
|
22 |
-
class CocoEvaluator(object):
|
23 |
-
def __init__(self, coco_gt, iou_types, useCats=True):
|
24 |
-
assert isinstance(iou_types, (list, tuple))
|
25 |
-
coco_gt = copy.deepcopy(coco_gt)
|
26 |
-
self.coco_gt = coco_gt
|
27 |
-
|
28 |
-
self.iou_types = iou_types
|
29 |
-
self.coco_eval = {}
|
30 |
-
for iou_type in iou_types:
|
31 |
-
self.coco_eval[iou_type] = COCOeval(coco_gt, iouType=iou_type)
|
32 |
-
self.coco_eval[iou_type].useCats = useCats
|
33 |
-
|
34 |
-
self.img_ids = []
|
35 |
-
self.eval_imgs = {k: [] for k in iou_types}
|
36 |
-
self.useCats = useCats
|
37 |
-
|
38 |
-
def update(self, predictions):
|
39 |
-
img_ids = list(np.unique(list(predictions.keys())))
|
40 |
-
self.img_ids.extend(img_ids)
|
41 |
-
|
42 |
-
for iou_type in self.iou_types:
|
43 |
-
results = self.prepare(predictions, iou_type)
|
44 |
-
|
45 |
-
# suppress pycocotools prints
|
46 |
-
with open(os.devnull, 'w') as devnull:
|
47 |
-
with contextlib.redirect_stdout(devnull):
|
48 |
-
coco_dt = COCO.loadRes(self.coco_gt, results) if results else COCO()
|
49 |
-
coco_eval = self.coco_eval[iou_type]
|
50 |
-
|
51 |
-
coco_eval.cocoDt = coco_dt
|
52 |
-
coco_eval.params.imgIds = list(img_ids)
|
53 |
-
coco_eval.params.useCats = self.useCats
|
54 |
-
img_ids, eval_imgs = evaluate(coco_eval)
|
55 |
-
|
56 |
-
self.eval_imgs[iou_type].append(eval_imgs)
|
57 |
-
|
58 |
-
def synchronize_between_processes(self):
|
59 |
-
for iou_type in self.iou_types:
|
60 |
-
self.eval_imgs[iou_type] = np.concatenate(self.eval_imgs[iou_type], 2)
|
61 |
-
create_common_coco_eval(self.coco_eval[iou_type], self.img_ids, self.eval_imgs[iou_type])
|
62 |
-
|
63 |
-
def accumulate(self):
|
64 |
-
for coco_eval in self.coco_eval.values():
|
65 |
-
coco_eval.accumulate()
|
66 |
-
|
67 |
-
def summarize(self):
|
68 |
-
for iou_type, coco_eval in self.coco_eval.items():
|
69 |
-
print("IoU metric: {}".format(iou_type))
|
70 |
-
coco_eval.summarize()
|
71 |
-
|
72 |
-
def prepare(self, predictions, iou_type):
|
73 |
-
if iou_type == "bbox":
|
74 |
-
return self.prepare_for_coco_detection(predictions)
|
75 |
-
elif iou_type == "segm":
|
76 |
-
return self.prepare_for_coco_segmentation(predictions)
|
77 |
-
elif iou_type == "keypoints":
|
78 |
-
return self.prepare_for_coco_keypoint(predictions)
|
79 |
-
else:
|
80 |
-
raise ValueError("Unknown iou type {}".format(iou_type))
|
81 |
-
|
82 |
-
def prepare_for_coco_detection(self, predictions):
|
83 |
-
coco_results = []
|
84 |
-
for original_id, prediction in predictions.items():
|
85 |
-
if len(prediction) == 0:
|
86 |
-
continue
|
87 |
-
|
88 |
-
boxes = prediction["boxes"]
|
89 |
-
boxes = convert_to_xywh(boxes).tolist()
|
90 |
-
if not isinstance(prediction["scores"], list):
|
91 |
-
scores = prediction["scores"].tolist()
|
92 |
-
else:
|
93 |
-
scores = prediction["scores"]
|
94 |
-
if not isinstance(prediction["labels"], list):
|
95 |
-
labels = prediction["labels"].tolist()
|
96 |
-
else:
|
97 |
-
labels = prediction["labels"]
|
98 |
-
|
99 |
-
|
100 |
-
try:
|
101 |
-
coco_results.extend(
|
102 |
-
[
|
103 |
-
{
|
104 |
-
"image_id": original_id,
|
105 |
-
"category_id": labels[k],
|
106 |
-
"bbox": box,
|
107 |
-
"score": scores[k],
|
108 |
-
}
|
109 |
-
for k, box in enumerate(boxes)
|
110 |
-
]
|
111 |
-
)
|
112 |
-
except:
|
113 |
-
import ipdb; ipdb.set_trace()
|
114 |
-
return coco_results
|
115 |
-
|
116 |
-
def prepare_for_coco_segmentation(self, predictions):
|
117 |
-
coco_results = []
|
118 |
-
for original_id, prediction in predictions.items():
|
119 |
-
if len(prediction) == 0:
|
120 |
-
continue
|
121 |
-
|
122 |
-
scores = prediction["scores"]
|
123 |
-
labels = prediction["labels"]
|
124 |
-
masks = prediction["masks"]
|
125 |
-
|
126 |
-
masks = masks > 0.5
|
127 |
-
|
128 |
-
scores = prediction["scores"].tolist()
|
129 |
-
labels = prediction["labels"].tolist()
|
130 |
-
|
131 |
-
rles = [
|
132 |
-
mask_util.encode(np.array(mask[0, :, :, np.newaxis], dtype=np.uint8, order="F"))[0]
|
133 |
-
for mask in masks
|
134 |
-
]
|
135 |
-
for rle in rles:
|
136 |
-
rle["counts"] = rle["counts"].decode("utf-8")
|
137 |
-
|
138 |
-
coco_results.extend(
|
139 |
-
[
|
140 |
-
{
|
141 |
-
"image_id": original_id,
|
142 |
-
"category_id": labels[k],
|
143 |
-
"segmentation": rle,
|
144 |
-
"score": scores[k],
|
145 |
-
}
|
146 |
-
for k, rle in enumerate(rles)
|
147 |
-
]
|
148 |
-
)
|
149 |
-
return coco_results
|
150 |
-
|
151 |
-
def prepare_for_coco_keypoint(self, predictions):
|
152 |
-
coco_results = []
|
153 |
-
for original_id, prediction in predictions.items():
|
154 |
-
if len(prediction) == 0:
|
155 |
-
continue
|
156 |
-
|
157 |
-
boxes = prediction["boxes"]
|
158 |
-
boxes = convert_to_xywh(boxes).tolist()
|
159 |
-
scores = prediction["scores"].tolist()
|
160 |
-
labels = prediction["labels"].tolist()
|
161 |
-
keypoints = prediction["keypoints"]
|
162 |
-
keypoints = keypoints.flatten(start_dim=1).tolist()
|
163 |
-
|
164 |
-
coco_results.extend(
|
165 |
-
[
|
166 |
-
{
|
167 |
-
"image_id": original_id,
|
168 |
-
"category_id": labels[k],
|
169 |
-
'keypoints': keypoint,
|
170 |
-
"score": scores[k],
|
171 |
-
}
|
172 |
-
for k, keypoint in enumerate(keypoints)
|
173 |
-
]
|
174 |
-
)
|
175 |
-
return coco_results
|
176 |
-
|
177 |
-
|
178 |
-
def convert_to_xywh(boxes):
|
179 |
-
xmin, ymin, xmax, ymax = boxes.unbind(1)
|
180 |
-
return torch.stack((xmin, ymin, xmax - xmin, ymax - ymin), dim=1)
|
181 |
-
|
182 |
-
|
183 |
-
def merge(img_ids, eval_imgs):
|
184 |
-
all_img_ids = all_gather(img_ids)
|
185 |
-
all_eval_imgs = all_gather(eval_imgs)
|
186 |
-
|
187 |
-
merged_img_ids = []
|
188 |
-
for p in all_img_ids:
|
189 |
-
merged_img_ids.extend(p)
|
190 |
-
|
191 |
-
merged_eval_imgs = []
|
192 |
-
for p in all_eval_imgs:
|
193 |
-
merged_eval_imgs.append(p)
|
194 |
-
|
195 |
-
merged_img_ids = np.array(merged_img_ids)
|
196 |
-
merged_eval_imgs = np.concatenate(merged_eval_imgs, 2)
|
197 |
-
|
198 |
-
# keep only unique (and in sorted order) images
|
199 |
-
merged_img_ids, idx = np.unique(merged_img_ids, return_index=True)
|
200 |
-
merged_eval_imgs = merged_eval_imgs[..., idx]
|
201 |
-
|
202 |
-
return merged_img_ids, merged_eval_imgs
|
203 |
-
|
204 |
-
|
205 |
-
def create_common_coco_eval(coco_eval, img_ids, eval_imgs):
|
206 |
-
img_ids, eval_imgs = merge(img_ids, eval_imgs)
|
207 |
-
img_ids = list(img_ids)
|
208 |
-
eval_imgs = list(eval_imgs.flatten())
|
209 |
-
|
210 |
-
coco_eval.evalImgs = eval_imgs
|
211 |
-
coco_eval.params.imgIds = img_ids
|
212 |
-
coco_eval._paramsEval = copy.deepcopy(coco_eval.params)
|
213 |
-
|
214 |
-
|
215 |
-
#################################################################
|
216 |
-
# From pycocotools, just removed the prints and fixed
|
217 |
-
# a Python3 bug about unicode not defined
|
218 |
-
#################################################################
|
219 |
-
|
220 |
-
|
221 |
-
def evaluate(self):
|
222 |
-
'''
|
223 |
-
Run per image evaluation on given images and store results (a list of dict) in self.evalImgs
|
224 |
-
:return: None
|
225 |
-
'''
|
226 |
-
p = self.params
|
227 |
-
# add backward compatibility if useSegm is specified in params
|
228 |
-
if p.useSegm is not None:
|
229 |
-
p.iouType = 'segm' if p.useSegm == 1 else 'bbox'
|
230 |
-
print('useSegm (deprecated) is not None. Running {} evaluation'.format(p.iouType))
|
231 |
-
p.imgIds = list(np.unique(p.imgIds))
|
232 |
-
if p.useCats:
|
233 |
-
p.catIds = list(np.unique(p.catIds))
|
234 |
-
p.maxDets = sorted(p.maxDets)
|
235 |
-
self.params = p
|
236 |
-
|
237 |
-
self._prepare()
|
238 |
-
# loop through images, area range, max detection number
|
239 |
-
catIds = p.catIds if p.useCats else [-1]
|
240 |
-
|
241 |
-
if p.iouType == 'segm' or p.iouType == 'bbox':
|
242 |
-
computeIoU = self.computeIoU
|
243 |
-
elif p.iouType == 'keypoints':
|
244 |
-
computeIoU = self.computeOks
|
245 |
-
self.ious = {
|
246 |
-
(imgId, catId): computeIoU(imgId, catId)
|
247 |
-
for imgId in p.imgIds
|
248 |
-
for catId in catIds}
|
249 |
-
|
250 |
-
evaluateImg = self.evaluateImg
|
251 |
-
maxDet = p.maxDets[-1]
|
252 |
-
evalImgs = [
|
253 |
-
evaluateImg(imgId, catId, areaRng, maxDet)
|
254 |
-
for catId in catIds
|
255 |
-
for areaRng in p.areaRng
|
256 |
-
for imgId in p.imgIds
|
257 |
-
]
|
258 |
-
# this is NOT in the pycocotools code, but could be done outside
|
259 |
-
evalImgs = np.asarray(evalImgs).reshape(len(catIds), len(p.areaRng), len(p.imgIds))
|
260 |
-
self._paramsEval = copy.deepcopy(self.params)
|
261 |
-
|
262 |
-
return p.imgIds, evalImgs
|
263 |
-
|
264 |
-
#################################################################
|
265 |
-
# end of straight copy from pycocotools, just removing the prints
|
266 |
-
#################################################################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/coco_panoptic.py
DELETED
@@ -1,99 +0,0 @@
|
|
1 |
-
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
|
2 |
-
import json
|
3 |
-
from pathlib import Path
|
4 |
-
|
5 |
-
import numpy as np
|
6 |
-
import torch
|
7 |
-
from PIL import Image
|
8 |
-
|
9 |
-
from panopticapi.utils import rgb2id
|
10 |
-
from util.box_ops import masks_to_boxes
|
11 |
-
|
12 |
-
from .coco import make_coco_transforms
|
13 |
-
|
14 |
-
|
15 |
-
class CocoPanoptic:
|
16 |
-
def __init__(self, img_folder, ann_folder, ann_file, transforms=None, return_masks=True):
|
17 |
-
with open(ann_file, 'r') as f:
|
18 |
-
self.coco = json.load(f)
|
19 |
-
|
20 |
-
# sort 'images' field so that they are aligned with 'annotations'
|
21 |
-
# i.e., in alphabetical order
|
22 |
-
self.coco['images'] = sorted(self.coco['images'], key=lambda x: x['id'])
|
23 |
-
# sanity check
|
24 |
-
if "annotations" in self.coco:
|
25 |
-
for img, ann in zip(self.coco['images'], self.coco['annotations']):
|
26 |
-
assert img['file_name'][:-4] == ann['file_name'][:-4]
|
27 |
-
|
28 |
-
self.img_folder = img_folder
|
29 |
-
self.ann_folder = ann_folder
|
30 |
-
self.ann_file = ann_file
|
31 |
-
self.transforms = transforms
|
32 |
-
self.return_masks = return_masks
|
33 |
-
|
34 |
-
def __getitem__(self, idx):
|
35 |
-
ann_info = self.coco['annotations'][idx] if "annotations" in self.coco else self.coco['images'][idx]
|
36 |
-
img_path = Path(self.img_folder) / ann_info['file_name'].replace('.png', '.jpg')
|
37 |
-
ann_path = Path(self.ann_folder) / ann_info['file_name']
|
38 |
-
|
39 |
-
img = Image.open(img_path).convert('RGB')
|
40 |
-
w, h = img.size
|
41 |
-
if "segments_info" in ann_info:
|
42 |
-
masks = np.asarray(Image.open(ann_path), dtype=np.uint32)
|
43 |
-
masks = rgb2id(masks)
|
44 |
-
|
45 |
-
ids = np.array([ann['id'] for ann in ann_info['segments_info']])
|
46 |
-
masks = masks == ids[:, None, None]
|
47 |
-
|
48 |
-
masks = torch.as_tensor(masks, dtype=torch.uint8)
|
49 |
-
labels = torch.tensor([ann['category_id'] for ann in ann_info['segments_info']], dtype=torch.int64)
|
50 |
-
|
51 |
-
target = {}
|
52 |
-
target['image_id'] = torch.tensor([ann_info['image_id'] if "image_id" in ann_info else ann_info["id"]])
|
53 |
-
if self.return_masks:
|
54 |
-
target['masks'] = masks
|
55 |
-
target['labels'] = labels
|
56 |
-
|
57 |
-
target["boxes"] = masks_to_boxes(masks)
|
58 |
-
|
59 |
-
target['size'] = torch.as_tensor([int(h), int(w)])
|
60 |
-
target['orig_size'] = torch.as_tensor([int(h), int(w)])
|
61 |
-
if "segments_info" in ann_info:
|
62 |
-
for name in ['iscrowd', 'area']:
|
63 |
-
target[name] = torch.tensor([ann[name] for ann in ann_info['segments_info']])
|
64 |
-
|
65 |
-
if self.transforms is not None:
|
66 |
-
img, target = self.transforms(img, target)
|
67 |
-
|
68 |
-
return img, target
|
69 |
-
|
70 |
-
def __len__(self):
|
71 |
-
return len(self.coco['images'])
|
72 |
-
|
73 |
-
def get_height_and_width(self, idx):
|
74 |
-
img_info = self.coco['images'][idx]
|
75 |
-
height = img_info['height']
|
76 |
-
width = img_info['width']
|
77 |
-
return height, width
|
78 |
-
|
79 |
-
|
80 |
-
def build(image_set, args):
|
81 |
-
img_folder_root = Path(args.coco_path)
|
82 |
-
ann_folder_root = Path(args.coco_panoptic_path)
|
83 |
-
assert img_folder_root.exists(), f'provided COCO path {img_folder_root} does not exist'
|
84 |
-
assert ann_folder_root.exists(), f'provided COCO path {ann_folder_root} does not exist'
|
85 |
-
mode = 'panoptic'
|
86 |
-
PATHS = {
|
87 |
-
"train": ("train2017", Path("annotations") / f'{mode}_train2017.json'),
|
88 |
-
"val": ("val2017", Path("annotations") / f'{mode}_val2017.json'),
|
89 |
-
}
|
90 |
-
|
91 |
-
img_folder, ann_file = PATHS[image_set]
|
92 |
-
img_folder_path = img_folder_root / img_folder
|
93 |
-
ann_folder = ann_folder_root / f'{mode}_{img_folder}'
|
94 |
-
ann_file = ann_folder_root / ann_file
|
95 |
-
|
96 |
-
dataset = CocoPanoptic(img_folder_path, ann_folder, ann_file,
|
97 |
-
transforms=make_coco_transforms(image_set), return_masks=args.masks)
|
98 |
-
|
99 |
-
return dataset
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/data_util.py
DELETED
@@ -1,170 +0,0 @@
|
|
1 |
-
import os
|
2 |
-
import os.path as osp
|
3 |
-
import shutil
|
4 |
-
import time
|
5 |
-
import datetime
|
6 |
-
|
7 |
-
import torch
|
8 |
-
|
9 |
-
from util.slconfig import SLConfig
|
10 |
-
|
11 |
-
class Error(OSError):
|
12 |
-
pass
|
13 |
-
|
14 |
-
def slcopytree(src, dst, symlinks=False, ignore=None, copy_function=shutil.copyfile,
|
15 |
-
ignore_dangling_symlinks=False):
|
16 |
-
"""
|
17 |
-
modified from shutil.copytree without copystat.
|
18 |
-
|
19 |
-
Recursively copy a directory tree.
|
20 |
-
|
21 |
-
The destination directory must not already exist.
|
22 |
-
If exception(s) occur, an Error is raised with a list of reasons.
|
23 |
-
|
24 |
-
If the optional symlinks flag is true, symbolic links in the
|
25 |
-
source tree result in symbolic links in the destination tree; if
|
26 |
-
it is false, the contents of the files pointed to by symbolic
|
27 |
-
links are copied. If the file pointed by the symlink doesn't
|
28 |
-
exist, an exception will be added in the list of errors raised in
|
29 |
-
an Error exception at the end of the copy process.
|
30 |
-
|
31 |
-
You can set the optional ignore_dangling_symlinks flag to true if you
|
32 |
-
want to silence this exception. Notice that this has no effect on
|
33 |
-
platforms that don't support os.symlink.
|
34 |
-
|
35 |
-
The optional ignore argument is a callable. If given, it
|
36 |
-
is called with the `src` parameter, which is the directory
|
37 |
-
being visited by copytree(), and `names` which is the list of
|
38 |
-
`src` contents, as returned by os.listdir():
|
39 |
-
|
40 |
-
callable(src, names) -> ignored_names
|
41 |
-
|
42 |
-
Since copytree() is called recursively, the callable will be
|
43 |
-
called once for each directory that is copied. It returns a
|
44 |
-
list of names relative to the `src` directory that should
|
45 |
-
not be copied.
|
46 |
-
|
47 |
-
The optional copy_function argument is a callable that will be used
|
48 |
-
to copy each file. It will be called with the source path and the
|
49 |
-
destination path as arguments. By default, copy2() is used, but any
|
50 |
-
function that supports the same signature (like copy()) can be used.
|
51 |
-
|
52 |
-
"""
|
53 |
-
errors = []
|
54 |
-
if os.path.isdir(src):
|
55 |
-
names = os.listdir(src)
|
56 |
-
if ignore is not None:
|
57 |
-
ignored_names = ignore(src, names)
|
58 |
-
else:
|
59 |
-
ignored_names = set()
|
60 |
-
|
61 |
-
os.makedirs(dst)
|
62 |
-
for name in names:
|
63 |
-
if name in ignored_names:
|
64 |
-
continue
|
65 |
-
srcname = os.path.join(src, name)
|
66 |
-
dstname = os.path.join(dst, name)
|
67 |
-
try:
|
68 |
-
if os.path.islink(srcname):
|
69 |
-
linkto = os.readlink(srcname)
|
70 |
-
if symlinks:
|
71 |
-
# We can't just leave it to `copy_function` because legacy
|
72 |
-
# code with a custom `copy_function` may rely on copytree
|
73 |
-
# doing the right thing.
|
74 |
-
os.symlink(linkto, dstname)
|
75 |
-
else:
|
76 |
-
# ignore dangling symlink if the flag is on
|
77 |
-
if not os.path.exists(linkto) and ignore_dangling_symlinks:
|
78 |
-
continue
|
79 |
-
# otherwise let the copy occurs. copy2 will raise an error
|
80 |
-
if os.path.isdir(srcname):
|
81 |
-
slcopytree(srcname, dstname, symlinks, ignore,
|
82 |
-
copy_function)
|
83 |
-
else:
|
84 |
-
copy_function(srcname, dstname)
|
85 |
-
elif os.path.isdir(srcname):
|
86 |
-
slcopytree(srcname, dstname, symlinks, ignore, copy_function)
|
87 |
-
else:
|
88 |
-
# Will raise a SpecialFileError for unsupported file types
|
89 |
-
copy_function(srcname, dstname)
|
90 |
-
# catch the Error from the recursive copytree so that we can
|
91 |
-
# continue with other files
|
92 |
-
except Error as err:
|
93 |
-
errors.extend(err.args[0])
|
94 |
-
except OSError as why:
|
95 |
-
errors.append((srcname, dstname, str(why)))
|
96 |
-
else:
|
97 |
-
copy_function(src, dst)
|
98 |
-
|
99 |
-
if errors:
|
100 |
-
raise Error(errors)
|
101 |
-
return dst
|
102 |
-
|
103 |
-
def check_and_copy(src_path, tgt_path):
|
104 |
-
if os.path.exists(tgt_path):
|
105 |
-
return None
|
106 |
-
|
107 |
-
return slcopytree(src_path, tgt_path)
|
108 |
-
|
109 |
-
|
110 |
-
def remove(srcpath):
|
111 |
-
if os.path.isdir(srcpath):
|
112 |
-
return shutil.rmtree(srcpath)
|
113 |
-
else:
|
114 |
-
return os.remove(srcpath)
|
115 |
-
|
116 |
-
|
117 |
-
def preparing_dataset(pathdict, image_set, args):
|
118 |
-
start_time = time.time()
|
119 |
-
dataset_file = args.dataset_file
|
120 |
-
data_static_info = SLConfig.fromfile('util/static_data_path.py')
|
121 |
-
static_dict = data_static_info[dataset_file][image_set]
|
122 |
-
|
123 |
-
copyfilelist = []
|
124 |
-
for k,tgt_v in pathdict.items():
|
125 |
-
if os.path.exists(tgt_v):
|
126 |
-
if args.local_rank == 0:
|
127 |
-
print("path <{}> exist. remove it!".format(tgt_v))
|
128 |
-
remove(tgt_v)
|
129 |
-
# continue
|
130 |
-
|
131 |
-
if args.local_rank == 0:
|
132 |
-
src_v = static_dict[k]
|
133 |
-
assert isinstance(src_v, str)
|
134 |
-
if src_v.endswith('.zip'):
|
135 |
-
# copy
|
136 |
-
cp_tgt_dir = os.path.dirname(tgt_v)
|
137 |
-
filename = os.path.basename(src_v)
|
138 |
-
cp_tgt_path = os.path.join(cp_tgt_dir, filename)
|
139 |
-
print('Copy from <{}> to <{}>.'.format(src_v, cp_tgt_path))
|
140 |
-
os.makedirs(cp_tgt_dir, exist_ok=True)
|
141 |
-
check_and_copy(src_v, cp_tgt_path)
|
142 |
-
|
143 |
-
# unzip
|
144 |
-
import zipfile
|
145 |
-
print("Starting unzip <{}>".format(cp_tgt_path))
|
146 |
-
with zipfile.ZipFile(cp_tgt_path, 'r') as zip_ref:
|
147 |
-
zip_ref.extractall(os.path.dirname(cp_tgt_path))
|
148 |
-
|
149 |
-
copyfilelist.append(cp_tgt_path)
|
150 |
-
copyfilelist.append(tgt_v)
|
151 |
-
else:
|
152 |
-
print('Copy from <{}> to <{}>.'.format(src_v, tgt_v))
|
153 |
-
os.makedirs(os.path.dirname(tgt_v), exist_ok=True)
|
154 |
-
check_and_copy(src_v, tgt_v)
|
155 |
-
copyfilelist.append(tgt_v)
|
156 |
-
|
157 |
-
if len(copyfilelist) == 0:
|
158 |
-
copyfilelist = None
|
159 |
-
args.copyfilelist = copyfilelist
|
160 |
-
|
161 |
-
if args.distributed:
|
162 |
-
torch.distributed.barrier()
|
163 |
-
total_time = time.time() - start_time
|
164 |
-
if copyfilelist:
|
165 |
-
total_time_str = str(datetime.timedelta(seconds=int(total_time)))
|
166 |
-
print('Data copy time {}'.format(total_time_str))
|
167 |
-
return copyfilelist
|
168 |
-
|
169 |
-
|
170 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/dataset.py
DELETED
@@ -1,44 +0,0 @@
|
|
1 |
-
from __future__ import print_function
|
2 |
-
|
3 |
-
import torch
|
4 |
-
import torchvision.datasets as datasets
|
5 |
-
from torch.utils.data import Dataset
|
6 |
-
from PIL import Image
|
7 |
-
from .tsv_io import TSVFile
|
8 |
-
import numpy as np
|
9 |
-
import base64
|
10 |
-
import io
|
11 |
-
|
12 |
-
|
13 |
-
class TSVDataset(Dataset):
|
14 |
-
""" TSV dataset for ImageNet 1K training
|
15 |
-
"""
|
16 |
-
def __init__(self, tsv_file, transform=None, target_transform=None):
|
17 |
-
self.tsv = TSVFile(tsv_file)
|
18 |
-
self.transform = transform
|
19 |
-
self.target_transform = target_transform
|
20 |
-
|
21 |
-
def __getitem__(self, index):
|
22 |
-
"""
|
23 |
-
Args:
|
24 |
-
index (int): Index
|
25 |
-
Returns:
|
26 |
-
tuple: (image, target) where target is class_index of the target class.
|
27 |
-
"""
|
28 |
-
row = self.tsv.seek(index)
|
29 |
-
image_data = base64.b64decode(row[-1])
|
30 |
-
image = Image.open(io.BytesIO(image_data))
|
31 |
-
image = image.convert('RGB')
|
32 |
-
target = int(row[1])
|
33 |
-
|
34 |
-
if self.transform is not None:
|
35 |
-
img = self.transform(image)
|
36 |
-
else:
|
37 |
-
img = image
|
38 |
-
if self.target_transform is not None:
|
39 |
-
target = self.target_transform(target)
|
40 |
-
|
41 |
-
return img, target
|
42 |
-
|
43 |
-
def __len__(self):
|
44 |
-
return self.tsv.num_rows()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/odvg.py
DELETED
@@ -1,258 +0,0 @@
|
|
1 |
-
from torchvision.datasets.vision import VisionDataset
|
2 |
-
import os.path
|
3 |
-
from typing import Callable, Optional
|
4 |
-
import json
|
5 |
-
from PIL import Image
|
6 |
-
import torch
|
7 |
-
import random
|
8 |
-
import os, sys
|
9 |
-
sys.path.append(os.path.dirname(sys.path[0]))
|
10 |
-
|
11 |
-
import datasets.transforms as T
|
12 |
-
|
13 |
-
class ODVGDataset(VisionDataset):
|
14 |
-
"""
|
15 |
-
Args:
|
16 |
-
root (string): Root directory where images are downloaded to.
|
17 |
-
anno (string): Path to json annotation file.
|
18 |
-
label_map_anno (string): Path to json label mapping file. Only for Object Detection
|
19 |
-
transform (callable, optional): A function/transform that takes in an PIL image
|
20 |
-
and returns a transformed version. E.g, ``transforms.PILToTensor``
|
21 |
-
target_transform (callable, optional): A function/transform that takes in the
|
22 |
-
target and transforms it.
|
23 |
-
transforms (callable, optional): A function/transform that takes input sample and its target as entry
|
24 |
-
and returns a transformed version.
|
25 |
-
"""
|
26 |
-
|
27 |
-
def __init__(
|
28 |
-
self,
|
29 |
-
root: str,
|
30 |
-
anno: str,
|
31 |
-
label_map_anno: str = None,
|
32 |
-
max_labels: int = 80,
|
33 |
-
transform: Optional[Callable] = None,
|
34 |
-
target_transform: Optional[Callable] = None,
|
35 |
-
transforms: Optional[Callable] = None,
|
36 |
-
) -> None:
|
37 |
-
super().__init__(root, transforms, transform, target_transform)
|
38 |
-
self.root = root
|
39 |
-
self.dataset_mode = "OD" if label_map_anno else "VG"
|
40 |
-
self.max_labels = max_labels
|
41 |
-
if self.dataset_mode == "OD":
|
42 |
-
self.load_label_map(label_map_anno)
|
43 |
-
self._load_metas(anno)
|
44 |
-
self.get_dataset_info()
|
45 |
-
|
46 |
-
def load_label_map(self, label_map_anno):
|
47 |
-
with open(label_map_anno, 'r') as file:
|
48 |
-
self.label_map = json.load(file)
|
49 |
-
self.label_index = set(self.label_map.keys())
|
50 |
-
|
51 |
-
def _load_metas(self, anno):
|
52 |
-
with open(anno, 'r') as f:
|
53 |
-
self.metas = json.load(f)
|
54 |
-
|
55 |
-
|
56 |
-
def get_dataset_info(self):
|
57 |
-
print(f" == total images: {len(self)}")
|
58 |
-
if self.dataset_mode == "OD":
|
59 |
-
print(f" == total labels: {len(self.label_map)}")
|
60 |
-
|
61 |
-
def __getitem__(self, index: int):
|
62 |
-
meta = self.metas[index]
|
63 |
-
rel_path = meta["filename"]
|
64 |
-
abs_path = os.path.join(self.root, rel_path)
|
65 |
-
if not os.path.exists(abs_path):
|
66 |
-
raise FileNotFoundError(f"{abs_path} not found.")
|
67 |
-
image = Image.open(abs_path).convert('RGB')
|
68 |
-
w, h = image.size
|
69 |
-
if self.dataset_mode == "OD":
|
70 |
-
anno = meta["detection"]
|
71 |
-
instances = [obj for obj in anno["instances"]]
|
72 |
-
boxes = [obj["bbox"] for obj in instances]
|
73 |
-
# generate vg_labels
|
74 |
-
# pos bbox labels
|
75 |
-
ori_classes = [str(obj["label"]) for obj in instances]
|
76 |
-
pos_labels = set(ori_classes)
|
77 |
-
# neg bbox labels
|
78 |
-
neg_labels = self.label_index.difference(pos_labels)
|
79 |
-
|
80 |
-
vg_labels = list(pos_labels)
|
81 |
-
num_to_add = min(len(neg_labels), self.max_labels-len(pos_labels))
|
82 |
-
if num_to_add > 0:
|
83 |
-
vg_labels.extend(random.sample(neg_labels, num_to_add))
|
84 |
-
|
85 |
-
# shuffle
|
86 |
-
for i in range(len(vg_labels)-1, 0, -1):
|
87 |
-
j = random.randint(0, i)
|
88 |
-
vg_labels[i], vg_labels[j] = vg_labels[j], vg_labels[i]
|
89 |
-
|
90 |
-
caption_list = [self.label_map[lb] for lb in vg_labels]
|
91 |
-
caption_dict = {item:index for index, item in enumerate(caption_list)}
|
92 |
-
|
93 |
-
caption = ' . '.join(caption_list) + ' .'
|
94 |
-
classes = [caption_dict[self.label_map[str(obj["label"])]] for obj in instances]
|
95 |
-
boxes = torch.as_tensor(boxes, dtype=torch.float32).reshape(-1, 4)
|
96 |
-
classes = torch.tensor(classes, dtype=torch.int64)
|
97 |
-
elif self.dataset_mode == "VG":
|
98 |
-
anno = meta["Grounding"]
|
99 |
-
instances = [obj for obj in anno["regions"]]
|
100 |
-
boxes = [obj["bbox"] for obj in instances]
|
101 |
-
caption_list = [obj["phrase"] for obj in instances]
|
102 |
-
c = list(zip(boxes, caption_list))
|
103 |
-
random.shuffle(c)
|
104 |
-
boxes[:], caption_list[:] = zip(*c)
|
105 |
-
uni_caption_list = list(set(caption_list))
|
106 |
-
label_map = {}
|
107 |
-
for idx in range(len(uni_caption_list)):
|
108 |
-
label_map[uni_caption_list[idx]] = idx
|
109 |
-
classes = [label_map[cap] for cap in caption_list]
|
110 |
-
caption = ' . '.join(uni_caption_list) + ' .'
|
111 |
-
boxes = torch.as_tensor(boxes, dtype=torch.float32).reshape(-1, 4)
|
112 |
-
classes = torch.tensor(classes, dtype=torch.int64)
|
113 |
-
caption_list = uni_caption_list
|
114 |
-
# print("caption_list" , caption_list)
|
115 |
-
# print("caption" , caption)
|
116 |
-
# print("boxes" , boxes)
|
117 |
-
target = {}
|
118 |
-
target["image_id"] = rel_path.strip(".jpg")
|
119 |
-
target["size"] = torch.as_tensor([int(h), int(w)])
|
120 |
-
target["cap_list"] = caption_list
|
121 |
-
target["caption"] = caption
|
122 |
-
target["boxes"] = boxes
|
123 |
-
target["labels"] = classes
|
124 |
-
# print(" image_id " , target["image_id"])
|
125 |
-
# size, cap_list, caption, bboxes, labels
|
126 |
-
|
127 |
-
if self.transforms is not None:
|
128 |
-
image, target = self.transforms(image, target)
|
129 |
-
|
130 |
-
return image, target
|
131 |
-
|
132 |
-
|
133 |
-
def __len__(self) -> int:
|
134 |
-
return len(self.metas)
|
135 |
-
|
136 |
-
|
137 |
-
def make_coco_transforms(image_set, fix_size=False, strong_aug=False, args=None):
|
138 |
-
|
139 |
-
normalize = T.Compose([
|
140 |
-
T.ToTensor(),
|
141 |
-
T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
|
142 |
-
])
|
143 |
-
|
144 |
-
# config the params for data aug
|
145 |
-
scales = [480, 512, 544, 576, 608, 640, 672, 704, 736, 768, 800]
|
146 |
-
max_size = 1333
|
147 |
-
scales2_resize = [400, 500, 600]
|
148 |
-
scales2_crop = [384, 600]
|
149 |
-
|
150 |
-
# update args from config files
|
151 |
-
scales = getattr(args, 'data_aug_scales', scales)
|
152 |
-
max_size = getattr(args, 'data_aug_max_size', max_size)
|
153 |
-
scales2_resize = getattr(args, 'data_aug_scales2_resize', scales2_resize)
|
154 |
-
scales2_crop = getattr(args, 'data_aug_scales2_crop', scales2_crop)
|
155 |
-
|
156 |
-
# resize them
|
157 |
-
data_aug_scale_overlap = getattr(args, 'data_aug_scale_overlap', None)
|
158 |
-
if data_aug_scale_overlap is not None and data_aug_scale_overlap > 0:
|
159 |
-
data_aug_scale_overlap = float(data_aug_scale_overlap)
|
160 |
-
scales = [int(i*data_aug_scale_overlap) for i in scales]
|
161 |
-
max_size = int(max_size*data_aug_scale_overlap)
|
162 |
-
scales2_resize = [int(i*data_aug_scale_overlap) for i in scales2_resize]
|
163 |
-
scales2_crop = [int(i*data_aug_scale_overlap) for i in scales2_crop]
|
164 |
-
|
165 |
-
# datadict_for_print = {
|
166 |
-
# 'scales': scales,
|
167 |
-
# 'max_size': max_size,
|
168 |
-
# 'scales2_resize': scales2_resize,
|
169 |
-
# 'scales2_crop': scales2_crop
|
170 |
-
# }
|
171 |
-
# print("data_aug_params:", json.dumps(datadict_for_print, indent=2))
|
172 |
-
|
173 |
-
if image_set == 'train':
|
174 |
-
if fix_size:
|
175 |
-
return T.Compose([
|
176 |
-
T.RandomHorizontalFlip(),
|
177 |
-
T.RandomResize([(max_size, max(scales))]),
|
178 |
-
normalize,
|
179 |
-
])
|
180 |
-
|
181 |
-
if strong_aug:
|
182 |
-
import datasets.sltransform as SLT
|
183 |
-
|
184 |
-
return T.Compose([
|
185 |
-
T.RandomHorizontalFlip(),
|
186 |
-
T.RandomSelect(
|
187 |
-
T.RandomResize(scales, max_size=max_size),
|
188 |
-
T.Compose([
|
189 |
-
T.RandomResize(scales2_resize),
|
190 |
-
T.RandomSizeCrop(*scales2_crop),
|
191 |
-
T.RandomResize(scales, max_size=max_size),
|
192 |
-
])
|
193 |
-
),
|
194 |
-
SLT.RandomSelectMulti([
|
195 |
-
SLT.RandomCrop(),
|
196 |
-
SLT.LightingNoise(),
|
197 |
-
SLT.AdjustBrightness(2),
|
198 |
-
SLT.AdjustContrast(2),
|
199 |
-
]),
|
200 |
-
normalize,
|
201 |
-
])
|
202 |
-
|
203 |
-
return T.Compose([
|
204 |
-
T.RandomHorizontalFlip(),
|
205 |
-
T.RandomSelect(
|
206 |
-
T.RandomResize(scales, max_size=max_size),
|
207 |
-
T.Compose([
|
208 |
-
T.RandomResize(scales2_resize),
|
209 |
-
T.RandomSizeCrop(*scales2_crop),
|
210 |
-
T.RandomResize(scales, max_size=max_size),
|
211 |
-
])
|
212 |
-
),
|
213 |
-
normalize,
|
214 |
-
])
|
215 |
-
|
216 |
-
if image_set in ['val', 'eval_debug', 'train_reg', 'test']:
|
217 |
-
|
218 |
-
if os.environ.get("GFLOPS_DEBUG_SHILONG", False) == 'INFO':
|
219 |
-
print("Under debug mode for flops calculation only!!!!!!!!!!!!!!!!")
|
220 |
-
return T.Compose([
|
221 |
-
T.ResizeDebug((1280, 800)),
|
222 |
-
normalize,
|
223 |
-
])
|
224 |
-
|
225 |
-
return T.Compose([
|
226 |
-
T.RandomResize([max(scales)], max_size=max_size),
|
227 |
-
normalize,
|
228 |
-
])
|
229 |
-
|
230 |
-
raise ValueError(f'unknown {image_set}')
|
231 |
-
|
232 |
-
def build_odvg(image_set, args, datasetinfo):
|
233 |
-
img_folder = datasetinfo["root"]
|
234 |
-
ann_file = datasetinfo["anno"]
|
235 |
-
label_map = datasetinfo["label_map"] if "label_map" in datasetinfo else None
|
236 |
-
try:
|
237 |
-
strong_aug = args.strong_aug
|
238 |
-
except:
|
239 |
-
strong_aug = False # False originally
|
240 |
-
print(img_folder, ann_file, label_map)
|
241 |
-
dataset = ODVGDataset(img_folder, ann_file, label_map, max_labels=args.max_labels,
|
242 |
-
transforms=make_coco_transforms(image_set, fix_size=args.fix_size, strong_aug=strong_aug, args=args),
|
243 |
-
)
|
244 |
-
return dataset
|
245 |
-
|
246 |
-
|
247 |
-
if __name__=="__main__":
|
248 |
-
dataset_vg = ODVGDataset("path/GRIT-20M/data/","path/GRIT-20M/anno/grit_odvg_10k.jsonl",)
|
249 |
-
print(len(dataset_vg))
|
250 |
-
data = dataset_vg[random.randint(0, 100)]
|
251 |
-
print(data)
|
252 |
-
dataset_od = ODVGDataset("pathl/V3Det/",
|
253 |
-
"path/V3Det/annotations/v3det_2023_v1_all_odvg.jsonl",
|
254 |
-
"path/V3Det/annotations/v3det_label_map.json",
|
255 |
-
)
|
256 |
-
print(len(dataset_od))
|
257 |
-
data = dataset_od[random.randint(0, 100)]
|
258 |
-
print(data)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/panoptic_eval.py
DELETED
@@ -1,44 +0,0 @@
|
|
1 |
-
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
|
2 |
-
import json
|
3 |
-
import os
|
4 |
-
|
5 |
-
import util.misc as utils
|
6 |
-
|
7 |
-
try:
|
8 |
-
from panopticapi.evaluation import pq_compute
|
9 |
-
except ImportError:
|
10 |
-
pass
|
11 |
-
|
12 |
-
|
13 |
-
class PanopticEvaluator(object):
|
14 |
-
def __init__(self, ann_file, ann_folder, output_dir="panoptic_eval"):
|
15 |
-
self.gt_json = ann_file
|
16 |
-
self.gt_folder = ann_folder
|
17 |
-
if utils.is_main_process():
|
18 |
-
if not os.path.exists(output_dir):
|
19 |
-
os.mkdir(output_dir)
|
20 |
-
self.output_dir = output_dir
|
21 |
-
self.predictions = []
|
22 |
-
|
23 |
-
def update(self, predictions):
|
24 |
-
for p in predictions:
|
25 |
-
with open(os.path.join(self.output_dir, p["file_name"]), "wb") as f:
|
26 |
-
f.write(p.pop("png_string"))
|
27 |
-
|
28 |
-
self.predictions += predictions
|
29 |
-
|
30 |
-
def synchronize_between_processes(self):
|
31 |
-
all_predictions = utils.all_gather(self.predictions)
|
32 |
-
merged_predictions = []
|
33 |
-
for p in all_predictions:
|
34 |
-
merged_predictions += p
|
35 |
-
self.predictions = merged_predictions
|
36 |
-
|
37 |
-
def summarize(self):
|
38 |
-
if utils.is_main_process():
|
39 |
-
json_data = {"annotations": self.predictions}
|
40 |
-
predictions_json = os.path.join(self.output_dir, "predictions.json")
|
41 |
-
with open(predictions_json, "w") as f:
|
42 |
-
f.write(json.dumps(json_data))
|
43 |
-
return pq_compute(self.gt_json, predictions_json, gt_folder=self.gt_folder, pred_folder=self.output_dir)
|
44 |
-
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/random_crop.py
DELETED
@@ -1,135 +0,0 @@
|
|
1 |
-
import PIL #version 1.2.0
|
2 |
-
import torch
|
3 |
-
import os
|
4 |
-
import torchvision.transforms.functional as F
|
5 |
-
import numpy as np
|
6 |
-
import random
|
7 |
-
|
8 |
-
|
9 |
-
def intersect(boxes1, boxes2):
|
10 |
-
'''
|
11 |
-
Find intersection of every box combination between two sets of box
|
12 |
-
boxes1: bounding boxes 1, a tensor of dimensions (n1, 4)
|
13 |
-
boxes2: bounding boxes 2, a tensor of dimensions (n2, 4)
|
14 |
-
|
15 |
-
Out: Intersection each of boxes1 with respect to each of boxes2,
|
16 |
-
a tensor of dimensions (n1, n2)
|
17 |
-
'''
|
18 |
-
n1 = boxes1.size(0)
|
19 |
-
n2 = boxes2.size(0)
|
20 |
-
max_xy = torch.min(boxes1[:, 2:].unsqueeze(1).expand(n1, n2, 2),
|
21 |
-
boxes2[:, 2:].unsqueeze(0).expand(n1, n2, 2))
|
22 |
-
|
23 |
-
min_xy = torch.max(boxes1[:, :2].unsqueeze(1).expand(n1, n2, 2),
|
24 |
-
boxes2[:, :2].unsqueeze(0).expand(n1, n2, 2))
|
25 |
-
inter = torch.clamp(max_xy - min_xy , min=0) # (n1, n2, 2)
|
26 |
-
return inter[:, :, 0] * inter[:, :, 1] #(n1, n2)
|
27 |
-
def find_IoU(boxes1, boxes2):
|
28 |
-
'''
|
29 |
-
Find IoU between every boxes set of boxes
|
30 |
-
boxes1: a tensor of dimensions (n1, 4) (left, top, right , bottom)
|
31 |
-
boxes2: a tensor of dimensions (n2, 4)
|
32 |
-
|
33 |
-
Out: IoU each of boxes1 with respect to each of boxes2, a tensor of
|
34 |
-
dimensions (n1, n2)
|
35 |
-
|
36 |
-
Formula:
|
37 |
-
(box1 ∩ box2) / (box1 u box2) = (box1 ∩ box2) / (area(box1) + area(box2) - (box1 ∩ box2 ))
|
38 |
-
'''
|
39 |
-
inter = intersect(boxes1, boxes2)
|
40 |
-
area_boxes1 = (boxes1[:, 2] - boxes1[:, 0]) * (boxes1[:, 3] - boxes1[:, 1])
|
41 |
-
area_boxes2 = (boxes2[:, 2] - boxes2[:, 0]) * (boxes2[:, 3] - boxes2[:, 1])
|
42 |
-
|
43 |
-
area_boxes1 = area_boxes1.unsqueeze(1).expand_as(inter) #(n1, n2)
|
44 |
-
area_boxes2 = area_boxes2.unsqueeze(0).expand_as(inter) #(n1, n2)
|
45 |
-
union = (area_boxes1 + area_boxes2 - inter)
|
46 |
-
return inter / union
|
47 |
-
|
48 |
-
|
49 |
-
def random_crop(image, boxes, labels, difficulties=None):
|
50 |
-
'''
|
51 |
-
image: A PIL image
|
52 |
-
boxes: Bounding boxes, a tensor of dimensions (#objects, 4)
|
53 |
-
labels: labels of object, a tensor of dimensions (#objects)
|
54 |
-
difficulties: difficulties of detect object, a tensor of dimensions (#objects)
|
55 |
-
|
56 |
-
Out: cropped image , new boxes, new labels, new difficulties
|
57 |
-
'''
|
58 |
-
if type(image) == PIL.Image.Image:
|
59 |
-
image = F.to_tensor(image)
|
60 |
-
original_h = image.size(1)
|
61 |
-
original_w = image.size(2)
|
62 |
-
|
63 |
-
while True:
|
64 |
-
mode = random.choice([0.1, 0.3, 0.5, 0.9, None])
|
65 |
-
|
66 |
-
if mode is None:
|
67 |
-
return F.to_pil_image(image), boxes, labels, difficulties
|
68 |
-
|
69 |
-
new_image = image
|
70 |
-
new_boxes = boxes
|
71 |
-
new_difficulties = difficulties
|
72 |
-
new_labels = labels
|
73 |
-
for _ in range(50):
|
74 |
-
# Crop dimensions: [0.3, 1] of original dimensions
|
75 |
-
new_h = random.uniform(0.3*original_h, original_h)
|
76 |
-
new_w = random.uniform(0.3*original_w, original_w)
|
77 |
-
|
78 |
-
# Aspect ratio constraint b/t .5 & 2
|
79 |
-
if new_h/new_w < 0.5 or new_h/new_w > 2:
|
80 |
-
continue
|
81 |
-
|
82 |
-
#Crop coordinate
|
83 |
-
left = random.uniform(0, original_w - new_w)
|
84 |
-
right = left + new_w
|
85 |
-
top = random.uniform(0, original_h - new_h)
|
86 |
-
bottom = top + new_h
|
87 |
-
crop = torch.FloatTensor([int(left), int(top), int(right), int(bottom)])
|
88 |
-
|
89 |
-
# Calculate IoU between the crop and the bounding boxes
|
90 |
-
overlap = find_IoU(crop.unsqueeze(0), boxes) #(1, #objects)
|
91 |
-
overlap = overlap.squeeze(0)
|
92 |
-
|
93 |
-
# If not a single bounding box has a IoU of greater than the minimum, try again
|
94 |
-
if overlap.shape[0] == 0:
|
95 |
-
continue
|
96 |
-
if overlap.max().item() < mode:
|
97 |
-
continue
|
98 |
-
|
99 |
-
#Crop
|
100 |
-
new_image = image[:, int(top):int(bottom), int(left):int(right)] #(3, new_h, new_w)
|
101 |
-
|
102 |
-
#Center of bounding boxes
|
103 |
-
center_bb = (boxes[:, :2] + boxes[:, 2:])/2.0
|
104 |
-
|
105 |
-
#Find bounding box has been had center in crop
|
106 |
-
center_in_crop = (center_bb[:, 0] >left) * (center_bb[:, 0] < right
|
107 |
-
) *(center_bb[:, 1] > top) * (center_bb[:, 1] < bottom) #( #objects)
|
108 |
-
|
109 |
-
if not center_in_crop.any():
|
110 |
-
continue
|
111 |
-
|
112 |
-
#take matching bounding box
|
113 |
-
new_boxes = boxes[center_in_crop, :]
|
114 |
-
|
115 |
-
#take matching labels
|
116 |
-
new_labels = labels[center_in_crop]
|
117 |
-
|
118 |
-
#take matching difficulities
|
119 |
-
if difficulties is not None:
|
120 |
-
new_difficulties = difficulties[center_in_crop]
|
121 |
-
else:
|
122 |
-
new_difficulties = None
|
123 |
-
|
124 |
-
#Use the box left and top corner or the crop's
|
125 |
-
new_boxes[:, :2] = torch.max(new_boxes[:, :2], crop[:2])
|
126 |
-
|
127 |
-
#adjust to crop
|
128 |
-
new_boxes[:, :2] -= crop[:2]
|
129 |
-
|
130 |
-
new_boxes[:, 2:] = torch.min(new_boxes[:, 2:],crop[2:])
|
131 |
-
|
132 |
-
#adjust to crop
|
133 |
-
new_boxes[:, 2:] -= crop[:2]
|
134 |
-
|
135 |
-
return F.to_pil_image(new_image), new_boxes, new_labels, new_difficulties
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
datasets/sltransform.py
DELETED
@@ -1,247 +0,0 @@
|
|
1 |
-
# modified from https://github.com/anhtuan85/Data-Augmentation-for-Object-Detection/blob/master/augmentation.ipynb
|
2 |
-
|
3 |
-
import PIL #version 1.2.0
|
4 |
-
from PIL import Image #version 6.1.0
|
5 |
-
import torch
|
6 |
-
import os
|
7 |
-
import torchvision.transforms.functional as F
|
8 |
-
import numpy as np
|
9 |
-
import random
|
10 |
-
|
11 |
-
from .random_crop import random_crop
|
12 |
-
from util.box_ops import box_cxcywh_to_xyxy, box_xyxy_to_cxcywh
|
13 |
-
|
14 |
-
class AdjustContrast:
|
15 |
-
def __init__(self, contrast_factor):
|
16 |
-
self.contrast_factor = contrast_factor
|
17 |
-
|
18 |
-
def __call__(self, img, target):
|
19 |
-
"""
|
20 |
-
img (PIL Image or Tensor): Image to be adjusted.
|
21 |
-
"""
|
22 |
-
_contrast_factor = ((random.random() + 1.0) / 2.0) * self.contrast_factor
|
23 |
-
img = F.adjust_contrast(img, _contrast_factor)
|
24 |
-
return img, target
|
25 |
-
|
26 |
-
class AdjustBrightness:
|
27 |
-
def __init__(self, brightness_factor):
|
28 |
-
self.brightness_factor = brightness_factor
|
29 |
-
|
30 |
-
def __call__(self, img, target):
|
31 |
-
"""
|
32 |
-
img (PIL Image or Tensor): Image to be adjusted.
|
33 |
-
"""
|
34 |
-
_brightness_factor = ((random.random() + 1.0) / 2.0) * self.brightness_factor
|
35 |
-
img = F.adjust_brightness(img, _brightness_factor)
|
36 |
-
return img, target
|
37 |
-
|
38 |
-
def lighting_noise(image):
|
39 |
-
'''
|
40 |
-
color channel swap in image
|
41 |
-
image: A PIL image
|
42 |
-
'''
|
43 |
-
new_image = image
|
44 |
-
perms = ((0, 1, 2), (0, 2, 1), (1, 0, 2),
|
45 |
-
(1, 2, 0), (2, 0, 1), (2, 1, 0))
|
46 |
-
swap = perms[random.randint(0, len(perms)- 1)]
|
47 |
-
new_image = F.to_tensor(new_image)
|
48 |
-
new_image = new_image[swap, :, :]
|
49 |
-
new_image = F.to_pil_image(new_image)
|
50 |
-
return new_image
|
51 |
-
|
52 |
-
class LightingNoise:
|
53 |
-
def __init__(self) -> None:
|
54 |
-
pass
|
55 |
-
|
56 |
-
def __call__(self, img, target):
|
57 |
-
return lighting_noise(img), target
|
58 |
-
|
59 |
-
|
60 |
-
def rotate(image, boxes, angle):
|
61 |
-
'''
|
62 |
-
Rotate image and bounding box
|
63 |
-
image: A Pil image (w, h)
|
64 |
-
boxes: A tensors of dimensions (#objects, 4)
|
65 |
-
|
66 |
-
Out: rotated image (w, h), rotated boxes
|
67 |
-
'''
|
68 |
-
new_image = image.copy()
|
69 |
-
new_boxes = boxes.clone()
|
70 |
-
|
71 |
-
#Rotate image, expand = True
|
72 |
-
w = image.width
|
73 |
-
h = image.height
|
74 |
-
cx = w/2
|
75 |
-
cy = h/2
|
76 |
-
new_image = new_image.rotate(angle, expand=True)
|
77 |
-
angle = np.radians(angle)
|
78 |
-
alpha = np.cos(angle)
|
79 |
-
beta = np.sin(angle)
|
80 |
-
#Get affine matrix
|
81 |
-
AffineMatrix = torch.tensor([[alpha, beta, (1-alpha)*cx - beta*cy],
|
82 |
-
[-beta, alpha, beta*cx + (1-alpha)*cy]])
|
83 |
-
|
84 |
-
#Rotation boxes
|
85 |
-
box_width = (boxes[:,2] - boxes[:,0]).reshape(-1,1)
|
86 |
-
box_height = (boxes[:,3] - boxes[:,1]).reshape(-1,1)
|
87 |
-
|
88 |
-
#Get corners for boxes
|
89 |
-
x1 = boxes[:,0].reshape(-1,1)
|
90 |
-
y1 = boxes[:,1].reshape(-1,1)
|
91 |
-
|
92 |
-
x2 = x1 + box_width
|
93 |
-
y2 = y1
|
94 |
-
|
95 |
-
x3 = x1
|
96 |
-
y3 = y1 + box_height
|
97 |
-
|
98 |
-
x4 = boxes[:,2].reshape(-1,1)
|
99 |
-
y4 = boxes[:,3].reshape(-1,1)
|
100 |
-
|
101 |
-
corners = torch.stack((x1,y1,x2,y2,x3,y3,x4,y4), dim= 1)
|
102 |
-
# corners.reshape(-1, 8) #Tensors of dimensions (#objects, 8)
|
103 |
-
corners = corners.reshape(-1,2) #Tensors of dimension (4* #objects, 2)
|
104 |
-
corners = torch.cat((corners, torch.ones(corners.shape[0], 1)), dim= 1) #(Tensors of dimension (4* #objects, 3))
|
105 |
-
|
106 |
-
cos = np.abs(AffineMatrix[0, 0])
|
107 |
-
sin = np.abs(AffineMatrix[0, 1])
|
108 |
-
|
109 |
-
nW = int((h * sin) + (w * cos))
|
110 |
-
nH = int((h * cos) + (w * sin))
|
111 |
-
AffineMatrix[0, 2] += (nW / 2) - cx
|
112 |
-
AffineMatrix[1, 2] += (nH / 2) - cy
|
113 |
-
|
114 |
-
|
115 |
-
#Apply affine transform
|
116 |
-
rotate_corners = torch.mm(AffineMatrix, corners.t().to(torch.float64)).t()
|
117 |
-
rotate_corners = rotate_corners.reshape(-1,8)
|
118 |
-
|
119 |
-
x_corners = rotate_corners[:,[0,2,4,6]]
|
120 |
-
y_corners = rotate_corners[:,[1,3,5,7]]
|
121 |
-
|
122 |
-
#Get (x_min, y_min, x_max, y_max)
|
123 |
-
x_min, _ = torch.min(x_corners, dim= 1)
|
124 |
-
x_min = x_min.reshape(-1, 1)
|
125 |
-
y_min, _ = torch.min(y_corners, dim= 1)
|
126 |
-
y_min = y_min.reshape(-1, 1)
|
127 |
-
x_max, _ = torch.max(x_corners, dim= 1)
|
128 |
-
x_max = x_max.reshape(-1, 1)
|
129 |
-
y_max, _ = torch.max(y_corners, dim= 1)
|
130 |
-
y_max = y_max.reshape(-1, 1)
|
131 |
-
|
132 |
-
new_boxes = torch.cat((x_min, y_min, x_max, y_max), dim= 1)
|
133 |
-
|
134 |
-
scale_x = new_image.width / w
|
135 |
-
scale_y = new_image.height / h
|
136 |
-
|
137 |
-
#Resize new image to (w, h)
|
138 |
-
|
139 |
-
new_image = new_image.resize((w, h))
|
140 |
-
|
141 |
-
#Resize boxes
|
142 |
-
new_boxes /= torch.Tensor([scale_x, scale_y, scale_x, scale_y])
|
143 |
-
new_boxes[:, 0] = torch.clamp(new_boxes[:, 0], 0, w)
|
144 |
-
new_boxes[:, 1] = torch.clamp(new_boxes[:, 1], 0, h)
|
145 |
-
new_boxes[:, 2] = torch.clamp(new_boxes[:, 2], 0, w)
|
146 |
-
new_boxes[:, 3] = torch.clamp(new_boxes[:, 3], 0, h)
|
147 |
-
return new_image, new_boxes
|
148 |
-
|
149 |
-
# def convert_xywh_to_xyxy(boxes: torch.Tensor):
|
150 |
-
# _boxes = boxes.clone()
|
151 |
-
# box_xy = _boxes[:, :2]
|
152 |
-
# box_wh = _boxes[:, 2:]
|
153 |
-
# box_x1y1 = box_xy - box_wh/2
|
154 |
-
# box_x2y2 = box_xy + box_wh/2
|
155 |
-
# box_xyxy = torch.cat((box_x1y1, box_x2y2), dim=-1)
|
156 |
-
# return box_xyxy
|
157 |
-
|
158 |
-
class Rotate:
|
159 |
-
def __init__(self, angle=10) -> None:
|
160 |
-
self.angle = angle
|
161 |
-
|
162 |
-
def __call__(self, img, target):
|
163 |
-
w,h = img.size
|
164 |
-
whwh = torch.Tensor([w, h, w, h])
|
165 |
-
boxes_xyxy = box_cxcywh_to_xyxy(target['boxes']) * whwh
|
166 |
-
img, boxes_new = rotate(img, boxes_xyxy, self.angle)
|
167 |
-
target['boxes'] = box_xyxy_to_cxcywh(boxes_new).to(boxes_xyxy.dtype) / (whwh + 1e-3)
|
168 |
-
return img, target
|
169 |
-
|
170 |
-
|
171 |
-
class RandomCrop:
|
172 |
-
def __init__(self) -> None:
|
173 |
-
pass
|
174 |
-
|
175 |
-
def __call__(self, img, target):
|
176 |
-
w,h = img.size
|
177 |
-
try:
|
178 |
-
boxes_xyxy = target['boxes']
|
179 |
-
labels = target['labels']
|
180 |
-
img, new_boxes, new_labels, _ = random_crop(img, boxes_xyxy, labels)
|
181 |
-
target['boxes'] = new_boxes
|
182 |
-
target['labels'] = new_labels
|
183 |
-
except Exception as e:
|
184 |
-
pass
|
185 |
-
return img, target
|
186 |
-
|
187 |
-
|
188 |
-
class RandomCropDebug:
|
189 |
-
def __init__(self) -> None:
|
190 |
-
pass
|
191 |
-
|
192 |
-
def __call__(self, img, target):
|
193 |
-
boxes_xyxy = target['boxes'].clone()
|
194 |
-
labels = target['labels'].clone()
|
195 |
-
img, new_boxes, new_labels, _ = random_crop(img, boxes_xyxy, labels)
|
196 |
-
target['boxes'] = new_boxes
|
197 |
-
target['labels'] = new_labels
|
198 |
-
|
199 |
-
|
200 |
-
return img, target
|
201 |
-
|
202 |
-
class RandomSelectMulti(object):
|
203 |
-
"""
|
204 |
-
Randomly selects between transforms1 and transforms2,
|
205 |
-
"""
|
206 |
-
def __init__(self, transformslist, p=-1):
|
207 |
-
self.transformslist = transformslist
|
208 |
-
self.p = p
|
209 |
-
assert p == -1
|
210 |
-
|
211 |
-
def __call__(self, img, target):
|
212 |
-
if self.p == -1:
|
213 |
-
return random.choice(self.transformslist)(img, target)
|
214 |
-
|
215 |
-
|
216 |
-
class Albumentations:
|
217 |
-
def __init__(self):
|
218 |
-
import albumentations as A
|
219 |
-
self.transform = A.Compose([
|
220 |
-
A.Blur(p=0.01),
|
221 |
-
A.MedianBlur(p=0.01),
|
222 |
-
A.ToGray(p=0.01),
|
223 |
-
A.CLAHE(p=0.01),
|
224 |
-
A.RandomBrightnessContrast(p=0.005),
|
225 |
-
A.RandomGamma(p=0.005),
|
226 |
-
A.ImageCompression(quality_lower=75, p=0.005)],
|
227 |
-
bbox_params=A.BboxParams(format='pascal_voc', label_fields=['class_labels']))
|
228 |
-
|
229 |
-
def __call__(self, img, target, p=1.0):
|
230 |
-
"""
|
231 |
-
Input:
|
232 |
-
target['boxes']: xyxy, unnormalized data.
|
233 |
-
|
234 |
-
"""
|
235 |
-
boxes_raw = target['boxes']
|
236 |
-
labels_raw = target['labels']
|
237 |
-
img_np = np.array(img)
|
238 |
-
if self.transform and random.random() < p:
|
239 |
-
new_res = self.transform(image=img_np, bboxes=boxes_raw, class_labels=labels_raw) # transformed
|
240 |
-
boxes_new = torch.Tensor(new_res['bboxes']).to(boxes_raw.dtype).reshape_as(boxes_raw)
|
241 |
-
img_np = new_res['image']
|
242 |
-
labels_new = torch.Tensor(new_res['class_labels']).to(labels_raw.dtype)
|
243 |
-
img_new = Image.fromarray(img_np)
|
244 |
-
target['boxes'] = boxes_new
|
245 |
-
target['labels'] = labels_new
|
246 |
-
|
247 |
-
return img_new, target
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
environment.yaml
ADDED
@@ -0,0 +1,248 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
name: dino
|
2 |
+
channels:
|
3 |
+
- pytorch
|
4 |
+
- nvidia
|
5 |
+
- conda-forge
|
6 |
+
- defaults
|
7 |
+
dependencies:
|
8 |
+
- addict=2.4.0=pyhd8ed1ab_2
|
9 |
+
- aiohttp=3.8.5=py39ha55989b_0
|
10 |
+
- aiosignal=1.3.1=pyhd8ed1ab_0
|
11 |
+
- asttokens=2.0.5=pyhd3eb1b0_0
|
12 |
+
- async-timeout=4.0.3=pyhd8ed1ab_0
|
13 |
+
- attrs=23.1.0=pyh71513ae_1
|
14 |
+
- aws-c-auth=0.7.0=h6f3c987_2
|
15 |
+
- aws-c-cal=0.6.0=h6ba3258_0
|
16 |
+
- aws-c-common=0.8.23=hcfcfb64_0
|
17 |
+
- aws-c-compression=0.2.17=h420beca_1
|
18 |
+
- aws-c-event-stream=0.3.1=had47b81_1
|
19 |
+
- aws-c-http=0.7.11=h72ba615_0
|
20 |
+
- aws-c-io=0.13.28=ha35c040_0
|
21 |
+
- aws-c-mqtt=0.8.14=h4941efa_2
|
22 |
+
- aws-c-s3=0.3.13=he04eaa7_2
|
23 |
+
- aws-c-sdkutils=0.1.11=h420beca_1
|
24 |
+
- aws-checksums=0.1.16=h420beca_1
|
25 |
+
- aws-crt-cpp=0.20.3=h247a981_4
|
26 |
+
- aws-sdk-cpp=1.10.57=h1a0519f_17
|
27 |
+
- backcall=0.2.0=pyhd3eb1b0_0
|
28 |
+
- blas=2.118=mkl
|
29 |
+
- blas-devel=3.9.0=18_win64_mkl
|
30 |
+
- brotli=1.0.9=hcfcfb64_9
|
31 |
+
- brotli-bin=1.0.9=hcfcfb64_9
|
32 |
+
- brotli-python=1.0.9=py39h99910a6_9
|
33 |
+
- bzip2=1.0.8=h8ffe710_4
|
34 |
+
- c-ares=1.19.1=hcfcfb64_0
|
35 |
+
- ca-certificates=2023.08.22=haa95532_0
|
36 |
+
- certifi=2023.7.22=py39haa95532_0
|
37 |
+
- charset-normalizer=3.2.0=pyhd8ed1ab_0
|
38 |
+
- click=8.1.7=win_pyh7428d3b_0
|
39 |
+
- colorama=0.4.6=pyhd8ed1ab_0
|
40 |
+
- comm=0.1.2=py39haa95532_0
|
41 |
+
- contourpy=1.1.1=py39h1f6ef14_1
|
42 |
+
- cuda-cccl=12.2.140=0
|
43 |
+
- cuda-cudart=11.8.89=0
|
44 |
+
- cuda-cudart-dev=11.8.89=0
|
45 |
+
- cuda-cupti=11.8.87=0
|
46 |
+
- cuda-libraries=11.8.0=0
|
47 |
+
- cuda-libraries-dev=11.8.0=0
|
48 |
+
- cuda-nvrtc=11.8.89=0
|
49 |
+
- cuda-nvrtc-dev=11.8.89=0
|
50 |
+
- cuda-nvtx=11.8.86=0
|
51 |
+
- cuda-profiler-api=12.2.140=0
|
52 |
+
- cuda-runtime=11.8.0=0
|
53 |
+
- cycler=0.11.0=pyhd8ed1ab_0
|
54 |
+
- cython=3.0.0=py39h2bbff1b_0
|
55 |
+
- dataclasses=0.8=pyhc8e2a94_3
|
56 |
+
- datasets=2.14.5=pyhd8ed1ab_0
|
57 |
+
- debugpy=1.6.7=py39hd77b12b_0
|
58 |
+
- decorator=5.1.1=pyhd3eb1b0_0
|
59 |
+
- dill=0.3.7=pyhd8ed1ab_0
|
60 |
+
- exceptiongroup=1.0.4=py39haa95532_0
|
61 |
+
- executing=0.8.3=pyhd3eb1b0_0
|
62 |
+
- filelock=3.12.4=pyhd8ed1ab_0
|
63 |
+
- fonttools=4.42.1=py39ha55989b_0
|
64 |
+
- freeglut=3.2.2=h63175ca_2
|
65 |
+
- freetype=2.12.1=hdaf720e_2
|
66 |
+
- frozenlist=1.4.0=py39ha55989b_1
|
67 |
+
- fsspec=2023.6.0=pyh1a96a4e_0
|
68 |
+
- gettext=0.21.1=h5728263_0
|
69 |
+
- glib=2.78.0=h12be248_0
|
70 |
+
- glib-tools=2.78.0=h12be248_0
|
71 |
+
- gst-plugins-base=1.22.6=h001b923_1
|
72 |
+
- gstreamer=1.22.6=hb4038d2_1
|
73 |
+
- huggingface_hub=0.17.3=pyhd8ed1ab_0
|
74 |
+
- icu=70.1=h0e60522_0
|
75 |
+
- idna=3.4=pyhd8ed1ab_0
|
76 |
+
- importlib-metadata=6.8.0=pyha770c72_0
|
77 |
+
- importlib-resources=6.1.0=pyhd8ed1ab_0
|
78 |
+
- importlib_metadata=6.8.0=hd8ed1ab_0
|
79 |
+
- importlib_resources=6.1.0=pyhd8ed1ab_0
|
80 |
+
- intel-openmp=2023.2.0=h57928b3_49503
|
81 |
+
- ipykernel=6.25.0=py39h9909e9c_0
|
82 |
+
- ipython=8.15.0=py39haa95532_0
|
83 |
+
- jasper=2.0.33=hc2e4405_1
|
84 |
+
- jedi=0.18.1=py39haa95532_1
|
85 |
+
- jinja2=3.1.2=pyhd8ed1ab_1
|
86 |
+
- joblib=1.3.2=pyhd8ed1ab_0
|
87 |
+
- jpeg=9e=hcfcfb64_3
|
88 |
+
- jupyter_client=8.1.0=py39haa95532_0
|
89 |
+
- jupyter_core=5.3.0=py39haa95532_0
|
90 |
+
- kiwisolver=1.4.5=py39h1f6ef14_1
|
91 |
+
- krb5=1.20.1=heb0366b_0
|
92 |
+
- lcms2=2.14=h90d422f_0
|
93 |
+
- lerc=4.0.0=h63175ca_0
|
94 |
+
- libabseil=20230125.3=cxx17_h63175ca_0
|
95 |
+
- libarrow=12.0.1=h12e5d06_5_cpu
|
96 |
+
- libblas=3.9.0=18_win64_mkl
|
97 |
+
- libbrotlicommon=1.0.9=hcfcfb64_9
|
98 |
+
- libbrotlidec=1.0.9=hcfcfb64_9
|
99 |
+
- libbrotlienc=1.0.9=hcfcfb64_9
|
100 |
+
- libcblas=3.9.0=18_win64_mkl
|
101 |
+
- libclang=15.0.7=default_h77d9078_3
|
102 |
+
- libclang13=15.0.7=default_h77d9078_3
|
103 |
+
- libcrc32c=1.1.2=h0e60522_0
|
104 |
+
- libcublas=11.11.3.6=0
|
105 |
+
- libcublas-dev=11.11.3.6=0
|
106 |
+
- libcufft=10.9.0.58=0
|
107 |
+
- libcufft-dev=10.9.0.58=0
|
108 |
+
- libcurand=10.3.3.141=0
|
109 |
+
- libcurand-dev=10.3.3.141=0
|
110 |
+
- libcurl=8.1.2=h68f0423_0
|
111 |
+
- libcusolver=11.4.1.48=0
|
112 |
+
- libcusolver-dev=11.4.1.48=0
|
113 |
+
- libcusparse=11.7.5.86=0
|
114 |
+
- libcusparse-dev=11.7.5.86=0
|
115 |
+
- libdeflate=1.14=hcfcfb64_0
|
116 |
+
- libevent=2.1.12=h3671451_1
|
117 |
+
- libffi=3.4.2=h8ffe710_5
|
118 |
+
- libglib=2.78.0=he8f3873_0
|
119 |
+
- libgoogle-cloud=2.12.0=h00b2bdc_1
|
120 |
+
- libgrpc=1.54.3=ha177ca7_0
|
121 |
+
- libhwloc=2.9.3=default_haede6df_1009
|
122 |
+
- libiconv=1.17=h8ffe710_0
|
123 |
+
- liblapack=3.9.0=18_win64_mkl
|
124 |
+
- liblapacke=3.9.0=18_win64_mkl
|
125 |
+
- libnpp=11.8.0.86=0
|
126 |
+
- libnpp-dev=11.8.0.86=0
|
127 |
+
- libnvjpeg=11.9.0.86=0
|
128 |
+
- libnvjpeg-dev=11.9.0.86=0
|
129 |
+
- libogg=1.3.4=h8ffe710_1
|
130 |
+
- libopencv=4.5.3=py39h488c12c_8
|
131 |
+
- libpng=1.6.39=h19919ed_0
|
132 |
+
- libprotobuf=3.21.12=h12be248_2
|
133 |
+
- libsodium=1.0.18=h62dcd97_0
|
134 |
+
- libsqlite=3.43.0=hcfcfb64_0
|
135 |
+
- libssh2=1.11.0=h7dfc565_0
|
136 |
+
- libthrift=0.18.1=h06f6336_2
|
137 |
+
- libtiff=4.4.0=hc4f729c_5
|
138 |
+
- libutf8proc=2.8.0=h82a8f57_0
|
139 |
+
- libuv=1.44.2=hcfcfb64_1
|
140 |
+
- libvorbis=1.3.7=h0e60522_0
|
141 |
+
- libwebp-base=1.3.2=hcfcfb64_0
|
142 |
+
- libxcb=1.13=hcd874cb_1004
|
143 |
+
- libxml2=2.11.5=hc3477c8_1
|
144 |
+
- libzlib=1.2.13=hcfcfb64_5
|
145 |
+
- lz4-c=1.9.4=hcfcfb64_0
|
146 |
+
- m2w64-gcc-libgfortran=5.3.0=6
|
147 |
+
- m2w64-gcc-libs=5.3.0=7
|
148 |
+
- m2w64-gcc-libs-core=5.3.0=7
|
149 |
+
- m2w64-gmp=6.1.0=2
|
150 |
+
- m2w64-libwinpthread-git=5.0.0.4634.697f757=2
|
151 |
+
- markupsafe=2.1.3=py39ha55989b_1
|
152 |
+
- matplotlib-base=3.8.0=py39hf19769e_1
|
153 |
+
- matplotlib-inline=0.1.6=py39haa95532_0
|
154 |
+
- mkl=2022.1.0=h6a75c08_874
|
155 |
+
- mkl-devel=2022.1.0=h57928b3_875
|
156 |
+
- mkl-include=2022.1.0=h6a75c08_874
|
157 |
+
- mpmath=1.3.0=pyhd8ed1ab_0
|
158 |
+
- msys2-conda-epoch=20160418=1
|
159 |
+
- multidict=6.0.4=py39ha55989b_0
|
160 |
+
- multiprocess=0.70.15=py39ha55989b_1
|
161 |
+
- munkres=1.1.4=pyh9f0ad1d_0
|
162 |
+
- nest-asyncio=1.5.6=py39haa95532_0
|
163 |
+
- networkx=3.1=pyhd8ed1ab_0
|
164 |
+
- numpy=1.26.0=py39hddb5d58_0
|
165 |
+
- opencv=4.5.3=py39hcbf5309_8
|
166 |
+
- openjpeg=2.5.0=hc9384bd_1
|
167 |
+
- openssl=3.1.3=hcfcfb64_0
|
168 |
+
- orc=1.9.0=hada7b9e_1
|
169 |
+
- packaging=23.1=pyhd8ed1ab_0
|
170 |
+
- pandas=2.1.1=py39h32e6231_0
|
171 |
+
- parso=0.8.3=pyhd3eb1b0_0
|
172 |
+
- pcre2=10.40=h17e33f8_0
|
173 |
+
- pickleshare=0.7.5=pyhd3eb1b0_1003
|
174 |
+
- pillow=9.2.0=py39h595c93f_3
|
175 |
+
- pip=23.2.1=pyhd8ed1ab_0
|
176 |
+
- platformdirs=3.10.0=pyhd8ed1ab_0
|
177 |
+
- prompt-toolkit=3.0.36=py39haa95532_0
|
178 |
+
- psutil=5.9.0=py39h2bbff1b_0
|
179 |
+
- pthread-stubs=0.4=hcd874cb_1001
|
180 |
+
- pthreads-win32=2.9.1=hfa6e2cd_3
|
181 |
+
- pure_eval=0.2.2=pyhd3eb1b0_0
|
182 |
+
- py-opencv=4.5.3=py39h00e5391_8
|
183 |
+
- pyarrow=12.0.1=py39hca4e8af_5_cpu
|
184 |
+
- pycocotools=2.0.6=py39hc266a54_1
|
185 |
+
- pygments=2.15.1=py39haa95532_1
|
186 |
+
- pyparsing=3.1.1=pyhd8ed1ab_0
|
187 |
+
- pysocks=1.7.1=pyh0701188_6
|
188 |
+
- python=3.9.18=h4de0772_0_cpython
|
189 |
+
- python-dateutil=2.8.2=pyhd8ed1ab_0
|
190 |
+
- python-tzdata=2023.3=pyhd8ed1ab_0
|
191 |
+
- python-xxhash=3.3.0=py39ha55989b_1
|
192 |
+
- python_abi=3.9=4_cp39
|
193 |
+
- pytorch=2.0.1=py3.9_cuda11.8_cudnn8_0
|
194 |
+
- pytorch-cuda=11.8=h24eeafa_5
|
195 |
+
- pytorch-mutex=1.0=cuda
|
196 |
+
- pytz=2023.3.post1=pyhd8ed1ab_0
|
197 |
+
- pywin32=305=py39h2bbff1b_0
|
198 |
+
- pyyaml=6.0.1=py39ha55989b_1
|
199 |
+
- pyzmq=25.1.0=py39hd77b12b_0
|
200 |
+
- qt-main=5.15.8=h720456b_6
|
201 |
+
- re2=2023.03.02=hd4eee63_0
|
202 |
+
- regex=2023.8.8=py39ha55989b_1
|
203 |
+
- requests=2.31.0=pyhd8ed1ab_0
|
204 |
+
- sacremoses=0.0.53=pyhd8ed1ab_0
|
205 |
+
- safetensors=0.3.3=py39hf21820d_1
|
206 |
+
- setuptools=68.2.2=pyhd8ed1ab_0
|
207 |
+
- six=1.16.0=pyh6c4a22f_0
|
208 |
+
- snappy=1.1.10=hfb803bf_0
|
209 |
+
- stack_data=0.2.0=pyhd3eb1b0_0
|
210 |
+
- sympy=1.12=pyh04b8f61_3
|
211 |
+
- tbb=2021.10.0=h91493d7_1
|
212 |
+
- timm=0.9.7=pyhd8ed1ab_0
|
213 |
+
- tk=8.6.13=hcfcfb64_0
|
214 |
+
- tokenizers=0.13.3=py39hca44cb7_0
|
215 |
+
- tomli=2.0.1=pyhd8ed1ab_0
|
216 |
+
- tornado=6.3.2=py39h2bbff1b_0
|
217 |
+
- tqdm=4.66.1=pyhd8ed1ab_0
|
218 |
+
- traitlets=5.7.1=py39haa95532_0
|
219 |
+
- transformers=4.33.2=pyhd8ed1ab_0
|
220 |
+
- typing-extensions=4.8.0=hd8ed1ab_0
|
221 |
+
- typing_extensions=4.8.0=pyha770c72_0
|
222 |
+
- tzdata=2023c=h71feb2d_0
|
223 |
+
- ucrt=10.0.22621.0=h57928b3_0
|
224 |
+
- unicodedata2=15.0.0=py39ha55989b_1
|
225 |
+
- urllib3=2.0.5=pyhd8ed1ab_0
|
226 |
+
- vc=14.3=h64f974e_17
|
227 |
+
- vc14_runtime=14.36.32532=hdcecf7f_17
|
228 |
+
- vs2015_runtime=14.36.32532=h05e6639_17
|
229 |
+
- wcwidth=0.2.5=pyhd3eb1b0_0
|
230 |
+
- wheel=0.41.2=pyhd8ed1ab_0
|
231 |
+
- win_inet_pton=1.1.0=pyhd8ed1ab_6
|
232 |
+
- xorg-libxau=1.0.11=hcd874cb_0
|
233 |
+
- xorg-libxdmcp=1.1.3=hcd874cb_0
|
234 |
+
- xxhash=0.8.2=hcfcfb64_0
|
235 |
+
- xz=5.2.6=h8d14728_0
|
236 |
+
- yaml=0.2.5=h8ffe710_2
|
237 |
+
- yapf=0.40.1=pyhd8ed1ab_0
|
238 |
+
- yarl=1.9.2=py39ha55989b_0
|
239 |
+
- zeromq=4.3.4=hd77b12b_0
|
240 |
+
- zipp=3.17.0=pyhd8ed1ab_0
|
241 |
+
- zlib=1.2.13=hcfcfb64_5
|
242 |
+
- zstd=1.5.5=h12be248_0
|
243 |
+
- pip:
|
244 |
+
- opencv-python==4.8.0.76
|
245 |
+
- supervision==0.6.0
|
246 |
+
- torchaudio==2.0.2
|
247 |
+
- torchvision==0.15.2
|
248 |
+
prefix: C:\Users\Makoto\miniconda3\envs\dino
|
groundingdino.egg-info/PKG-INFO
ADDED
@@ -0,0 +1,213 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Metadata-Version: 2.1
|
2 |
+
Name: groundingdino
|
3 |
+
Version: 0.1.0
|
4 |
+
Summary: open-set object detector
|
5 |
+
Home-page: https://github.com/IDEA-Research/GroundingDINO
|
6 |
+
Author: International Digital Economy Academy, Shilong Liu
|
7 |
+
License: Apache License
|
8 |
+
Version 2.0, January 2004
|
9 |
+
http://www.apache.org/licenses/
|
10 |
+
|
11 |
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
12 |
+
|
13 |
+
1. Definitions.
|
14 |
+
|
15 |
+
"License" shall mean the terms and conditions for use, reproduction,
|
16 |
+
and distribution as defined by Sections 1 through 9 of this document.
|
17 |
+
|
18 |
+
"Licensor" shall mean the copyright owner or entity authorized by
|
19 |
+
the copyright owner that is granting the License.
|
20 |
+
|
21 |
+
"Legal Entity" shall mean the union of the acting entity and all
|
22 |
+
other entities that control, are controlled by, or are under common
|
23 |
+
control with that entity. For the purposes of this definition,
|
24 |
+
"control" means (i) the power, direct or indirect, to cause the
|
25 |
+
direction or management of such entity, whether by contract or
|
26 |
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
27 |
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
28 |
+
|
29 |
+
"You" (or "Your") shall mean an individual or Legal Entity
|
30 |
+
exercising permissions granted by this License.
|
31 |
+
|
32 |
+
"Source" form shall mean the preferred form for making modifications,
|
33 |
+
including but not limited to software source code, documentation
|
34 |
+
source, and configuration files.
|
35 |
+
|
36 |
+
"Object" form shall mean any form resulting from mechanical
|
37 |
+
transformation or translation of a Source form, including but
|
38 |
+
not limited to compiled object code, generated documentation,
|
39 |
+
and conversions to other media types.
|
40 |
+
|
41 |
+
"Work" shall mean the work of authorship, whether in Source or
|
42 |
+
Object form, made available under the License, as indicated by a
|
43 |
+
copyright notice that is included in or attached to the work
|
44 |
+
(an example is provided in the Appendix below).
|
45 |
+
|
46 |
+
"Derivative Works" shall mean any work, whether in Source or Object
|
47 |
+
form, that is based on (or derived from) the Work and for which the
|
48 |
+
editorial revisions, annotations, elaborations, or other modifications
|
49 |
+
represent, as a whole, an original work of authorship. For the purposes
|
50 |
+
of this License, Derivative Works shall not include works that remain
|
51 |
+
separable from, or merely link (or bind by name) to the interfaces of,
|
52 |
+
the Work and Derivative Works thereof.
|
53 |
+
|
54 |
+
"Contribution" shall mean any work of authorship, including
|
55 |
+
the original version of the Work and any modifications or additions
|
56 |
+
to that Work or Derivative Works thereof, that is intentionally
|
57 |
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
58 |
+
or by an individual or Legal Entity authorized to submit on behalf of
|
59 |
+
the copyright owner. For the purposes of this definition, "submitted"
|
60 |
+
means any form of electronic, verbal, or written communication sent
|
61 |
+
to the Licensor or its representatives, including but not limited to
|
62 |
+
communication on electronic mailing lists, source code control systems,
|
63 |
+
and issue tracking systems that are managed by, or on behalf of, the
|
64 |
+
Licensor for the purpose of discussing and improving the Work, but
|
65 |
+
excluding communication that is conspicuously marked or otherwise
|
66 |
+
designated in writing by the copyright owner as "Not a Contribution."
|
67 |
+
|
68 |
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
69 |
+
on behalf of whom a Contribution has been received by Licensor and
|
70 |
+
subsequently incorporated within the Work.
|
71 |
+
|
72 |
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
73 |
+
this License, each Contributor hereby grants to You a perpetual,
|
74 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
75 |
+
copyright license to reproduce, prepare Derivative Works of,
|
76 |
+
publicly display, publicly perform, sublicense, and distribute the
|
77 |
+
Work and such Derivative Works in Source or Object form.
|
78 |
+
|
79 |
+
3. Grant of Patent License. Subject to the terms and conditions of
|
80 |
+
this License, each Contributor hereby grants to You a perpetual,
|
81 |
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
82 |
+
(except as stated in this section) patent license to make, have made,
|
83 |
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
84 |
+
where such license applies only to those patent claims licensable
|
85 |
+
by such Contributor that are necessarily infringed by their
|
86 |
+
Contribution(s) alone or by combination of their Contribution(s)
|
87 |
+
with the Work to which such Contribution(s) was submitted. If You
|
88 |
+
institute patent litigation against any entity (including a
|
89 |
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
90 |
+
or a Contribution incorporated within the Work constitutes direct
|
91 |
+
or contributory patent infringement, then any patent licenses
|
92 |
+
granted to You under this License for that Work shall terminate
|
93 |
+
as of the date such litigation is filed.
|
94 |
+
|
95 |
+
4. Redistribution. You may reproduce and distribute copies of the
|
96 |
+
Work or Derivative Works thereof in any medium, with or without
|
97 |
+
modifications, and in Source or Object form, provided that You
|
98 |
+
meet the following conditions:
|
99 |
+
|
100 |
+
(a) You must give any other recipients of the Work or
|
101 |
+
Derivative Works a copy of this License; and
|
102 |
+
|
103 |
+
(b) You must cause any modified files to carry prominent notices
|
104 |
+
stating that You changed the files; and
|
105 |
+
|
106 |
+
(c) You must retain, in the Source form of any Derivative Works
|
107 |
+
that You distribute, all copyright, patent, trademark, and
|
108 |
+
attribution notices from the Source form of the Work,
|
109 |
+
excluding those notices that do not pertain to any part of
|
110 |
+
the Derivative Works; and
|
111 |
+
|
112 |
+
(d) If the Work includes a "NOTICE" text file as part of its
|
113 |
+
distribution, then any Derivative Works that You distribute must
|
114 |
+
include a readable copy of the attribution notices contained
|
115 |
+
within such NOTICE file, excluding those notices that do not
|
116 |
+
pertain to any part of the Derivative Works, in at least one
|
117 |
+
of the following places: within a NOTICE text file distributed
|
118 |
+
as part of the Derivative Works; within the Source form or
|
119 |
+
documentation, if provided along with the Derivative Works; or,
|
120 |
+
within a display generated by the Derivative Works, if and
|
121 |
+
wherever such third-party notices normally appear. The contents
|
122 |
+
of the NOTICE file are for informational purposes only and
|
123 |
+
do not modify the License. You may add Your own attribution
|
124 |
+
notices within Derivative Works that You distribute, alongside
|
125 |
+
or as an addendum to the NOTICE text from the Work, provided
|
126 |
+
that such additional attribution notices cannot be construed
|
127 |
+
as modifying the License.
|
128 |
+
|
129 |
+
You may add Your own copyright statement to Your modifications and
|
130 |
+
may provide additional or different license terms and conditions
|
131 |
+
for use, reproduction, or distribution of Your modifications, or
|
132 |
+
for any such Derivative Works as a whole, provided Your use,
|
133 |
+
reproduction, and distribution of the Work otherwise complies with
|
134 |
+
the conditions stated in this License.
|
135 |
+
|
136 |
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
137 |
+
any Contribution intentionally submitted for inclusion in the Work
|
138 |
+
by You to the Licensor shall be under the terms and conditions of
|
139 |
+
this License, without any additional terms or conditions.
|
140 |
+
Notwithstanding the above, nothing herein shall supersede or modify
|
141 |
+
the terms of any separate license agreement you may have executed
|
142 |
+
with Licensor regarding such Contributions.
|
143 |
+
|
144 |
+
6. Trademarks. This License does not grant permission to use the trade
|
145 |
+
names, trademarks, service marks, or product names of the Licensor,
|
146 |
+
except as required for reasonable and customary use in describing the
|
147 |
+
origin of the Work and reproducing the content of the NOTICE file.
|
148 |
+
|
149 |
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
150 |
+
agreed to in writing, Licensor provides the Work (and each
|
151 |
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
152 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
153 |
+
implied, including, without limitation, any warranties or conditions
|
154 |
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
155 |
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
156 |
+
appropriateness of using or redistributing the Work and assume any
|
157 |
+
risks associated with Your exercise of permissions under this License.
|
158 |
+
|
159 |
+
8. Limitation of Liability. In no event and under no legal theory,
|
160 |
+
whether in tort (including negligence), contract, or otherwise,
|
161 |
+
unless required by applicable law (such as deliberate and grossly
|
162 |
+
negligent acts) or agreed to in writing, shall any Contributor be
|
163 |
+
liable to You for damages, including any direct, indirect, special,
|
164 |
+
incidental, or consequential damages of any character arising as a
|
165 |
+
result of this License or out of the use or inability to use the
|
166 |
+
Work (including but not limited to damages for loss of goodwill,
|
167 |
+
work stoppage, computer failure or malfunction, or any and all
|
168 |
+
other commercial damages or losses), even if such Contributor
|
169 |
+
has been advised of the possibility of such damages.
|
170 |
+
|
171 |
+
9. Accepting Warranty or Additional Liability. While redistributing
|
172 |
+
the Work or Derivative Works thereof, You may choose to offer,
|
173 |
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
174 |
+
or other liability obligations and/or rights consistent with this
|
175 |
+
License. However, in accepting such obligations, You may act only
|
176 |
+
on Your own behalf and on Your sole responsibility, not on behalf
|
177 |
+
of any other Contributor, and only if You agree to indemnify,
|
178 |
+
defend, and hold each Contributor harmless for any liability
|
179 |
+
incurred by, or claims asserted against, such Contributor by reason
|
180 |
+
of your accepting any such warranty or additional liability.
|
181 |
+
|
182 |
+
END OF TERMS AND CONDITIONS
|
183 |
+
|
184 |
+
APPENDIX: How to apply the Apache License to your work.
|
185 |
+
|
186 |
+
To apply the Apache License to your work, attach the following
|
187 |
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
188 |
+
replaced with your own identifying information. (Don't include
|
189 |
+
the brackets!) The text should be enclosed in the appropriate
|
190 |
+
comment syntax for the file format. We also recommend that a
|
191 |
+
file or class name and description of purpose be included on the
|
192 |
+
same "printed page" as the copyright notice for easier
|
193 |
+
identification within third-party archives.
|
194 |
+
|
195 |
+
Copyright 2023 - present, IDEA Research.
|
196 |
+
|
197 |
+
Licensed under the Apache License, Version 2.0 (the "License");
|
198 |
+
you may not use this file except in compliance with the License.
|
199 |
+
You may obtain a copy of the License at
|
200 |
+
|
201 |
+
http://www.apache.org/licenses/LICENSE-2.0
|
202 |
+
|
203 |
+
Unless required by applicable law or agreed to in writing, software
|
204 |
+
distributed under the License is distributed on an "AS IS" BASIS,
|
205 |
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
206 |
+
See the License for the specific language governing permissions and
|
207 |
+
limitations under the License.
|
208 |
+
|
209 |
+
Platform: UNKNOWN
|
210 |
+
License-File: LICENSE
|
211 |
+
|
212 |
+
UNKNOWN
|
213 |
+
|
groundingdino.egg-info/SOURCES.txt
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
LICENSE
|
2 |
+
README.md
|
3 |
+
setup.py
|
4 |
+
/home/jamada/jupyterlab/projects/gdino-peft/gdino-official/GroundingDINO/groundingdino/models/GroundingDINO/csrc/cuda_version.cu
|
5 |
+
/home/jamada/jupyterlab/projects/gdino-peft/gdino-official/GroundingDINO/groundingdino/models/GroundingDINO/csrc/vision.cpp
|
6 |
+
/home/jamada/jupyterlab/projects/gdino-peft/gdino-official/GroundingDINO/groundingdino/models/GroundingDINO/csrc/MsDeformAttn/ms_deform_attn_cpu.cpp
|
7 |
+
/home/jamada/jupyterlab/projects/gdino-peft/gdino-official/GroundingDINO/groundingdino/models/GroundingDINO/csrc/MsDeformAttn/ms_deform_attn_cuda.cu
|
8 |
+
groundingdino/__init__.py
|
9 |
+
groundingdino/version.py
|
10 |
+
groundingdino.egg-info/PKG-INFO
|
11 |
+
groundingdino.egg-info/SOURCES.txt
|
12 |
+
groundingdino.egg-info/dependency_links.txt
|
13 |
+
groundingdino.egg-info/requires.txt
|
14 |
+
groundingdino.egg-info/top_level.txt
|
15 |
+
groundingdino/config/GroundingDINO_SwinB_cfg.py
|
16 |
+
groundingdino/config/GroundingDINO_SwinT_OGC.py
|
17 |
+
groundingdino/config/__init__.py
|
18 |
+
groundingdino/datasets/__init__.py
|
19 |
+
groundingdino/datasets/cocogrounding_eval.py
|
20 |
+
groundingdino/datasets/transforms.py
|
21 |
+
groundingdino/models/__init__.py
|
22 |
+
groundingdino/models/registry.py
|
23 |
+
groundingdino/models/GroundingDINO/__init__.py
|
24 |
+
groundingdino/models/GroundingDINO/bertwarper.py
|
25 |
+
groundingdino/models/GroundingDINO/fuse_modules.py
|
26 |
+
groundingdino/models/GroundingDINO/groundingdino.py
|
27 |
+
groundingdino/models/GroundingDINO/ms_deform_attn.py
|
28 |
+
groundingdino/models/GroundingDINO/transformer.py
|
29 |
+
groundingdino/models/GroundingDINO/transformer_vanilla.py
|
30 |
+
groundingdino/models/GroundingDINO/utils.py
|
31 |
+
groundingdino/models/GroundingDINO/backbone/__init__.py
|
32 |
+
groundingdino/models/GroundingDINO/backbone/backbone.py
|
33 |
+
groundingdino/models/GroundingDINO/backbone/position_encoding.py
|
34 |
+
groundingdino/models/GroundingDINO/backbone/swin_transformer.py
|
35 |
+
groundingdino/util/__init__.py
|
36 |
+
groundingdino/util/box_ops.py
|
37 |
+
groundingdino/util/get_tokenlizer.py
|
38 |
+
groundingdino/util/inference.py
|
39 |
+
groundingdino/util/logger.py
|
40 |
+
groundingdino/util/misc.py
|
41 |
+
groundingdino/util/slconfig.py
|
42 |
+
groundingdino/util/slio.py
|
43 |
+
groundingdino/util/time_counter.py
|
44 |
+
groundingdino/util/utils.py
|
45 |
+
groundingdino/util/visualizer.py
|
46 |
+
groundingdino/util/vl_utils.py
|
groundingdino.egg-info/dependency_links.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
|
groundingdino.egg-info/requires.txt
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
addict
|
2 |
+
numpy
|
3 |
+
opencv-python
|
4 |
+
pycocotools
|
5 |
+
supervision
|
6 |
+
timm
|
7 |
+
torch
|
8 |
+
torchvision
|
9 |
+
transformers
|
10 |
+
yapf
|
groundingdino.egg-info/top_level.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
groundingdino
|
groundingdino/.ipynb_checkpoints/__init__-checkpoint.py
ADDED
File without changes
|
groundingdino/.ipynb_checkpoints/version-checkpoint.py
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
__version__ = '0.1.0'
|
groundingdino/__init__.py
ADDED
File without changes
|
groundingdino/__pycache__/__init__.cpython-310.pyc
ADDED
Binary file (182 Bytes). View file
|
|
groundingdino/config/.ipynb_checkpoints/GroundingDINO_SwinB_cfg-checkpoint.py
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
batch_size = 1
|
2 |
+
modelname = "groundingdino"
|
3 |
+
backbone = "swin_B_384_22k"
|
4 |
+
position_embedding = "sine"
|
5 |
+
pe_temperatureH = 20
|
6 |
+
pe_temperatureW = 20
|
7 |
+
return_interm_indices = [1, 2, 3]
|
8 |
+
backbone_freeze_keywords = None
|
9 |
+
enc_layers = 6
|
10 |
+
dec_layers = 6
|
11 |
+
pre_norm = False
|
12 |
+
dim_feedforward = 2048
|
13 |
+
hidden_dim = 256
|
14 |
+
dropout = 0.0
|
15 |
+
nheads = 8
|
16 |
+
num_queries = 900
|
17 |
+
query_dim = 4
|
18 |
+
num_patterns = 0
|
19 |
+
num_feature_levels = 4
|
20 |
+
enc_n_points = 4
|
21 |
+
dec_n_points = 4
|
22 |
+
two_stage_type = "standard"
|
23 |
+
two_stage_bbox_embed_share = False
|
24 |
+
two_stage_class_embed_share = False
|
25 |
+
transformer_activation = "relu"
|
26 |
+
dec_pred_bbox_embed_share = True
|
27 |
+
dn_box_noise_scale = 1.0
|
28 |
+
dn_label_noise_ratio = 0.5
|
29 |
+
dn_label_coef = 1.0
|
30 |
+
dn_bbox_coef = 1.0
|
31 |
+
embed_init_tgt = True
|
32 |
+
dn_labelbook_size = 2000
|
33 |
+
max_text_len = 256
|
34 |
+
text_encoder_type = "bert-base-uncased"
|
35 |
+
use_text_enhancer = True
|
36 |
+
use_fusion_layer = True
|
37 |
+
use_checkpoint = True
|
38 |
+
use_transformer_ckpt = True
|
39 |
+
use_text_cross_attention = True
|
40 |
+
text_dropout = 0.0
|
41 |
+
fusion_dropout = 0.0
|
42 |
+
fusion_droppath = 0.1
|
43 |
+
sub_sentence_present = True
|
groundingdino/config/GroundingDINO_SwinB_cfg.py
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
batch_size = 1
|
2 |
+
modelname = "groundingdino"
|
3 |
+
backbone = "swin_B_384_22k"
|
4 |
+
position_embedding = "sine"
|
5 |
+
pe_temperatureH = 20
|
6 |
+
pe_temperatureW = 20
|
7 |
+
return_interm_indices = [1, 2, 3]
|
8 |
+
backbone_freeze_keywords = None
|
9 |
+
enc_layers = 6
|
10 |
+
dec_layers = 6
|
11 |
+
pre_norm = False
|
12 |
+
dim_feedforward = 2048
|
13 |
+
hidden_dim = 256
|
14 |
+
dropout = 0.0
|
15 |
+
nheads = 8
|
16 |
+
num_queries = 900
|
17 |
+
query_dim = 4
|
18 |
+
num_patterns = 0
|
19 |
+
num_feature_levels = 4
|
20 |
+
enc_n_points = 4
|
21 |
+
dec_n_points = 4
|
22 |
+
two_stage_type = "standard"
|
23 |
+
two_stage_bbox_embed_share = False
|
24 |
+
two_stage_class_embed_share = False
|
25 |
+
transformer_activation = "relu"
|
26 |
+
dec_pred_bbox_embed_share = True
|
27 |
+
dn_box_noise_scale = 1.0
|
28 |
+
dn_label_noise_ratio = 0.5
|
29 |
+
dn_label_coef = 1.0
|
30 |
+
dn_bbox_coef = 1.0
|
31 |
+
embed_init_tgt = True
|
32 |
+
dn_labelbook_size = 2000
|
33 |
+
max_text_len = 256
|
34 |
+
text_encoder_type = "bert-base-uncased"
|
35 |
+
use_text_enhancer = True
|
36 |
+
use_fusion_layer = True
|
37 |
+
use_checkpoint = True
|
38 |
+
use_transformer_ckpt = True
|
39 |
+
use_text_cross_attention = True
|
40 |
+
text_dropout = 0.0
|
41 |
+
fusion_dropout = 0.0
|
42 |
+
fusion_droppath = 0.1
|
43 |
+
sub_sentence_present = True
|
groundingdino/config/GroundingDINO_SwinT_OGC.py
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
batch_size = 1
|
2 |
+
modelname = "groundingdino"
|
3 |
+
backbone = "swin_T_224_1k"
|
4 |
+
position_embedding = "sine"
|
5 |
+
pe_temperatureH = 20
|
6 |
+
pe_temperatureW = 20
|
7 |
+
return_interm_indices = [1, 2, 3]
|
8 |
+
backbone_freeze_keywords = None
|
9 |
+
enc_layers = 6
|
10 |
+
dec_layers = 6
|
11 |
+
pre_norm = False
|
12 |
+
dim_feedforward = 2048
|
13 |
+
hidden_dim = 256
|
14 |
+
dropout = 0.0
|
15 |
+
nheads = 8
|
16 |
+
num_queries = 900
|
17 |
+
query_dim = 4
|
18 |
+
num_patterns = 0
|
19 |
+
num_feature_levels = 4
|
20 |
+
enc_n_points = 4
|
21 |
+
dec_n_points = 4
|
22 |
+
two_stage_type = "standard"
|
23 |
+
two_stage_bbox_embed_share = False
|
24 |
+
two_stage_class_embed_share = False
|
25 |
+
transformer_activation = "relu"
|
26 |
+
dec_pred_bbox_embed_share = True
|
27 |
+
dn_box_noise_scale = 1.0
|
28 |
+
dn_label_noise_ratio = 0.5
|
29 |
+
dn_label_coef = 1.0
|
30 |
+
dn_bbox_coef = 1.0
|
31 |
+
embed_init_tgt = True
|
32 |
+
dn_labelbook_size = 2000
|
33 |
+
max_text_len = 256
|
34 |
+
text_encoder_type = "bert-base-uncased"
|
35 |
+
use_text_enhancer = True
|
36 |
+
use_fusion_layer = True
|
37 |
+
use_checkpoint = True
|
38 |
+
use_transformer_ckpt = True
|
39 |
+
use_text_cross_attention = True
|
40 |
+
text_dropout = 0.0
|
41 |
+
fusion_dropout = 0.0
|
42 |
+
fusion_droppath = 0.1
|
43 |
+
sub_sentence_present = True
|
groundingdino/config/__init__.py
ADDED
File without changes
|
groundingdino/datasets/__init__.py
ADDED
File without changes
|
groundingdino/datasets/__pycache__/__init__.cpython-310.pyc
ADDED
Binary file (191 Bytes). View file
|
|
groundingdino/datasets/__pycache__/transforms.cpython-310.pyc
ADDED
Binary file (10.2 kB). View file
|
|
{datasets → groundingdino/datasets}/cocogrounding_eval.py
RENAMED
@@ -45,7 +45,7 @@ class CocoGroundingEvaluator(object):
|
|
45 |
def update(self, predictions):
|
46 |
img_ids = list(np.unique(list(predictions.keys())))
|
47 |
self.img_ids.extend(img_ids)
|
48 |
-
|
49 |
for iou_type in self.iou_types:
|
50 |
results = self.prepare(predictions, iou_type)
|
51 |
|
@@ -223,8 +223,6 @@ def evaluate(self):
|
|
223 |
"""
|
224 |
# tic = time.time()
|
225 |
# print('Running per image evaluation...')
|
226 |
-
|
227 |
-
# import pdb;pdb.set_trace()
|
228 |
p = self.params
|
229 |
# add backward compatibility if useSegm is specified in params
|
230 |
if p.useSegm is not None:
|
|
|
45 |
def update(self, predictions):
|
46 |
img_ids = list(np.unique(list(predictions.keys())))
|
47 |
self.img_ids.extend(img_ids)
|
48 |
+
|
49 |
for iou_type in self.iou_types:
|
50 |
results = self.prepare(predictions, iou_type)
|
51 |
|
|
|
223 |
"""
|
224 |
# tic = time.time()
|
225 |
# print('Running per image evaluation...')
|
|
|
|
|
226 |
p = self.params
|
227 |
# add backward compatibility if useSegm is specified in params
|
228 |
if p.useSegm is not None:
|