انتقل إلى المحتوى الرئيسي

الوحدة 4 — من نصّ إلى صورة ومن صورة إلى صورة

الكرسيّ المرجعيّ خرج جميلًا من الوحدة 3. الآن يطلب مدير التسويق نفس الكرسيّ بلون فيروزيّ، ثمّ بأصفر ذهبيّ، ثمّ بأحمر خمريّ، مع الحفاظ على نفس الزاوية ونفس الإضاءة. إعادة توليد من الصفر بتعليمة جديدة لن تعطي «نفس الكرسيّ»، بل كراسٍ مختلفة. هنا يدخل مسار صورة إلى صورة (img2img)، وهو المسار الذي يميّز عمل المحترف عن الهاوي.

الفرق الجوهريّ بين المسارَين

  • نصّ إلى صورة: يبدأ من latent عشوائيّ خالص، ويُزيل الضجيج على مدى كلّ الخطوات.
  • صورة إلى صورة: يبدأ من latent مأخوذ من صورة موجودة (تُرمَّز بـVAE)، ثمّ يُضيف عليها ضجيجًا جزئيًّا، ثمّ يُزيل هذا الضجيج بتعليمة جديدة.

المعلمة الحاسمة هي قوّة الضجيج (strength أو denoising strength)، بين 0 و1:

  • 0.0: لا يُضاف ضجيج، تخرج الصورة كما هي بلا تغيير.
  • 0.2-0.4: تعديل بصريّ محدود (لون، ملمس)، يبقى التكوين والوضعيّة والحجم كما هي.
  • 0.5-0.7: تعديل كبير مع بقاء العناصر الرئيسيّة قابلة للتعرّف.
  • 0.8-0.95: تعديل كامل تقريبًا، لا تبقى إلّا فكرة عامّة عن التكوين.
  • 1.0: يعادل نصّ إلى صورة بلا مرجع.

تحويل الكرسيّ إلى ثلاثة ألوان

نأخذ صورة الكرسيّ من الوحدة 3، ونطلب متغيّرات ألوان مع الحفاظ على البقيّة:

import torch
from PIL import Image
from diffusers import StableDiffusionXLImg2ImgPipeline

pipe_img2img = StableDiffusionXLImg2ImgPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16,
variant="fp16",
).to("cuda")

image_ref = Image.open("chaise_reference.png").convert("RGB")

couleurs = ["turquoise blue", "golden yellow", "burgundy red"]
for couleur in couleurs:
prompt = (
f"wooden Scandinavian chair with {couleur} upholstery, "
"professional product photography, three-quarter front view, "
"soft studio lighting, 85mm lens, sharp focus"
)
resultat = pipe_img2img(
prompt=prompt,
image=image_ref,
strength=0.35, # التغيير الأساسيّ هنا
guidance_scale=7.0,
num_inference_steps=30,
).images[0]
resultat.save(f"chaise_{couleur.replace(' ', '_')}.png")

قيمة strength=0.35 تُغيّر اللون والملمس بلا تحريك القوائم ولا الظلال. لو رفعناها إلى 0.7 لخرج كرسيّ بلون مطلوب لكن بشكل مختلف، ولو خفّضناها إلى 0.15 لبقي اللون الأصليّ ظاهرًا. الرقم الدقيق يعتمد على المرجع؛ ابدأ 0.3 وارفع بخطوة 0.05.

الحفاظ على التكوين

ثلاثة أشياء تُخرَّب سريعًا في مسار صورة إلى صورة إن لم يُنتبَه لها:

  1. الدقّة. الصورة المرجعيّة تُقاس إلى دقّة تشغيل النموذج (1024×1024 لـSDXL). صورة مرجعيّة 512×512 تُكبَّر أوّلًا وتفقد حدّتها. حضّر صورك في دقّة النموذج مسبقًا.
  2. نسبة العرض إلى الارتفاع. SDXL يدعم رسميًّا 1024×1024، 1152×896، 896×1152، 1216×832، 832×1216. تمرير 1440×810 يخرج مقطوعًا أو مشوّهًا. أعِد قصّ الصورة إلى نسبة مدعومة قبل التمرير.
  3. قوّة الضجيج مقابل عدد الخطوات. المعادلة الفعليّة: عدد الخطوات المُطبَّقة = strength × num_inference_steps. strength=0.35 مع 30 خطوة يعطي 10 خطوات إزالة ضجيج. لهذا لا يُنصَح بـstrength منخفض جدًّا (<0.15) لأنّ 3 خطوات لا تكفي لتوليد نظيف.

