Spaces:
Running
on
T4
Running
on
T4
Prasanna Sridhar
commited on
Commit
·
fbeafb6
1
Parent(s):
46093a1
Update notebook to export xy coordinates in json format
Browse files- app.py +17 -1
- notebooks/demo.ipynb +55 -14
app.py
CHANGED
@@ -176,11 +176,27 @@ def get_ind_to_filter(text, word_ids, keywords):
|
|
176 |
|
177 |
return inds_to_filter
|
178 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
def generate_heatmap(image, boxes):
|
180 |
# Plot results.
|
181 |
(w, h) = image.size
|
182 |
det_map = np.zeros((h, w))
|
183 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
det_map = ndimage.gaussian_filter(
|
185 |
det_map, sigma=(w // 200, w // 200), order=0
|
186 |
)
|
|
|
176 |
|
177 |
return inds_to_filter
|
178 |
|
179 |
+
def get_xy_from_boxes(image, boxes):
|
180 |
+
"""
|
181 |
+
Get box centers and return in image coordinates
|
182 |
+
"""
|
183 |
+
(w, h) = image.size
|
184 |
+
x = w * boxes[:, 0]
|
185 |
+
y = h * boxes[:, 1]
|
186 |
+
|
187 |
+
return x, y
|
188 |
+
|
189 |
def generate_heatmap(image, boxes):
|
190 |
# Plot results.
|
191 |
(w, h) = image.size
|
192 |
det_map = np.zeros((h, w))
|
193 |
+
x, y = get_xy_from_boxes(image, boxes)
|
194 |
+
|
195 |
+
# Box centers are floating point, convert to int and clip them at edge of box
|
196 |
+
x = np.clip(np.around(x).astype(int), 0, w - 1)
|
197 |
+
y = np.clip(np.around(y).astype(int), 0, h - 1)
|
198 |
+
|
199 |
+
det_map[y, x] = 1
|
200 |
det_map = ndimage.gaussian_filter(
|
201 |
det_map, sigma=(w // 200, w // 200), order=0
|
202 |
)
|
notebooks/demo.ipynb
CHANGED
@@ -6,7 +6,7 @@
|
|
6 |
"id": "yxig5CdZuHb9"
|
7 |
},
|
8 |
"source": [
|
9 |
-
"# CountGD -
|
10 |
"\n"
|
11 |
]
|
12 |
},
|
@@ -89,7 +89,13 @@
|
|
89 |
"source": [
|
90 |
"### Install Dependencies\n",
|
91 |
"\n",
|
92 |
-
"The environment will be setup with the code, models and required dependencies
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
]
|
94 |
},
|
95 |
{
|
@@ -114,8 +120,10 @@
|
|
114 |
" git clone \"https://huggingface.co/spaces/nikigoli/countgd\" /content/countgd\n",
|
115 |
" fi\n",
|
116 |
" cd /content/countgd\n",
|
117 |
-
"
|
118 |
-
"
|
|
|
|
|
119 |
"else\n",
|
120 |
" # TODO check if cwd is the correct git repo\n",
|
121 |
" # If users use vscode, then we set the default start directory to root of the repo\n",
|
@@ -128,11 +136,20 @@
|
|
128 |
"pip install --upgrade pip setuptools wheel\n",
|
129 |
"pip install -r requirements.txt\n",
|
130 |
"\n",
|
131 |
-
"# Compile modules\n",
|
132 |
-
"export CUDA_HOME=/usr/local/cuda/\n",
|
133 |
"cd models/GroundingDINO/ops\n",
|
134 |
-
"
|
135 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
"python3 test.py"
|
137 |
]
|
138 |
},
|
@@ -189,6 +206,7 @@
|
|
189 |
" get_device,\n",
|
190 |
" get_args_parser,\n",
|
191 |
" generate_heatmap,\n",
|
|
|
192 |
" predict,\n",
|
193 |
")\n",
|
194 |
"args = get_args_parser().parse_args([])\n",
|
@@ -197,7 +215,7 @@
|
|
197 |
"model = model.to(device)\n",
|
198 |
"\n",
|
199 |
"run = lambda image, text: predict(model, transform, image, text, None, device)\n",
|
200 |
-
"get_output = lambda image, boxes: (len(boxes), generate_heatmap(image, boxes))\n"
|
201 |
]
|
202 |
},
|
203 |
{
|
@@ -271,7 +289,7 @@
|
|
271 |
},
|
272 |
{
|
273 |
"cell_type": "code",
|
274 |
-
"execution_count":
|
275 |
"metadata": {
|
276 |
"id": "rFXRk-_uuHb_"
|
277 |
},
|
@@ -279,6 +297,17 @@
|
|
279 |
"source": [
|
280 |
"from tqdm import tqdm\n",
|
281 |
"import os\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
282 |
"def process_zipfile(input_zipfile: Path, text: str):\n",
|
283 |
" if not input_zipfile.exists() or not input_zipfile.is_file() or not os.access(input_zipfile, os.R_OK):\n",
|
284 |
" logger.error(f'Cannot open / read zipfile: {input_zipfile}. Please check if it exists')\n",
|
@@ -290,14 +319,24 @@
|
|
290 |
"\n",
|
291 |
" output_zipfile = input_zipfile.parent / f'{input_zipfile.stem}_countgd.zip'\n",
|
292 |
" output_csvfile = input_zipfile.parent / f'{input_zipfile.stem}.csv'\n",
|
|
|
|
|
|
|
293 |
"\n",
|
294 |
" logger.info(f'Writing outputs to {output_zipfile.name} and {output_csvfile.name} in {input_zipfile.parent} folder')\n",
|
295 |
" with zipfile_writer(output_zipfile) as add_to_zip, csvfile_writer(output_csvfile) as write_row:\n",
|
296 |
" for filename, im in tqdm(images_from_zipfile(input_zipfile)):\n",
|
297 |
-
"
|
298 |
-
"
|
299 |
-
"
|
300 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
301 |
]
|
302 |
},
|
303 |
{
|
@@ -310,6 +349,8 @@
|
|
310 |
"\n",
|
311 |
"Use the form on colab to set the parameters, providing the zipfile with input images and a promt text representing the object you want to count.\n",
|
312 |
"\n",
|
|
|
|
|
313 |
"If you are not running on colab, change the values in the next cell\n",
|
314 |
"\n",
|
315 |
"Make sure to run the cell once you change the value."
|
|
|
6 |
"id": "yxig5CdZuHb9"
|
7 |
},
|
8 |
"source": [
|
9 |
+
"# CountGD - Multimodal open-world object counting\n",
|
10 |
"\n"
|
11 |
]
|
12 |
},
|
|
|
89 |
"source": [
|
90 |
"### Install Dependencies\n",
|
91 |
"\n",
|
92 |
+
"The environment will be setup with the code, models and required dependencies.\n",
|
93 |
+
"\n",
|
94 |
+
"*Note for Colab users*\n",
|
95 |
+
"\n",
|
96 |
+
"To reduce the waiting time, you can use the pre-built wheel file available [here](https://drive.google.com/file/d/1Vl_6DAWfnVU7HFX5y_5TqqbkyTcjONbm/view?usp=sharing) - Visit the link and add it as a shortcut to your \"My Drive\" folder or edit the path accordingly below. (Line 28)\n",
|
97 |
+
"\n",
|
98 |
+
"Alternatively, if you are unable to use google drive, you can download the file to your machine & upload it to the colab runtime when you connect to it and update the path below to install it from there. (Line 28)"
|
99 |
]
|
100 |
},
|
101 |
{
|
|
|
120 |
" git clone \"https://huggingface.co/spaces/nikigoli/countgd\" /content/countgd\n",
|
121 |
" fi\n",
|
122 |
" cd /content/countgd\n",
|
123 |
+
"\n",
|
124 |
+
" # If you are testing out WIP items, uncomment the following and change the pr ref\n",
|
125 |
+
" # git fetch origin refs/pr/10:refs/remotes/origin/pr/10\n",
|
126 |
+
" # git checkout pr/10 && git pull\n",
|
127 |
"else\n",
|
128 |
" # TODO check if cwd is the correct git repo\n",
|
129 |
" # If users use vscode, then we set the default start directory to root of the repo\n",
|
|
|
136 |
"pip install --upgrade pip setuptools wheel\n",
|
137 |
"pip install -r requirements.txt\n",
|
138 |
"\n",
|
|
|
|
|
139 |
"cd models/GroundingDINO/ops\n",
|
140 |
+
"if [ \"${RUNNING_IN_COLAB}\" == \"True\" ]; then\n",
|
141 |
+
" export CUDA_HOME=/usr/local/cuda/\n",
|
142 |
+
" if ! pip install \"/content/drive/MyDrive/MultiScaleDeformableAttention-1.0-cp311-cp311-linux_x86_64.whl\"\n",
|
143 |
+
" then\n",
|
144 |
+
" echo \"failed to install wheel, trying to build from source\";\n",
|
145 |
+
" python3 setup.py build\n",
|
146 |
+
" pip install .\n",
|
147 |
+
" fi\n",
|
148 |
+
"else\n",
|
149 |
+
" # We try to build the module as we dont know what environment we are running on\n",
|
150 |
+
" python3 setup.py build\n",
|
151 |
+
" pip install .\n",
|
152 |
+
"fi\n",
|
153 |
"python3 test.py"
|
154 |
]
|
155 |
},
|
|
|
206 |
" get_device,\n",
|
207 |
" get_args_parser,\n",
|
208 |
" generate_heatmap,\n",
|
209 |
+
" get_xy_from_boxes,\n",
|
210 |
" predict,\n",
|
211 |
")\n",
|
212 |
"args = get_args_parser().parse_args([])\n",
|
|
|
215 |
"model = model.to(device)\n",
|
216 |
"\n",
|
217 |
"run = lambda image, text: predict(model, transform, image, text, None, device)\n",
|
218 |
+
"get_output = lambda image, boxes: (len(boxes), get_xy_from_boxes(image, boxes), generate_heatmap(image, boxes))\n"
|
219 |
]
|
220 |
},
|
221 |
{
|
|
|
289 |
},
|
290 |
{
|
291 |
"cell_type": "code",
|
292 |
+
"execution_count": null,
|
293 |
"metadata": {
|
294 |
"id": "rFXRk-_uuHb_"
|
295 |
},
|
|
|
297 |
"source": [
|
298 |
"from tqdm import tqdm\n",
|
299 |
"import os\n",
|
300 |
+
"import json\n",
|
301 |
+
"def convert_xy_to_json(xy: tuple):\n",
|
302 |
+
" x, y = xy\n",
|
303 |
+
" pts = []\n",
|
304 |
+
" for _x, _y in zip(x.tolist(), y.tolist()):\n",
|
305 |
+
" _x, _y = round(_x, 3), round(_y, 3)\n",
|
306 |
+
" pts.append([_x, _y])\n",
|
307 |
+
"\n",
|
308 |
+
" # List of [x, y] points\n",
|
309 |
+
" return pts\n",
|
310 |
+
"\n",
|
311 |
"def process_zipfile(input_zipfile: Path, text: str):\n",
|
312 |
" if not input_zipfile.exists() or not input_zipfile.is_file() or not os.access(input_zipfile, os.R_OK):\n",
|
313 |
" logger.error(f'Cannot open / read zipfile: {input_zipfile}. Please check if it exists')\n",
|
|
|
319 |
"\n",
|
320 |
" output_zipfile = input_zipfile.parent / f'{input_zipfile.stem}_countgd.zip'\n",
|
321 |
" output_csvfile = input_zipfile.parent / f'{input_zipfile.stem}.csv'\n",
|
322 |
+
" output_xyjson = input_zipfile.parent / f'{input_zipfile.stem}_xy.json'\n",
|
323 |
+
"\n",
|
324 |
+
" xy_map = {}\n",
|
325 |
"\n",
|
326 |
" logger.info(f'Writing outputs to {output_zipfile.name} and {output_csvfile.name} in {input_zipfile.parent} folder')\n",
|
327 |
" with zipfile_writer(output_zipfile) as add_to_zip, csvfile_writer(output_csvfile) as write_row:\n",
|
328 |
" for filename, im in tqdm(images_from_zipfile(input_zipfile)):\n",
|
329 |
+
" try:\n",
|
330 |
+
" boxes, _ = run(im, text)\n",
|
331 |
+
" count, xy, heatmap = get_output(im, boxes)\n",
|
332 |
+
" logger.info(f'Count: {count} - {filename}')\n",
|
333 |
+
" xy_map[filename] = convert_xy_to_json(xy)\n",
|
334 |
+
" write_row({'filename': filename, 'count': count})\n",
|
335 |
+
" add_to_zip(heatmap, filename)\n",
|
336 |
+
" except Exception:\n",
|
337 |
+
" logger.error(f'failed to process {filename}')\n",
|
338 |
+
"\n",
|
339 |
+
" output_xyjson.write_text(json.dumps(xy_map))"
|
340 |
]
|
341 |
},
|
342 |
{
|
|
|
349 |
"\n",
|
350 |
"Use the form on colab to set the parameters, providing the zipfile with input images and a promt text representing the object you want to count.\n",
|
351 |
"\n",
|
352 |
+
"Use the fileupload button to add the zip file to the `countgd` directory or change the path below accordingly.\n",
|
353 |
+
"\n",
|
354 |
"If you are not running on colab, change the values in the next cell\n",
|
355 |
"\n",
|
356 |
"Make sure to run the cell once you change the value."
|