dream2589632147 commited on
Commit
2e2a632
·
verified ·
1 Parent(s): 1c4e450

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +129 -139
app.py CHANGED
@@ -1,139 +1,129 @@
1
- import gradio as gr
2
- import torch
3
- import cv2
4
- import numpy as np
5
- from PIL import Image
6
- from diffusers import StableDiffusionControlNetPipeline, ControlNetModel, DDIMScheduler
7
- from controlnet_aux import CannyDetector
8
- from diffusers.utils import load_image
9
- from moviepy.editor import VideoFileClip
10
- import os
11
- import shutil
12
- import tempfile # لاستخدام مجلدات مؤقتة آمنة
13
-
14
- # 1. تهيئة النموذج
15
- # تحديد جهاز التشغيل (يجب أن يكون CUDA في بيئة GPU Docker)
16
- device = "cuda" if torch.cuda.is_available() else "cpu"
17
- torch_dtype = torch.float16 if device == "cuda" else torch.float32
18
-
19
- # تحميل ControlNet (نموذج Canny)
20
- try:
21
- controlnet_model = ControlNetModel.from_pretrained(
22
- "lllyasviel/sd-controlnet-canny", torch_dtype=torch_dtype
23
- )
24
- # تحميل الـ Pipeline الرئيسية
25
- model_id = "runwayml/stable-diffusion-v1-5"
26
- pipe = StableDiffusionControlNetPipeline.from_pretrained(
27
- model_id, controlnet=controlnet_model, torch_dtype=torch_dtype
28
- )
29
- pipe.scheduler = DDIMScheduler.from_config(pipe.scheduler.config)
30
- pipe.to(device)
31
- print("Models loaded successfully.")
32
- except Exception as e:
33
- print(f"Error loading models: {e}. Running on CPU (slow).")
34
- # محاولة التحميل بدون GPU إذا فشل CUDA
35
- pipe = StableDiffusionControlNetPipeline.from_pretrained(model_id, controlnet=controlnet_model)
36
- pipe.to("cpu")
37
-
38
-
39
- # تهيئة مُعالِج Canny
40
- canny_processor = CannyDetector()
41
-
42
-
43
- # 2. دالة معالجة الفيديو والنموذج
44
- def colorize_video_multistyle(video_file, reference_image_path, prompt, style_choice, steps=25):
45
-
46
- # استخدام مجلد مؤقت لضمان التنظيف
47
- with tempfile.TemporaryDirectory() as temp_dir:
48
-
49
- # 1. استخراج الإطارات والصوت
50
- clip = VideoFileClip(video_file)
51
- audio_file = None
52
- if clip.audio:
53
- audio_file = os.path.join(temp_dir, "temp_audio.mp3")
54
- clip.audio.write_audiofile(audio_file, verbose=False, logger=None)
55
-
56
- fps = clip.fps
57
-
58
- # 2. تجهيز المدخلات للنموذج
59
- style_prompts = {
60
- "Auto Color": "photorealistic color photo, cinematic, detailed, masterpiece",
61
- "Vivid": "highly saturated, vibrant color photo, pop art colors",
62
- "Vintage": "sepia tone, old film grain, 1940s vintage look",
63
- }
64
- final_prompt = f"{prompt}, {style_prompts.get(style_choice, '')}"
65
- negative_prompt = "lowres, bad anatomy, bad hands, blurry, distorted, nsfw, frame, border, changed details"
66
-
67
- # تجهيز الصورة المرجعية (IP-Adapter - يُفترض أنه محمل إذا كان مطلوباً)
68
- # ip_adapter_images = []
69
- # if reference_image_path:
70
- # ref_image = load_image(reference_image_path).convert("RGB")
71
- # ip_adapter_images.append(ref_image)
72
- # pipe.set_ip_adapter_images(ip_adapter_images) # يجب إلغاء التعليق إذا تم تحميل IP-Adapter
73
-
74
- colored_frames = []
75
-
76
- # 3. معالجة الإطارات (التلوين باستخدام ControlNet)
77
- for i, frame in enumerate(clip.iter_frames(fps=fps, dtype='uint8')):
78
-
79
- pil_image = Image.fromarray(frame).convert("RGB")
80
-
81
- # الخطوة الحاسمة: استخراج خريطة Canny للحفاظ على الهيكل
82
- canny_image = canny_processor(pil_image)
83
-
84
- # تمرير خريطة Canny للنموذج
85
- image_out = pipe(
86
- prompt=final_prompt,
87
- negative_prompt=negative_prompt,
88
- image=canny_image, # ControlNet Canny Input
89
- num_inference_steps=steps,
90
- guidance_scale=7.5
91
- ).images[0]
92
-
93
- colored_frames.append(np.array(image_out))
94
-
95
- # 4. تجميع الإطارات في فيديو MP4
96
- output_video_path = os.path.join(temp_dir, "colored_temp_video.mp4")
97
- height, width, layers = colored_frames[0].shape
98
-
99
- fourcc = cv2.VideoWriter_fourcc(*'mp4v')
100
- out = cv2.VideoWriter(output_video_path, fourcc, fps, (width, height))
101
-
102
- for frame in colored_frames:
103
- out.write(cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))
104
-
105
- out.release()
106
-
107
- # 5. إضافة الصوت الأصلي
108
- final_video_path = "final_colored_video.mp4" # يتم إنشاء هذا الملف في المجلد الحالي
109
- if audio_file and os.path.exists(audio_file):
110
- video_clip = VideoFileClip(output_video_path)
111
- # التأكد من أن مدة الفيديو الملون تتطابق مع مدة الصوت
112
- final_clip = video_clip.set_audio(clip.audio)
113
- final_clip.write_videofile(final_video_path, codec='libx264', audio_codec='aac', verbose=False, logger=None)
114
- else:
115
- shutil.copy(output_video_path, final_video_path)
116
-
117
- clip.close()
118
-
119
- return final_video_path
120
-
121
-
122
- # 3. واجهة Gradio للإنتاج
123
- iface = gr.Interface(
124
- fn=colorize_video_multistyle,
125
- inputs=[
126
- gr.Video(label="ملف الفيديو (إلزامي)"),
127
- gr.Image(label="الصورة المرجعية (لنقل الألوان)", type="filepath", required=False),
128
- gr.Textbox(label="المطالبة النصية (لتوجيه التلوين)", required=False, value=""),
129
- gr.Dropdown(["Auto Color", "Vivid", "Vintage"], label="اختيار النمط المسبق", value="Auto Color"),
130
- gr.Slider(minimum=10, maximum=50, step=5, value=25, label="خطوات التوليد (للسرعة/الجودة)")
131
- ],
132
- outputs=gr.Video(label="الفيديو الملون (MP4)"),
133
- title="🎨 Multi-Style Video Colorizer (Dockerized)",
134
- description="تلوين الفيديو مع الحفاظ على الهيكل باستخدام ControlNet."
135
- )
136
-
137
- if __name__ == "__main__":
138
- # تشغيل Gradio على 0.0.0.0 والمنفذ 7860 للسماح بالوصول من خارج الحاوية
139
- iface.launch(server_name="0.0.0.0", server_port=7860)
 