تشغيل المسارَين معًا: الأنبوب

المسار الأقوى في الاستوديو المهنيّ يجمع الاثنين في سلسلة:

  1. توليد أوّليّ بنصّ إلى صورة بـSDXL base، 30 خطوة، للحصول على تكوين جيّد.
  2. تحسين بصورة إلى صورة بـSDXL refiner، strength=0.3، 15 خطوة، للحصول على تفاصيل حادّة.
  3. متغيّرات لونيّة بصورة إلى صورة على النتيجة النهائيّة، strength=0.35، لخطّ منتجات كامل.
from diffusers import StableDiffusionXLPipeline, StableDiffusionXLImg2ImgPipeline

base = StableDiffusionXLPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16, variant="fp16",
).to("cuda")

refiner = StableDiffusionXLImg2ImgPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-refiner-1.0",
torch_dtype=torch.float16, variant="fp16",
).to("cuda")

image_base = base(prompt=prompt, num_inference_steps=30, guidance_scale=6.0).images[0]
image_finale = refiner(prompt=prompt, image=image_base, strength=0.3, num_inference_steps=15).images[0]

متى نُفضّل مسارًا على آخر

  • جديد كليًّا (لم يوجد قبلًا): نصّ إلى صورة. مثال: كرسيّ جديد لخطّ منتجات جديد.
  • تعديل صورة موجودة مع الحفاظ على أغلبها (تلوين، ملمس، خامة): صورة إلى صورة بـstrength منخفض.
  • إعادة تصوّر جذريّة (نفس الفكرة، تكوين جديد كليًّا): نصّ إلى صورة مع تعليمة موجّهة.
  • تعديل جزء محدود من الصورة (استبدال ذراع، إزالة عنصر): الرسم الداخليّ (inpainting)، الوحدة القادمة.

الخيط الأحمر: كتالوج الكرسيّ الواحد

بعد هذه الوحدة، نمتلك:

  • صورة مرجعيّة نظيفة للكرسيّ الأساسيّ (نصّ إلى صورة).
  • ثلاث متغيّرات لونيّة (صورة إلى صورة).
  • ثلاث زوايا مختلفة (نصّ إلى صورة بتعليمات مختلفة، نفس البذرة لتكوين متسّق).

هذه تسع صور مُنتجة في أقلّ من ربع ساعة على GPU متوسّطة، تصلح للنشر في كتالوج أوّليّ. الوحدة القادمة ستُصلح تفصيلًا مزعجًا في واحدة منها بدقّة جراحيّة.

قاعدة قرار

إذا كنت تُعيد كتابة نفس التعليمة مع تعديل صغير في اللون أو الملمس، فأنت تحتاج صورة إلى صورة لا نصّ إلى صورة. توفير الوقت والاتّساق البصريّ يستحقّ خمس دقائق تعلّم إضافيّة.

الخلاصة

  • نصّ إلى صورة ينشئ من الصفر؛ صورة إلى صورة يعدّل من موجود.
  • قوّة الضجيج (strength) هي المفتاح: 0.35 للتعديلات اللونيّة، 0.7 لإعادة تصوّر جزئيّة.
  • التكوين يُحفَظ بـstrength منخفض ودقّة صحيحة ونسبة عرض مدعومة.
  • الأنبوب المهنيّ يجمع base + refiner + متغيّرات لونيّة في سلسلة قصيرة تُنتج كتالوجًا كاملًا.