Skip to content

Commit

Permalink
Enums, more resize flexibility
Browse files Browse the repository at this point in the history
  • Loading branch information
zeptofine committed Oct 18, 2023
1 parent 7a630c5 commit 2c366e9
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 98 deletions.
2 changes: 1 addition & 1 deletion imdataset_creator/datarules/base_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def get_field(self, field_name: str, args: Sequence[Any], kwargs: Mapping[str, A


DEFAULT_OUTPUT_FORMAT = "{relative_path}/{file}.{ext}"
PLACEHOLDER_FORMAT_FILE = File("/folder/subfolder/to/file.png", "/folder", "subfolder/to", "file", ".png")
PLACEHOLDER_FORMAT_FILE = File.from_src(Path("/folder"), Path("/folder/subfolder/to/file.png"))
PLACEHOLDER_FORMAT_KWARGS = PLACEHOLDER_FORMAT_FILE.to_dict()


Expand Down
9 changes: 2 additions & 7 deletions imdataset_creator/datarules/dataset_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,14 @@
from typing import Generator, Literal, TypeVar, overload

import polars as pl
from polars import DataFrame, Expr, Series
from polars import DataFrame, Expr
from polars.type_aliases import SchemaDefinition

from ..configs import MainConfig
from ..file import File
from ..scenarios import FileScenario, OutputScenario
from .base_rules import (
Comparable,
DataTypeSchema,
ExprDict,
FastComparable,
Input,
Output,
Producer,
ProducerSchema,
ProducerSet,
Expand Down Expand Up @@ -242,6 +237,7 @@ def populate_chunks(
db_schema = self.type_schema
chunk: DataFrame
for chunk in chunks:
# current_paths = list(chunk.get_column("path")) # used for debugging
for schema in schemas:
chunk = chunk.with_columns(**schema)
chunk = chunk.select(db_schema)
Expand Down Expand Up @@ -332,4 +328,3 @@ def comply_to_schema(self, schema: SchemaDefinition, in_place: bool = False) ->
if in_place:
self.__df = new_df
return new_df

1 change: 0 additions & 1 deletion imdataset_creator/datarules/image_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ def __call__(self) -> ProducerSchema:
return [{"hash": col("path").apply(self._hash_img)}]

def _hash_img(self, pth) -> str:
assert self.hasher is not None
return str(self.hasher(Image.open(pth)))


Expand Down
39 changes: 31 additions & 8 deletions imdataset_creator/file.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,36 @@
import os
from dataclasses import dataclass
from pathlib import Path

from .configs.keyworded import fancy_repr


class MalleablePath(str):
def __format__(self, format_spec):
formats = format_spec.split(",")
newfmt: MalleablePath = self
for fmt in formats:
if "=" in fmt:
key, val = fmt.split("=")
if key == "maxlen":
newfmt = MalleablePath(newfmt[: int(val)])
else:
raise ValueError(f"Unknown format specifier: {key}")
elif fmt == "underscores":
newfmt = MalleablePath("_".join(self.split(" ")))
elif fmt == "underscore_path":
newfmt = MalleablePath("_".join(Path(self).parts))

return str(newfmt)


@fancy_repr
@dataclass(frozen=True)
class File:
absolute_pth: str
src: str
relative_path: str
file: str
absolute_pth: MalleablePath
src: MalleablePath
relative_path: MalleablePath
file: MalleablePath
ext: str

def to_dict(self):
Expand All @@ -22,9 +45,9 @@ def to_dict(self):
@classmethod
def from_src(cls, src: Path, pth: Path):
return cls(
absolute_pth=str(pth.resolve()),
src=str(src),
relative_path=str(pth.relative_to(src).parent),
file=pth.stem,
absolute_pth=MalleablePath(pth.resolve()),
src=MalleablePath(src),
relative_path=MalleablePath(pth.relative_to(src).parent),
file=MalleablePath(pth.stem),
ext=pth.suffix[1:],
)
45 changes: 35 additions & 10 deletions imdataset_creator/gui/output_filters.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
from PySide6.QtCore import QSize
from PySide6.QtWidgets import QDoubleSpinBox, QLabel, QSpinBox
from PySide6.QtWidgets import (
QCheckBox,
QComboBox,
QDoubleSpinBox,
QFrame,
QLabel,
QLineEdit,
QProgressBar,
QPushButton,
QSlider,
QSpinBox,
QToolButton,
QWidget,
)

from ..datarules.base_rules import Filter
from ..image_filters import destroyers, resizer
Expand Down Expand Up @@ -34,13 +47,16 @@ class ResizeFilterView(FilterView):
bound_item = resizer.Resize

def configure_settings_group(self):
self.resize_mode = QComboBox(self)
self.resize_mode.addItems(resizer.ResizeMode._member_names_)
self.scale = QDoubleSpinBox(self)
self.scale.setSuffix("%")
self.scale.setMinimum(1)
self.scale.setMaximum(1_000)
self.scale.setMaximum(100_000)

self.group_grid.addWidget(QLabel("Scale:", self), 0, 0)
self.group_grid.addWidget(self.scale, 0, 1)
self.group_grid.addWidget(QLabel("Resize mode: ", self), 0, 0)
self.group_grid.addWidget(self.resize_mode, 0, 1)
self.group_grid.addWidget(QLabel("Scale:", self), 1, 0)
self.group_grid.addWidget(self.scale, 1, 1)

def reset_settings_group(self):
self.scale.setValue(100)
Expand Down Expand Up @@ -89,6 +105,15 @@ def get_config(self) -> resizer.CropData:
"height": val if (val := self.height_box.value()) else None,
}

@classmethod
def from_config(cls, cfg: resizer.CropData, parent=None):
self = cls(parent)
self.left_box.setValue(cfg["left"] or 0)
self.top_box.setValue(cfg["top"] or 0)
self.width_box.setValue(cfg["width"] or 0)
self.height_box.setValue(cfg["height"] or 0)
return self


class BlurFilterView(FilterView):
title = "Blur"
Expand All @@ -97,7 +122,7 @@ class BlurFilterView(FilterView):
bound_item = destroyers.Blur

def configure_settings_group(self):
self.algorithms = MiniCheckList(destroyers.AllBlurAlgos, self)
self.algorithms = MiniCheckList(destroyers.BlurAlgorithm._member_names_, self)
self.scale = QDoubleSpinBox(self)
scale_label = QLabel("Scale:", self)
tooltip(scale_label, TOOLTIPS["blur_scale"])
Expand Down Expand Up @@ -134,14 +159,14 @@ def get_config(self) -> destroyers.BlurData:
{
"algorithms": algos,
"blur_range": [self.blur_range_x.value(), self.blur_range_y.value()],
"scale": self.scale.value() / 100,
"scale": self.scale.value(),
}
)

@classmethod
def from_config(cls, cfg, parent=None):
self = cls(parent)
self.scale.setValue(cfg["scale"] * 100)
self.scale.setValue(cfg["scale"])
for item in cfg["algorithms"]:
self.algorithms.set_config(item, True)
r_x, r_y = cfg["blur_range"]
Expand All @@ -158,7 +183,7 @@ class NoiseFilterView(FilterView):
bound_item = destroyers.Noise

def configure_settings_group(self):
self.algorithms = MiniCheckList(destroyers.AllNoiseAlgos, self)
self.algorithms = MiniCheckList(destroyers.NoiseAlgorithm._member_names_, self)
self.scale = QDoubleSpinBox(self)
self.scale.setSuffix("%")
self.scale.setMinimum(1)
Expand Down Expand Up @@ -215,7 +240,7 @@ class CompressionFilterView(FilterView):
bound_item = destroyers.Compression

def configure_settings_group(self):
self.algorithms = MiniCheckList(destroyers.AllCompressionAlgos, self)
self.algorithms = MiniCheckList(destroyers.CompressionAlgorithms._member_names_, self)
self.group_grid.addWidget(self.algorithms, 0, 0, 1, 3)

# jpeg quality
Expand Down
10 changes: 6 additions & 4 deletions imdataset_creator/gui/rule_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,12 @@ def get_config_wrapper(self: RuleView):
def set_requires(self, val):
newdesc = self.__original_desc
if val:
newdesc += f"\n requires: {val}"
newdesc = newdesc + ("\n" if newdesc else "") + f"requires: {val}"
print("updated requires")
self.desc = newdesc
self.description_widget.setText(newdesc)
if not self.description_widget.isVisible():
self.description_widget.show()


class ItemsUnusedError(ValueError):
Expand Down Expand Up @@ -157,8 +160,8 @@ def reset_settings_group(self):
def get(self):
super().get()
return data_rules.BlackWhitelistRule(
self.whitelist.toPlainText().splitlines(),
self.blacklist.toPlainText().splitlines(),
whitelist=self.whitelist.toPlainText().splitlines(),
blacklist=self.blacklist.toPlainText().splitlines(),
)

def get_config(self) -> data_rules.BlackWhitelistData:
Expand Down Expand Up @@ -238,7 +241,6 @@ def reset_settings_group(self):
self.crop.setChecked(True)

def get(self):
super().get()
return image_rules.ResRule(
min_res=self.min.value(),
max_res=self.max.value(),
Expand Down
Loading

0 comments on commit 2c366e9

Please sign in to comment.