roundabout,
created on Wednesday, 2 April 2025, 11:09:19 (1743592159),
received on Wednesday, 2 April 2025, 11:09:27 (1743592167)
Author identity: vlad <vlad.muntoiu@gmail.com>
d3704a175738fd631fc3d4b2d8e6f85722d2f651
.idea/.gitignore
@@ -0,0 +1,8 @@
# Default ignored files /shelf/ /workspace.xml # Editor-based HTTP Client requests /httpRequests/ # Datasource local storage ignored files /dataSources/ /dataSources.local.xml
.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,107 @@
<component name="InspectionProjectProfileManager"> <profile version="1.0"> <option name="myName" value="Project Default" /> <inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true"> <option name="myValues"> <value> <list size="7"> <item index="0" class="java.lang.String" itemvalue="hx-put" /> <item index="1" class="java.lang.String" itemvalue="hx-vals" /> <item index="2" class="java.lang.String" itemvalue="hx-trigger" /> <item index="3" class="java.lang.String" itemvalue="hx-post" /> <item index="4" class="java.lang.String" itemvalue="hx-headers" /> <item index="5" class="java.lang.String" itemvalue="hx-include" /> <item index="6" class="java.lang.String" itemvalue="hx-swap" /> </list> </value> </option> <option name="myCustomValuesEnabled" value="true" /> </inspection_tool> <inspection_tool class="HtmlUnknownTag" enabled="true" level="WARNING" enabled_by_default="true"> <option name="myValues"> <value> <list size="18"> <item index="0" class="java.lang.String" itemvalue="nobr" /> <item index="1" class="java.lang.String" itemvalue="noembed" /> <item index="2" class="java.lang.String" itemvalue="comment" /> <item index="3" class="java.lang.String" itemvalue="noscript" /> <item index="4" class="java.lang.String" itemvalue="embed" /> <item index="5" class="java.lang.String" itemvalue="script" /> <item index="6" class="java.lang.String" itemvalue="page" /> <item index="7" class="java.lang.String" itemvalue="bigtext" /> <item index="8" class="java.lang.String" itemvalue="iconify-icon" /> <item index="9" class="java.lang.String" itemvalue="x-buttonbox" /> <item index="10" class="java.lang.String" itemvalue="x-frame" /> <item index="11" class="java.lang.String" itemvalue="x-vbox" /> <item index="12" class="java.lang.String" itemvalue="x-hbox" /> <item index="13" class="java.lang.String" itemvalue="x-notebook" /> <item index="14" class="java.lang.String" itemvalue="x-tab" /> <item index="15" class="java.lang.String" itemvalue="x-codeline" /> <item index="16" class="java.lang.String" itemvalue="x-viewport" /> <item index="17" class="java.lang.String" itemvalue="py-script" /> </list> </value> </option> <option name="myCustomValuesEnabled" value="true" /> </inspection_tool> <inspection_tool class="JupyterPackageInspection" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="PyInterpreterInspection" enabled="false" level="WARNING" enabled_by_default="false" /> <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true"> <option name="ignoredPackages"> <value> <list size="10"> <item index="0" class="java.lang.String" itemvalue="pygame" /> <item index="1" class="java.lang.String" itemvalue="numpy" /> <item index="2" class="java.lang.String" itemvalue="requests" /> <item index="3" class="java.lang.String" itemvalue="CairoSVG" /> <item index="4" class="java.lang.String" itemvalue="flask_httpauth" /> <item index="5" class="java.lang.String" itemvalue="flask_migrate" /> <item index="6" class="java.lang.String" itemvalue="flask_babel" /> <item index="7" class="java.lang.String" itemvalue="flask_bcrypt" /> <item index="8" class="java.lang.String" itemvalue="flask_sqlalchemy" /> <item index="9" class="java.lang.String" itemvalue="jinja2-fragments" /> </list> </value> </option> </inspection_tool> <inspection_tool class="PyPep8Inspection" enabled="true" level="TEXT ATTRIBUTES" enabled_by_default="true" editorAttributes="CONSIDERATION_ATTRIBUTES"> <option name="ignoredErrors"> <list> <option value="E501" /> <option value="E402" /> <option value="E741" /> </list> </option> </inspection_tool> <inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true"> <option name="ignoredErrors"> <list> <option value="N802" /> <option value="N806" /> <option value="N803" /> </list> </option> </inspection_tool> <inspection_tool class="PyShadowingBuiltinsInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true"> <option name="ignoredNames"> <list> <option value="input" /> </list> </option> </inspection_tool> <inspection_tool class="PyStubPackagesAdvertiser" enabled="true" level="WARNING" enabled_by_default="true"> <option name="ignoredPackages"> <list> <option value="PyGObject-stubs==0.0.8" /> </list> </option> </inspection_tool> <inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true"> <option name="ignoredIdentifiers"> <list> <option value="main.struct" /> </list> </option> </inspection_tool> </profile> </component>
.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager"> <settings> <option name="USE_PROJECT_PROFILE" value="false" /> <version value="1.0" /> </settings> </component>
.idea/misc.xml
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <project version="4"> <component name="Black"> <option name="sdkName" value="Python 3.12 (recycle4me)" /> </component> <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.12 (recycle4me)" project-jdk-type="Python SDK" /> </project>
.idea/modules.xml
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <project version="4"> <component name="ProjectModuleManager"> <modules> <module fileurl="file://$PROJECT_DIR$/.idea/recycle4me.iml" filepath="$PROJECT_DIR$/.idea/recycle4me.iml" /> </modules> </component> </project>
.idea/recycle4me.iml
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?> <module type="PYTHON_MODULE" version="4"> <component name="NewModuleRootManager"> <content url="file://$MODULE_DIR$"> <excludeFolder url="file://$MODULE_DIR$/.venv" /> </content> <orderEntry type="jdk" jdkName="Python 3.12 (recycle4me)" jdkType="Python SDK" /> <orderEntry type="sourceFolder" forTests="false" /> </component> </module>
.idea/vcs.xml
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <project version="4"> <component name="VcsDirectoryMappings"> <mapping directory="" vcs="Git" /> </component> </project>
download_data.py
@@ -0,0 +1,103 @@
import os import shutil import httpx import tqdm from PIL import Image, ImageOps import tempfile from pathlib import Path query_yaml = """ want: - has: ["waste"] - nature: ["photo"] """ object_types = httpx.get("https://datasets.roundabout-host.com/api/object-types").json() base_types = { "plastic household waste": set(), "glass household waste": set(), "metal household waste": set(), "paper and cardboard": set(), "organic household waste": set(), "household waste": set(), "waste": set(), } def get_objects(object_info): objects = set() for object in object_info["children"]: #print(f"Scanning {object}") info = httpx.get("https://datasets.roundabout-host.com/api/object/" + object).json() objects |= get_objects(info) objects.add(object_info["id"]) return objects for object_name in base_types: object_info = httpx.get("https://datasets.roundabout-host.com/api/object/" + object_name).json() base_types[object_name] = get_objects(object_info) print(object_name, base_types[object_name]) result = {"resources": True} # dummy value to enter the loop photos = [] offset = 0 limit = 192 output = Path("data/") print("Downloading photo metadata...") while result["resources"]: result = httpx.post(f"https://datasets.roundabout-host.com/api/query-pictures?offset={offset}&limit={limit}", data={"query": query_yaml}).json() photos += result["resources"] offset += limit print(f"Received photos {offset-limit} to {offset}") shutil.rmtree(output, ignore_errors=True) os.makedirs(output) class_mapping = { "plastic household waste": 0, "glass household waste": 1, "metal household waste": 2, "paper and cardboard": 3, "organic household waste": 4, "household waste": 5, "waste": 6, } with tempfile.NamedTemporaryFile(delete_on_close=False, mode="wb") as temporary_file: for photo in tqdm.tqdm(photos): # Download the photo result = httpx.get(photo["download"], follow_redirects=True) temporary_file.write(result.content) temporary_file.seek(0) image = Image.open(temporary_file.name, formats=["JPEG"]) ImageOps.exif_transpose(image, in_place=True) image.thumbnail((640, 640)) image.save(output / (str(photo["id"]) + ".jpg")) # Download the annotations with open(output / (str(photo["id"]) + ".txt"), "w") as annotation_file: for region in photo["regions"]: klass = -1 for base_type in base_types: if region["object"] in base_types[base_type]: klass = class_mapping[base_type] break if klass == -1: continue if region["type"] == "bbox": cx = region["shape"]["x"] + region["shape"]["w"] / 2 cy = region["shape"]["y"] + region["shape"]["h"] / 2 w = region["shape"]["w"] h = region["shape"]["h"] elif region["type"] == "polygon": x = [point["x"] for point in region["shape"]] y = [point["y"] for point in region["shape"]] cx = (min(x) + max(x)) / 2 cy = (min(y) + max(y)) / 2 w = max(x) - min(x) h = max(y) - min(y) annotation_file.write(f"{klass} {cx} {cy} {w} {h}\n")