1
+ import gradio as gr
2
+ import torch
3
+ import cv2
4
+ import numpy as np
5
+ from PIL import Image
6
+ from diffusers import StableDiffusionControlNetPipeline, ControlNetModel, DDIMScheduler
7
+ from controlnet_aux import CannyDetector
8
+ from diffusers.utils import load_image
9
+ from moviepy.editor import VideoFileClip
10
+ import os
11
+ import shutil
12
+ import tempfile
13
+ import datetime
14
+
15
+ # 1. تهيئة النموذج
16
+ # تحديد جهاز التشغيل (GPU إذا كان متاحًا محليًا)
17
+ device = "cuda" if torch.cuda.is_available() else "cpu"
18
+ torch_dtype = torch.float16 if device == "cuda" else torch.float32
19
+
20
+ try:
21
+ controlnet_model = ControlNetModel.from_pretrained(
22
+ "lllyasviel/sd-controlnet-canny", torch_dtype=torch_dtype
23
+ )
24
+ model_id = "runwayml/stable-diffusion-v1-5"
25
+ pipe = StableDiffusionControlNetPipeline.from_pretrained(
26
+ model_id, controlnet=controlnet_model, torch_dtype=torch_dtype
27
+ )
28
+ pipe.scheduler = DDIMScheduler.from_config(pipe.scheduler.config)
29
+ pipe.to(device)
30
+ print("Models loaded successfully on:", device)
31
+ except Exception as e:
32
+ print(f"Error loading models on CUDA: {e}. Switching to CPU.")
33
+ controlnet_model = ControlNetModel.from_pretrained("lllyasviel/sd-controlnet-canny")
34
+ pipe = StableDiffusionControlNetPipeline.from_pretrained(model_id, controlnet=controlnet_model)
35
+ pipe.to("cpu")
36
+
37
+ canny_processor = CannyDetector()
38
+
39
+
40
+ # 2. دالة معالجة الفيديو والنموذج (بدون تغيير)
41
+ def colorize_video_multistyle(video_file, reference_image_path, prompt, style_choice, steps=25):
42
+
43
+ timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
44
+ final_output_name = f"colored_output_{timestamp}.mp4"
45
+
46
+ with tempfile.TemporaryDirectory() as temp_dir:
47
+
48
+ clip = VideoFileClip(video_file)
49
+ audio_file = None
50
+ if clip.audio:
51
+ audio_file = os.path.join(temp_dir, "temp_audio.mp3")
52
+ clip.audio.write_audiofile(audio_file, verbose=False, logger=None)
53
+
54
+ fps = clip.fps
55
+
56
+ style_prompts = {
57
+ "Auto Color": "photorealistic color photo, cinematic, detailed, masterpiece",
58
+ "Vivid": "highly saturated, vibrant color photo, pop art colors",
59
+ "Vintage": "sepia tone, old film grain, 1940s vintage look",
60
+ }
61
+ final_prompt = f"{prompt}, {style_prompts.get(style_choice, '')}"
62
+ negative_prompt = "lowres, bad anatomy, bad hands, blurry, distorted, nsfw, frame, border, changed details, monochrome"
63
+
64
+ colored_frames = []
65
+
66
+ for i, frame in enumerate(clip.iter_frames(fps=fps, dtype='uint8')):
67
+
68
+ pil_image = Image.fromarray(frame).convert("RGB")
69
+ canny_image = canny_processor(pil_image)
70
+
71
+ # يمكنك إزالة هذه الأسطر إذا لم تقم بتحميل IP-Adapter
72
+ # ip_adapter_images = []
73
+ # if reference_image_path:
74
+ # ref_image = load_image(reference_image_path).convert("RGB")
75
+ # ip_adapter_images.append(ref_image)
76
+ # # pipe.set_ip_adapter_images(ip_adapter_images)
77
+
78
+ image_out = pipe(
79
+ prompt=final_prompt,
80
+ negative_prompt=negative_prompt,
81
+ image=canny_image,
82
+ num_inference_steps=steps,
83
+ guidance_scale=7.5
84
+ ).images[0]
85
+
86
+ colored_frames.append(np.array(image_out))
87
+
88
+ output_video_path = os.path.join(temp_dir, "colored_temp_video.mp4")
89
+ height, width, layers = colored_frames[0].shape
90
+
91
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
92
+ out = cv2.VideoWriter(output_video_path, fourcc, fps, (width, height))
93
+
94
+ for frame in colored_frames:
95
+ out.write(cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))
96
+
97
+ out.release()
98
+
99
+ if audio_file and os.path.exists(audio_file):
100
+ video_clip = VideoFileClip(output_video_path)
101
+ final_clip = video_clip.set_audio(clip.audio)
102
+ final_clip.write_videofile(final_output_name, codec='libx264', audio_codec='aac', verbose=False, logger=None)
103
+ else:
104
+ shutil.copy(output_video_path, final_output_name)
105
+
106
+ clip.close()
107
+
108
+ return final_output_name
109
+
110
+
111
+ # 3. واجهة Gradio النهائية والتشغيل
112
+ iface = gr.Interface(
113
+ fn=colorize_video_multistyle,
114
+ inputs=[
115
+ gr.Video(label="ملف الفيديو (إلزامي)"),
116
+ gr.Image(label="الصورة المرجعية (لنقل الألوان)", type="filepath", required=False),
117
+ gr.Textbox(label="المطالبة النصية (لتوجيه التلوين)", required=False, value=""),
118
+ gr.Dropdown(["Auto Color", "Vivid", "Vintage"], label="اختيار النمط المسبق", value="Auto Color"),
119
+ gr.Slider(minimum=10, maximum=50, step=5, value=25, label="خطوات التوليد (للسرعة/الجودة)")
120
+ ],
121
+ outputs=gr.Video(label="الفيديو الملون (MP4)"),
122
+ title="🎨 Multi-Style Video Colorizer (Gradio)",
123
+ description="تلوين احترافي للفيديو باستخدام ControlNet: يُحافظ على الهيكل وتتغير الألوان فقط."
124
+ )
125
+
126
+ if __name__ == "__main__":
127
+ # هذا السطر يشغل الواجهة على عنوان محلي يمكن الوصول إليه عبر المتصفح
128
+ # يمكنك استخدام share=True لمشاركة الواجهة مؤقتاً عبر الإنترنت
129
+ iface.launch() # تم حذف server_name و server_port للاعتماد على إعدادات Gradio الافتراضية