Texture_Image_Generation / generate_dataset.py
Afnaan
Deploy Texture Image Generation App
b396ca1
Raw
History Blame Contribute Delete
5.76 kB
"""
Procedurally generate a synthetic texture dataset for DCGAN training.
Generates 5 texture types: wood, marble, fabric, brick, noise.
Each type produces 200 images → 1000 total, saved to data/textures/<type>/.
"""
import os
import random
import numpy as np
from PIL import Image, ImageFilter, ImageDraw
IMG_SIZE = 64
NUM_PER_CLASS = 200
OUTPUT_DIR = os.path.join("data", "textures")
TEXTURE_TYPES = ["wood", "marble", "fabric", "brick", "noise"]
def generate_wood(size=IMG_SIZE):
"""Simulate wood grain using sine waves + noise."""
arr = np.zeros((size, size, 3), dtype=np.uint8)
freq = random.uniform(3, 8)
phase = random.uniform(0, np.pi * 2)
for y in range(size):
for x in range(size):
grain = np.sin(freq * y / size * np.pi * 2 + phase + random.gauss(0, 0.05))
r = int(np.clip(120 + 60 * grain + random.randint(-10, 10), 80, 200))
g = int(np.clip(70 + 30 * grain + random.randint(-10, 10), 40, 130))
b = int(np.clip(30 + 10 * grain + random.randint(-5, 5), 10, 70))
arr[y, x] = [r, g, b]
img = Image.fromarray(arr)
img = img.filter(ImageFilter.GaussianBlur(radius=0.5))
return img
def generate_marble(size=IMG_SIZE):
"""Simulate marble veins using Perlin-like noise."""
arr = np.zeros((size, size, 3), dtype=np.uint8)
scale = random.uniform(0.05, 0.15)
for y in range(size):
for x in range(size):
val = np.sin(x * scale + y * scale * 0.5 + random.gauss(0, 0.3)) * 0.5 + 0.5
base = int(200 + 40 * val)
r = int(np.clip(base + random.randint(-5, 5), 150, 255))
g = int(np.clip(base - 10 + random.randint(-5, 5), 140, 245))
b = int(np.clip(base - 5 + random.randint(-5, 5), 145, 250))
arr[y, x] = [r, g, b]
img = Image.fromarray(arr)
img = img.filter(ImageFilter.GaussianBlur(radius=0.3))
return img
def generate_fabric(size=IMG_SIZE):
"""Simulate woven fabric using a grid pattern."""
arr = np.zeros((size, size, 3), dtype=np.uint8)
thread_size = random.randint(3, 6)
hue_r = random.randint(50, 200)
hue_g = random.randint(50, 200)
hue_b = random.randint(50, 200)
for y in range(size):
for x in range(size):
is_warp = (x // thread_size) % 2 == 0
is_weft = (y // thread_size) % 2 == 0
if is_warp and not is_weft:
factor = 1.2
elif not is_warp and is_weft:
factor = 0.8
else:
factor = 1.0
r = int(np.clip(hue_r * factor + random.randint(-5, 5), 0, 255))
g = int(np.clip(hue_g * factor + random.randint(-5, 5), 0, 255))
b = int(np.clip(hue_b * factor + random.randint(-5, 5), 0, 255))
arr[y, x] = [r, g, b]
return Image.fromarray(arr)
def generate_brick(size=IMG_SIZE):
"""Simulate brick wall pattern."""
img = Image.new("RGB", (size, size), color=(180, 80, 50))
draw = ImageDraw.Draw(img)
brick_h = random.randint(8, 12)
brick_w = random.randint(16, 24)
mortar_color = (200, 190, 180)
for row in range(size // brick_h + 1):
y = row * brick_h
offset = (brick_w // 2) if row % 2 else 0
# Horizontal mortar line
draw.line([(0, y), (size, y)], fill=mortar_color, width=1)
# Vertical mortar lines
for col in range(-1, size // brick_w + 2):
x = col * brick_w + offset
draw.line([(x, y), (x, y + brick_h)], fill=mortar_color, width=1)
# Add slight noise
arr = np.array(img)
noise = np.random.randint(-15, 15, arr.shape, dtype=np.int16)
arr = np.clip(arr.astype(np.int16) + noise, 0, 255).astype(np.uint8)
return Image.fromarray(arr)
def generate_noise(size=IMG_SIZE):
"""Generate colorful noise texture."""
mode = random.choice(["perlin_like", "color_bands", "static"])
if mode == "static":
arr = np.random.randint(0, 255, (size, size, 3), dtype=np.uint8)
elif mode == "color_bands":
arr = np.zeros((size, size, 3), dtype=np.uint8)
for y in range(size):
r = int((np.sin(y * 0.3) * 0.5 + 0.5) * 255)
g = int((np.cos(y * 0.2) * 0.5 + 0.5) * 255)
b = int((np.sin(y * 0.5 + 1) * 0.5 + 0.5) * 255)
arr[y, :] = [r, g, b]
noise = np.random.randint(-30, 30, arr.shape, dtype=np.int16)
arr = np.clip(arr.astype(np.int16) + noise, 0, 255).astype(np.uint8)
else:
arr = np.zeros((size, size, 3), dtype=np.uint8)
scale = random.uniform(0.1, 0.3)
for y in range(size):
for x in range(size):
v = int((np.sin(x * scale) * np.cos(y * scale) * 0.5 + 0.5) * 255)
arr[y, x] = [v, int(v * 0.7), int(v * 0.4)]
img = Image.fromarray(arr)
img = img.filter(ImageFilter.GaussianBlur(radius=0.5))
return img
GENERATORS = {
"wood": generate_wood,
"marble": generate_marble,
"fabric": generate_fabric,
"brick": generate_brick,
"noise": generate_noise,
}
def main():
total = 0
for texture_type in TEXTURE_TYPES:
out_dir = os.path.join(OUTPUT_DIR, texture_type)
os.makedirs(out_dir, exist_ok=True)
gen_fn = GENERATORS[texture_type]
print(f"Generating {NUM_PER_CLASS} '{texture_type}' textures...")
for i in range(NUM_PER_CLASS):
img = gen_fn(IMG_SIZE)
img.save(os.path.join(out_dir, f"{texture_type}_{i:04d}.png"))
total += 1
print(f" OK Saved {NUM_PER_CLASS} images to {out_dir}")
print(f"\n Dataset generation complete! Total images: {total}")
print(f" Saved to: {os.path.abspath(OUTPUT_DIR)}")
if __name__ == "__main__":
main()