כיצד לשלב צביעה ב-AI לתמונות שחור-לבן באפליקציות מובייל
נתקלנו לא פעם בתרחיש הבא: משתמש מעלה תמונה ישנה בשחור-לבן בתקווה לקבל צבעים טבעיים. צביעת תמונות היא משימה מאתגרת בתחום ראייה ממוחשבת. ההתמקדות שלנו היא בצביעה ב-AI לתמונות שחור-לבן למובייל. אבל צביעה היא בעיה עם קלט אחד נכון ומספר אינסופי של פלטים "נכונים". השמיים יכולים להיות כחולים או אפורים. המעיל יכול להיות שחור או כחול. מודל AI בוחר בחירה סבירה סטטיסטית, לא שחזור של המציאות. אנו מסבירים את הניואנס הזה למשתמש ישירות בממשק, אבל היישום הטכני נשאר החלק המעניין ביותר. הניסיון שלנו — 5 שנים בפיתוח מובייל ו-12+ פרויקטים עם שילוב AI — מאפשר לנו להבטיח תוצאה איכותית.
איזה מודל מתאים לצביעה במובייל?
הבחירה הקלאסית היא DeOldify (fastai + U-Net עם self-attention). הוא מכליל היטב ומייצר צבעים רוויים. החיסרון: לפעמים הוא "מזהם" את הצבע בכתמים לא רצויים על פנים או בגדים ברקעים מורכבים. DDColor (2023) — ארכיטקטורה מבוססת transformer — עובד טוב משמעותית על פורטרטים וארכיטקטורה. הוא משחזר בצורה מדויקת יותר צבעי עור ושמיים. למעשה, DDColor מדויק פי 2 בגווני עור מאשר DeOldify. BigColor ו-ChromaGAN מיועדים למשימות ספציפיות (תמונות היסטוריות עם נזק חמור).
| מודל | ארכיטקטורה | גודל (בסיסי) | מאפיינים |
|---|---|---|---|
| DeOldify | U-Net + self-attention | 250 MB (FP32), 60-70 MB (INT8) | צבעים רוויים, סיכון לכתמים על פנים |
| DDColor | Transformer | 110 MB | שחזור מדויק של עור ושמיים |
| BigColor | GAN + ResNet | 150 MB | טוב לתמונות פגומות |
| ChromaGAN | GAN | 130 MB | עמיד לרעש |
למובייל, אנו משתמשים באחד מאלה — מומר ל-Core ML או TFLite. לאחר קוונטיזציה של INT8, DeOldify שוקל 60–70 MB — מקובל לאפליקציית מובייל.
כיצד לשלב את המודל ב-iOS ואנדרואיד?
תהליך השילוב מורכב ממספר שלבים:
- בחירת המודל והמרתו לפורמט היעד (Core ML / TFLite / ONNX).
- הגדרת עיבוד מקדים: המרת גווני אפור ל-RGB, נורמליזציה.
- הרצת inference עם אופטימיזציה ספציפית למכשיר (Neural Engine, GPU, NNAPI).
- עיבוד לאחר: inference באריחים עם נורמליזציית צבע לתמונות גדולות.
המרת DeOldify ל-Core ML
דוגמת קוד להמרה
import coremltools as ct
import torch
from deoldify.visualize import get_image_colorizer
colorizer = get_image_colorizer(artistic=True)
model = colorizer.learn.model.eval()
# Экспорт через torch.jit.trace
example = torch.zeros(1, 3, 256, 256)
traced = torch.jit.trace(model, example)
mlmodel = ct.convert(
traced,
inputs=[ct.TensorType(name="input", shape=(1, 3, 256, 256))],
compute_precision=ct.precision.FLOAT16,
minimum_deployment_target=ct.target.iOS16
)
mlmodel.save("DeOldify_artistic.mlpackage")פרט חשוב: DeOldify מצפה לקלט RGB (גם עבור גווני אפור — הוא ממיר פנימית ל-Lab ועובד עם ערוצי AB). לפני הזנת תמונה בגווני אפור, יש לשכפל אותה לערוץ RGB משולש: import coremltools as ct import torch from deoldify.visualize import get_image_colorizer colorizer = get_image_colorizer(artistic=True) model = colorizer.learn.model.eval() # Экспорт через torch.jit.trace example = torch.zeros(1, 3, 256, 256) traced = torch.jit.trace(model, example) mlmodel = ct.convert( traced, inputs=[ct.TensorType(name="input", shape=(1, 3, 256, 256))], compute_precision=ct.precision.FLOAT16, minimum_deployment_target=ct.target.iOS16 ) mlmodel.save("DeOldify_artistic.mlpackage") . ב-Core ML זה נעשה בעיבוד המקדים, לא במודל עצמו.
iOS: הרצת Inference
let config = MLModelConfiguration()
config.computeUnits = .cpuAndNeuralEngine // ANE для FLOAT16
let model = try DeOldify_artistic(configuration: config)
// Подготовка: grayscale CVPixelBuffer → RGB
func prepareInput(from grayImage: UIImage) -> CVPixelBuffer? {
// Создаём RGB пиксельный буфер из grayscale, реплицируя канал
var pixelBuffer: CVPixelBuffer?
CVPixelBufferCreate(nil, width, height, kCVPixelFormatType_32BGRA, nil, &pixelBuffer)
// ... копируем серый канал во все три
return pixelBuffer
}
let input = DeOldify_artisticInput(input: pixelBuffer)
let output = try model.prediction(input: input)
let colorizedImage = UIImage(cvPixelBuffer: output.output)באייפון 13, תמונה בגודל 512×512 מעובדת ב-0.8–1.2 שניות. עבור Full HD (1920×1080), אנו משתמשים ב-inference באריחים עם טלאים בגודל 512×512 ומיזוג בתפרים. הגישה מבוססת האריחים יוצרת בעיה של חוסר עקביות צבע בין טלאים: המודל עשוי לצבוע קטע שמיים אחד בכחול וקטע שכן באפור. הפתרון הוא התאמת היסטוגרמת צבע גלובלית: נורמליזציה של היסטוגרמת כל טלאי להיסטוגרמה הגלובלית.
אנדרואיד: TFLite עם ONNX Runtime כחלופה
// ONNX Runtime даёт гибкость: одна модель для iOS и Android
val env = OrtEnvironment.getEnvironment()
val session = env.createSession(
"deoldify_optimized.onnx",
OrtSession.SessionOptions().apply {
addNnapi() // или addCuda() если есть GPU
}
)
val inputTensor = OnnxTensor.createTensor(env, inputArray, longArrayOf(1, 3, 512, 512))
val results = session.run(mapOf("input" to inputTensor))
val outputArray = (results[0].value as Array<*>)ONNX Runtime Mobile הוא בחירה טובה כאשר אותו מודל נדרש בשתי הפלטפורמות — אין צורך בהמרה כפולה. ה-NNAPI delegate עובד על מכשירים עם Android 8.1 ומעלה. ONNX Runtime מפחית את מורכבות הפריסה פי 3 בהשוואה לבניית Core ML ו-TFLite נפרדות.
UX: מה לקחת בחשבון
צביעה היא פעולה איטית (1–5 שניות). הצג מחוון התקדמות מונפש. דפוס טוב הוא מחוון לפני/אחרי: המשתמש גורר מחלק ורואה את המקור והתוצאה זה לצד זה. זה גם UX וגם הדגמה ברורה של עבודת המודל.
שמור את התוצאה ב-gray → [gray, gray, gray] או let config = MLModelConfiguration() config.computeUnits = .cpuAndNeuralEngine // ANE для FLOAT16 let model = try DeOldify_artistic(configuration: config) // Подготовка: grayscale CVPixelBuffer → RGB func prepareInput(from grayImage: UIImage) -> CVPixelBuffer? { // Создаём RGB пиксельный буфер из grayscale, реплицируя канал var pixelBuffer: CVPixelBuffer? CVPixelBufferCreate(nil, width, height, kCVPixelFormatType_32BGRA, nil, &pixelBuffer) // ... копируем серый канал во все три return pixelBuffer } let input = DeOldify_artisticInput(input: pixelBuffer) let output = try model.prediction(input: input) let colorizedImage = UIImage(cvPixelBuffer: output.output) באיכות מקסימלית. תוצאת הצביעה סובלת בצורה גרועה דחיסת JPEG חוזרת: חפצים במעברי צבע הופכים לבולטים.
מה כלול בעבודה
- בחירה והמרה של המודל לפלטפורמת היעד (Core ML / TFLite / ONNX)
- אופטימיזציה למכשירים ספציפיים (Neural Engine, GPU, NNAPI)
- יישום inference באריחים עם נורמליזציית צבע
- פיתוח ממשק משתמש עם השוואת לפני/אחרי והתקדמות
- שילוב שמירה לגלריה ושיתוף
- תיעוד על המודל, עיבוד מקדים והוראות לבדיקת App Store Review (לפי App Store Review Guidelines סעיף 5.1 לעיבוד תמונות)
- בדיקות על תמונות היסטוריות באיכויות שונות
חיסכון ברישיונות: לא משלמים עבור מודלים בקוד פתוח. עלות פיתוח טיפוסית לפלטפורמה אחת היא $8,000–$12,000, וחוסכת לך עד $20,000 בהשוואה להעסקת צוות פנימי. עלות הפיתוח דומה למשכורת חודשית של מפתח אחד.
אנו מספקים שילוב מפתח ביד (под ключ) תוך 2–8 שבועות. העבודה כוללת (входит) את כל השלבים לעיל. צור קשר כדי להעריך את הפרויקט שלך בחינם. כתוב לנו לקבלת הצעת מחיר.
הערכות לוחות זמנים
| שלב | פלטפורמה אחת | שתי הפלטפורמות |
|---|---|---|
| בחירת מודל והמרה | שבוע 1 | 1.5 שבועות |
| יישום Inference וממשק משתמש | 1-2 שבועות | 2-3 שבועות |
| Inference באריחים + נורמליזציית צבע | 0.5-1 שבוע | 1-2 שבועות |
| בדיקות ואופטימיזציה | 0.5-1 שבוע | 1-1.5 שבועות |
| סה"כ | 2–4 שבועות | 5–8 שבועות |
אנו יכולים ליישם את הפתרון עבורך תוך 2 שבועות בלבד לפלטפורמה אחת. קבל ייעוץ — נעריך את הפרויקט שלך ונציע את המחסנית האופטימלית תוך יומיים.







