File size: 13,646 Bytes
84b7171 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | import customtkinter as ctk
from tkinter import filedialog, messagebox, StringVar, Menu, DoubleVar
from PIL import Image, ImageTk, ImageEnhance
import numpy as np
import torch
import random
import cv2
import time
# Geräteauswahl (CUDA wenn verfügbar)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Verwendetes Gerät: {device}")
# Klasse für die Verbindung zwischen Knoten
class Connection:
def __init__(self, target_node, weight=None):
self.target_node = target_node
self.weight = weight if weight is not None else random.uniform(0.1, 1.0)
self.weight_history = []
# Klasse für den Knoten im neuronalen Netzwerk
class Node:
def __init__(self, label):
self.label = label
self.connections = []
self.activation = 0.0
self.activation_history = []
def add_connection(self, target_node, weight=None):
self.connections.append(Connection(target_node, weight))
def propagate_signal(self, input_signal):
self.activation = max(0, input_signal) # Keine negativen Aktivierungen
self.activation_history.append(self.activation)
for connection in self.connections:
connection.target_node.activation += self.activation * connection.weight
connection.weight_history.append(connection.weight)
# Klasse für den Bildknoten
class ImageNode(Node):
def __init__(self, label):
super().__init__(label)
self.image = None
def generate_image(self, category_nodes, original_image, brightness_factor, contrast_factor):
self.image = self.generate_image_from_categories(category_nodes, original_image, brightness_factor, contrast_factor)
def generate_image_from_categories(self, category_nodes, original_image, brightness_factor, contrast_factor):
image_array = np.array(original_image) / 255.0 # Normalisiere Originalbild auf [0, 1]
image_tensor = torch.tensor(image_array, dtype=torch.float32).permute(2, 0, 1).to(device) # Zu Tensor konvertieren und auf das Gerät verschieben
modified_image_tensor = self.process_image(image_tensor, category_nodes, brightness_factor, contrast_factor)
return modified_image_tensor
def process_image(self, image_tensor, category_nodes, brightness_factor, contrast_factor):
modified_image_tensor = image_tensor.clone()
for x in range(modified_image_tensor.shape[1]):
for y in range(modified_image_tensor.shape[2]):
pixel = modified_image_tensor[:, x, y]
brightness = float(brightness_factor)
contrast = float(contrast_factor)
for node in category_nodes:
brightness += node.activation * 0.1
contrast += node.activation * 0.1
pixel = torch.clamp((pixel - 0.5) * contrast + 0.5 + brightness, 0, 1)
modified_image_tensor[:, x, y] = pixel
return modified_image_tensor
def get_color_from_label(self, label):
color_map = {
"Rot": torch.tensor([1, 0, 0], device=device),
"Grün": torch.tensor([0, 1, 0], device=device),
"Blau": torch.tensor([0, 0, 1], device=device),
"Gelb": torch.tensor([1, 1, 0], device=device),
"Cyan": torch.tensor([0, 1, 1], device=device),
"Magenta": torch.tensor([1, 0, 1], device=device)
}
return color_map.get(label, torch.tensor([1, 1, 1], device=device))
# Funktion zum Extrahieren der Hauptfarbwerte aus dem Bild
def extract_main_colors(image):
image_array = np.array(image)
colors = {}
for i in range(image_array.shape[0]):
for j in range(image_array.shape[1]):
color = tuple(image_array[i, j])
if sum(color) > 30: # Vermeiden von sehr dunklen Farben
if color in colors:
colors[color] += 1
else:
colors[color] = 1
# Sortieren nach Häufigkeit und die häufigsten Farben auswählen
sorted_colors = sorted(colors.items(), key=lambda item: item[1], reverse=True)
main_colors = [color for color, count in sorted_colors[:6]] # Nehmen Sie die 6 häufigsten Farben
# Skalieren der Farben auf einen helleren Bereich
scaled_colors = [(min(c[0] + 50, 255), min(c[1] + 50, 255), min(c[2] + 50, 255)) for c in main_colors]
return scaled_colors
# Funktion zum Erstellen des neuronalen Netzwerks
def create_neural_network(main_colors):
category_nodes = [Node(label) for label in ["Rot", "Grün", "Blau", "Gelb", "Cyan", "Magenta"]]
for node in category_nodes:
for target_node in category_nodes:
if node != target_node:
node.add_connection(target_node, weight=random.uniform(0.01, 8.0))
return category_nodes
# Funktion zum Speichern des Bildes
def save_image(image_tensor, filename, resolution, original_size=None):
resolutions = {
"HD": (1280, 720),
"Full HD": (1920, 1080),
"2K": (2048, 2048),
"4K": (5760, 3240),
"8K": (10670, 6000),
"Cover": (1024, 1024),
"Original (2K)": (2048,2048)
}
if resolution == "Original (2K)" and original_size:
width, height = original_size
else:
width, height = resolutions.get(resolution, (1920, 1080))
image = Image.fromarray((image_tensor.cpu().numpy().transpose(1, 2, 0) * 255).astype(np.uint8))
image = image.resize((width, height), Image.Resampling.LANCZOS)
image.save(filename, format='PNG') # Speichern als PNG
print(f"Bild erfolgreich gespeichert als {filename} mit Auflösung {resolution}")
# Funktion zum Schärfen des Bildes
def sharpen_image(image):
enhancer = ImageEnhance.Sharpness(image)
sharpened_image = enhancer.enhance(1.5) # Schärfe um 1.5 erhöhen
return sharpened_image
# Funktion zum Anpassen von Helligkeit und Kontrast
def match_histogram(source, template):
source = cv2.cvtColor(np.array(source), cv2.COLOR_RGB2LAB).astype("float32")
template = cv2.cvtColor(np.array(template), cv2.COLOR_RGB2LAB).astype("float32")
(l, a, b) = cv2.split(source)
(lH, aH, bH) = cv2.split(template)
# Anwenden von CLAHE nur auf den L-Kanal
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
l = clahe.apply((l * 255).astype(np.uint8)) / 255.0
# Anwenden von Histogram-Matching auf die a- und b-Kanäle
a = cv2.equalizeHist((a * 255).astype(np.uint8)) / 255.0
b = cv2.equalizeHist((b * 255).astype(np.uint8)) / 255.0
result = cv2.merge((l, a, b))
result = cv2.cvtColor(result.astype("uint8"), cv2.COLOR_LAB2RGB)
return Image.fromarray(result)
# GUI-Funktion zum Laden des Bildes und Einstellungen vornehmen
def load_image():
file_path = filedialog.askopenfilename(filetypes=[("Image Files", "*.png;*.jpg;*.jpeg;*.bmp;*.gif")])
if file_path:
image = Image.open(file_path)
# Speichern der originalen Bildgröße für "Original (2K)"
global original_image_size
original_image_size = image.size
image = image.resize((1920, 1080), Image.Resampling.LANCZOS)
img_tk = ImageTk.PhotoImage(image)
image_label.configure(image=img_tk)
image_label.image = img_tk
global loaded_image
loaded_image = image
# Initialisieren der Slider-Positionen mit den Helligkeits- und Kontrastwerten des geladenen Bildes
global brightness_var, contrast_var
brightness_value = calculate_brightness(image)
contrast_value = calculate_contrast(image)
brightness_var.set(brightness_value)
contrast_var.set(contrast_value)
print(f"Bild geladen: {file_path}")
def calculate_brightness(image):
image_array = np.array(image).astype(float)
mean_brightness = np.mean(image_array) / 255.0 # Normalisieren auf den Bereich [0, 1]
# Verschieben des Bereichs von [0, 1] auf [-1, 1] für den Slider
return (mean_brightness * 2) -1
def calculate_contrast(image):
image_array = np.array(image).astype(float)
mean_brightness = np.mean(image_array)
# Berechnung der Standardabweichung und des Kontrasts basierend auf der Helligkeitsvariation
std_dev = np.std(image_array)
contrast = (std_dev / 128.0) # Skalierung des Kontrasts auf einen Bereich um 1
# Stärkere Kontraste nach oben, schwächere nach unten anpassen
contrast = (contrast * 1.0) + 1.0
contrast = max(0.5, min(2.0, contrast)) # Begrenzung des Kontrasts
return contrast
# GUI-Funktion zum Generieren des Bildes
def generate_image():
if loaded_image:
start_time = time.time() # Startzeit messen
# Extrahieren der Hauptfarbwerte aus dem Bild
main_colors = extract_main_colors(loaded_image)
print(f"Hauptfarbwerte: {main_colors}")
# Validierung: Sicherstellen, dass mindestens sechs Farben vorhanden sind
if len(main_colors) < 6 or all(sum(color) < 150 for color in main_colors):
print("Hauptfarben zu dunkel oder zu wenige Farben, Standardfarben werden verwendet.")
main_colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (0, 255, 255), (255, 0, 255)] # Standardfarben
# Konvertiere die Farben in normale Aktivierungswerte zwischen 0 und 1
main_colors = [(r / 255.0, g / 255.0, b / 255.0) for r, g, b in main_colors]
# Erstellen des neuronalen Netzwerks
category_nodes = create_neural_network(main_colors)
# Setze initiale Aktivierungen basierend auf den Hauptfarben
for node, color in zip(category_nodes, main_colors):
node.activation = sum(color) / 3 # Durchschnittliche Helligkeit als Aktivierung
print(f"Knoten {node.label}: Aktivierung = {node.activation}, Farbe = {color}")
# Erstellen und Verarbeiten des Bildes
brightness_factor = brightness_var.get()
contrast_factor = contrast_var.get()
image_node = ImageNode("Image")
image_node.generate_image(category_nodes, loaded_image, brightness_factor, contrast_factor)
# Anzeigen des generierten Bildes
generated_image = Image.fromarray((image_node.image.cpu().numpy().transpose(1, 2, 0) * 255).astype(np.uint8))
generated_image = sharpen_image(generated_image) # Schärfen des Bildes
generated_image = match_histogram(generated_image, loaded_image) # Helligkeit und Kontrast anpassen
generated_image = generated_image.resize((64, 64), Image.Resampling.LANCZOS)
img_tk = ImageTk.PhotoImage(generated_image)
generated_image_label.configure(image=img_tk)
generated_image_label.image = img_tk
# Speichern des generierten Bildes
resolution = resolution_var.get()
save_image(image_node.image, "kunst.png", resolution, original_size=original_image_size if resolution == "Original (2K)" else None) # Speichern als PNG
end_time = time.time() # Endzeit messen
generation_time = end_time - start_time
print(f"Bild erfolgreich generiert und angezeigt. Generierungszeit: {generation_time:.2f} Sekunden")
else:
messagebox.showwarning("Warnung", "Bitte laden Sie zuerst ein Bild.")
# GUI-Funktion zum Starten der GUI
def start_gui():
global image_label, generated_image_label, loaded_image, resolution_var, brightness_var, contrast_var, original_image_size
loaded_image = None
original_image_size = None
ctk.set_appearance_mode("dark") # Setzen Sie das Erscheinungsbildmodus auf "dark"
ctk.set_default_color_theme("blue") # Setzen Sie das Standardfarbthema auf "blue"
root = ctk.CTk()
root.title("Bildgenerierung")
root.geometry("550x400")
# Menü hinzufügen
menubar = Menu(root)
root.config(menu=menubar)
file_menu = Menu(menubar, tearoff=0)
menubar.add_cascade(label="Datei", menu=file_menu)
file_menu.add_command(label="Bild laden", command=load_image)
file_menu.add_command(label="Bild generieren", command=generate_image)
file_menu.add_separator()
file_menu.add_command(label="Beenden", command=root.quit)
resolution_var = StringVar(value="Full HD")
resolution_label = ctk.CTkLabel(root, text="Bildauflösung:")
resolution_label.pack(pady=5)
resolution_combobox = ctk.CTkComboBox(root, variable=resolution_var, values=["HD", "2K", "Full HD", "4K", "8K", "Cover", "Original (2K)"])
resolution_combobox.pack(pady=5)
brightness_var = DoubleVar(value=0.0)
brightness_label = ctk.CTkLabel(root, text="Helligkeit:")
brightness_label.pack(pady=5)
brightness_scale = ctk.CTkSlider(root, from_=-1.0, to=1.0, number_of_steps=20, orientation=ctk.HORIZONTAL, variable=brightness_var)
brightness_scale.pack(pady=5)
contrast_var = DoubleVar(value=1.0)
contrast_label = ctk.CTkLabel(root, text="Kontrast:")
contrast_label.pack(pady=5)
contrast_scale = ctk.CTkSlider(root, from_=0.5, to=2.0, number_of_steps=15, orientation=ctk.HORIZONTAL, variable=contrast_var)
contrast_scale.pack(pady=5)
image_label = ctk.CTkLabel(root)
image_label.pack(pady=10)
generated_image_label = ctk.CTkLabel(root)
generated_image_label.pack(pady=10)
root.mainloop()
if __name__ == "__main__":
start_gui() |