VoxelModel-v1 / caption_filter.py
TobiasLogic's picture
VoxelModel v1: tiny text-to-3D voxel diffusion
49ce4bd verified
Raw
History Blame Contribute Delete
1.99 kB
from __future__ import annotations
import re
MAX_WORDS = 12
SCENE_PATTERNS = [
("variation", r"\bvari(?:ation|ations|ant|ants|ous)\b"),
("set of", r"\bsets?\s+of\b"),
("collection", r"\bcollections?\b"),
("assorted", r"\bassorted\b"),
("multiple", r"\bmultiple\b"),
("pair of", r"\bpairs?\s+of\b"),
("group of", r"\bgroups?\s+of\b"),
("scene", r"\bscenes?\b"),
("elements", r"\belements?\b"),
("featuring", r"\bfeaturing\b"),
("different", r"\bdifferent\b"),
]
MODIFIERS = {
"black", "white", "red", "blue", "green", "yellow", "orange", "purple",
"pink", "brown", "gray", "grey", "gold", "golden", "silver", "bronze",
"copper", "beige", "tan", "teal", "cyan", "magenta", "maroon", "navy",
"ivory", "cream", "turquoise", "lavender", "olive", "crimson", "scarlet",
"dark", "light", "pale", "bright", "deep", "pastel", "neon", "striped",
"wooden", "wood", "metal", "metallic", "plastic", "stone", "glass",
"steel", "iron", "brick", "concrete", "leather", "fabric", "marble",
}
_WORD = re.compile(r"[a-z][a-z'-]*")
_AND = re.compile(r"\band\b")
def _joins_noun_phrases(text):
parts = _AND.split(text)
if len(parts) < 2:
return False
for left, right in zip(parts[:-1], parts[1:]):
if "," in left:
return True
lw = _WORD.findall(left)
rw = _WORD.findall(right)
if not lw or not rw:
return True
if lw[-1] in MODIFIERS and rw[0] in MODIFIERS:
continue
return True
return False
def reject_reason(caption):
if not caption or not caption.strip():
return "empty"
text = caption.lower()
if len(caption.split()) > MAX_WORDS:
return "too long"
for name, pattern in SCENE_PATTERNS:
if re.search(pattern, text):
return name
if _joins_noun_phrases(text):
return "and"
return None
def is_single_object(caption):
return reject_reason(caption) is None