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")