File size: 2,624 Bytes
7a4a6f3
 
1c34990
 
7a4a6f3
1c34990
 
 
7a4a6f3
1c34990
 
 
7a4a6f3
1c34990
 
 
 
7a4a6f3
1c34990
 
 
 
 
 
 
 
7a4a6f3
1c34990
 
 
 
 
7a4a6f3
1c34990
7a4a6f3
1c34990
 
 
7a4a6f3
1c34990
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7a4a6f3
1c34990
 
 
7a4a6f3
1c34990
 
 
7a4a6f3
1c34990
 
 
 
 
 
 
 
 
7a4a6f3
1c34990
 
 
 
 
 
 
 
 
 
 
 
 
7a4a6f3
1c34990
 
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
import cv2
import numpy as np
import gradio as gr
import time

# ----------------------------
# Sketch Conversion Functions
# ----------------------------

def dodgeV2(image, mask):
    """Helper function for pencil sketch effect"""
    return cv2.divide(image, 255 - mask, scale=256)

def pencil_sketch(img, scale=256, blur_value=21, texture=False):
    """Convert image to realistic pencil sketch"""
    # Convert to grayscale
    gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # Invert image
    inv_gray = 255 - gray_img
    
    # Apply Gaussian blur
    blur_img = cv2.GaussianBlur(inv_gray, (blur_value, blur_value), 0)
    
    # Blend using dodge technique
    sketch = dodgeV2(gray_img, blur_img)
    
    # Optional: Add paper texture
    if texture:
        h, w = sketch.shape
        paper = np.random.normal(loc=200, scale=30, size=(h, w)).astype(np.uint8)
        sketch = cv2.multiply(sketch, paper, scale=1/255)
    
    return sketch

# ----------------------------
# Animation Function
# ----------------------------

def animate_sketch(image, scale=256, blur=21, texture=False, delay=0.01):
    """Simulate hand-drawn line-by-line animation"""
    img = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
    sketch = pencil_sketch(img, scale=scale, blur_value=blur, texture=texture)
    
    # Create blank canvas
    h, w = sketch.shape
    canvas = np.ones((h, w), dtype=np.uint8) * 255
    
    frames = []
    for i in range(h):
        canvas[i] = sketch[i]  # Draw line by line
        frame_rgb = cv2.cvtColor(canvas, cv2.COLOR_GRAY2RGB)
        frames.append(frame_rgb)
    
    return frames

# ----------------------------
# Gradio Interface
# ----------------------------

def gradio_sketch(image, scale, blur, texture):
    frames = animate_sketch(image, scale, blur, texture)
    return frames  # Gradio will display as GIF automatically

# Gradio UI
title = "🎨 Realistic Pencil Sketch Animation"
description = """
Upload any image and watch it transform into a realistic pencil sketch with hand-drawn animation!  
You can adjust:
- Scale: pencil intensity
- Blur: smoothness of strokes
- Texture: add paper texture
"""

iface = gr.Interface(
    fn=gradio_sketch,
    inputs=[
        gr.Image(type="pil", label="Upload Image"),
        gr.Slider(64, 512, value=256, step=1, label="Scale"),
        gr.Slider(1, 51, value=21, step=2, label="Blur"),
        gr.Checkbox(label="Add Paper Texture?")
    ],
    outputs=gr.Gallery(label="Animated Sketch"),
    title=title,
    description=description,
    allow_flagging="never",
)

if __name__ == "__main__":
    iface.launch()