File size: 2,719 Bytes
e38bf4d
d243d0e
8820453
 
 
 
d243d0e
aec5ec6
8820453
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
014d1cd
 
8820453
 
 
 
 
 
d243d0e
8820453
d243d0e
 
9b319b3
8820453
 
 
 
 
 
 
 
 
9b319b3
aec5ec6
d243d0e
8820453
aec5ec6
d243d0e
 
 
 
aec5ec6
d243d0e
8820453
 
 
 
 
 
 
 
 
 
f51b0f2
8820453
6e1bd9f
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
import numpy as np
import gradio as gr
import cv2  # OpenCV for face detection
from skimage import color
from sklearn.decomposition import TruncatedSVD
from concurrent.futures import ThreadPoolExecutor
from PIL import Image

# Detect faces using OpenCV
def detect_faces(image_np):
    """Detect faces in the image and return their bounding boxes."""
    gray_image = cv2.cvtColor(image_np, cv2.COLOR_RGB2GRAY)
    face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
    faces = face_cascade.detectMultiScale(gray_image, scaleFactor=1.1, minNeighbors=5)
    return faces

# Compress the image using Truncated SVD for faster performance
def truncated_svd_compress(image, k):
    """Compress the image using Truncated SVD by keeping only the top k singular values."""
    svd = TruncatedSVD(n_components=k)
    U = svd.fit_transform(image)
    S = svd.singular_values_
    Vt = svd.components_
    compressed_image = np.dot(U, np.dot(np.diag(S), Vt))
    return compressed_image

# Process the image asynchronously for smoother user experience
async def process_image_async(image, k):
    """Asynchronous image processing to avoid blocking."""
    return await asyncio.to_thread(process_image, image, k)

# Main image processing function
def process_image(image, k):
    """Process the uploaded image, detect faces, and compress it using Truncated SVD."""
    # Convert PIL Image to NumPy array
    image_np = np.array(image)
    
    # Detect faces in the image
    faces = detect_faces(image_np)
    
    # If faces are detected, highlight the regions (optional)
    if len(faces) > 0:
        for (x, y, w, h) in faces:
            cv2.rectangle(image_np, (x, y), (x+w, y+h), (255, 0, 0), 2)
    
    # Convert the image to grayscale
    gray_image = color.rgb2gray(image_np)
    
    # Compress the image
    compressed_image = truncated_svd_compress(gray_image, k)
    
    # Convert compressed image back to PIL Image for Gradio output
    compressed_image_pil = Image.fromarray((compressed_image * 255).astype(np.uint8))
    
    return compressed_image_pil

# Gradio interface
gr_interface = gr.Interface(
    fn=process_image,  # Image processing function
    inputs=[
        gr.Image(type="pil", label="Upload Image"),
        gr.Slider(1, 100, step=1, value=50, label="Compression Rank")  # Compression rank slider
    ],
    outputs=gr.Image(type="pil", label="Compressed Image"),
    title="Fast Interactive Image Compression with Face Detection",
    description="Upload an image and adjust the compression rank. The app detects faces and compresses the image using Truncated SVD for faster processing."
)

# Launch the Gradio interface
gr_interface.launch()