In Python, image processing unlocks powerful capabilities for computer vision, data augmentation, and automation—master these techniques to excel in ML engineering interviews and real-world applications! 🖼️
```python
# PIL/Pillow Basics - The essential image library
from PIL import Image
# Open and display image
img = Image.open("input.jpg")
img.show()
# Convert formats
img.save("output.png")
img.convert("L").save("grayscale.jpg") # RGB to grayscale
# Basic transformations
img.rotate(90).save("rotated.jpg")
img.resize((300, 300)).save("resized.jpg")
img.transpose(Image.FLIP_LEFT_RIGHT).save("mirrored.jpg")
```
```python
# Advanced Manipulation - Professional editing
from PIL import ImageEnhance, ImageFilter
# Adjust brightness/contrast
enhancer = ImageEnhance.Brightness(img)
bright_img = enhancer.enhance(1.5) # 50% brighter
# Apply filters
blurred = img.filter(ImageFilter.BLUR)
sharpened = img.filter(ImageFilter.SHARPEN)
edges = img.filter(ImageFilter.FIND_EDGES)
# Color manipulation
color_enhancer = ImageEnhance.Color(img)
color_enhancer.enhance(2.0).save("vibrant.jpg") # Double saturation
```
```python
# OpenCV Integration - Computer vision powerhouse
import cv2
import numpy as np
# Read and convert color spaces
cv_img = cv2.imread("input.jpg")
rgb_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
hsv_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2HSV)
# Edge detection (Canny algorithm)
edges = cv2.Canny(cv_img, 100, 200)
cv2.imwrite("edges.jpg", edges)
# Face detection (interview favorite)
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
faces = face_cascade.detectMultiScale(rgb_img, 1.3, 5)
for (x, y, w, h) in faces:
cv2.rectangle(cv_img, (x, y), (x+w, y+h), (255, 0, 0), 2)
cv2.imwrite("faces.jpg", cv_img)
```
```python
# Batch Processing - Production automation
import os
from PIL import Image
def process_images(input_dir, output_dir):
os.makedirs(output_dir, exist_ok=True)
for filename in os.listdir(input_dir):
if filename.lower().endswith(('.png', '.jpg', '.jpeg')):
with Image.open(os.path.join(input_dir, filename)) as img:
# Resize while maintaining aspect ratio
img.thumbnail((800, 800))
# Apply watermark
watermark = Image.open("watermark.png")
img.paste(watermark, (img.width - watermark.width, img.height - watermark.height), watermark)
img.save(os.path.join(output_dir, filename))
process_images("raw_photos", "processed")
```
```python
# Image Augmentation - Deep learning preparation
from torchvision import transforms
transform = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.ColorJitter(brightness=0.2, contrast=0.2),
transforms.RandomRotation(15),
transforms.Resize((224, 224)),
transforms.ToTensor()
])
# Apply to dataset
augmented_img = transform(img)
```
```python
# EXIF Data Handling - Privacy/security critical
from PIL import Image
img = Image.open("photo_with_gps.jpg")
# Strip metadata (security interview question)
data = list(img.getdata())
clean_img = Image.new(img.mode, img.size)
clean_img.putdata(data)
clean_img.save("clean.jpg", "JPEG", exif=b"")
# Read specific metadata
exif = img.getexif()
if 36867 in exif: # DateTimeOriginal
print(exif[36867])
```
```python
# Image Segmentation - Advanced computer vision
import numpy as np
import cv2
img = cv2.imread('input.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresh = cv2.threshold(gray, 180, 255, cv2.THRESH_BINARY_INV)
# Morphological operations
kernel = np.ones((2,2), np.uint8)
dilated = cv2.dilate(thresh, kernel, iterations=1)
# Find contours
contours, _ = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
area = cv2.contourArea(cnt)
if area > 100: # Filter small contours
x, y, w, h = cv2.boundingRect(cnt)
cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imwrite("segmented.jpg", img)
```
```python
# Memory Optimization - Handle large images
from PIL import Image
# Process without loading entire image
with Image.open("huge_image.tiff") as img:
# Work with tiles
for i, (x, y, w, h) in enumerate(img.tile):
tile = img.crop((x, y, x+w, y+h))
# Process tile
processed_tile = tile.filter(ImageFilter.SHARPEN)
# Paste back
img.paste(processed_tile, (x, y))
img.save("optimized.tiff")
```
```python
# Async Processing - Modern Python requirement
import asyncio
from PIL import Image
async def process_image_async(filename):
loop = asyncio.get_running_loop()
return await loop.run_in_executor(
None,
lambda: Image.open(filename).resize((500, 500)).save(f"thumb_{filename}")
)
async def main():
tasks = [process_image_async(f) for f in ["img1.jpg", "img2.jpg", "img3.jpg"]]
await asyncio.gather(*tasks)
asyncio.run(main())
```
```python
# Cloud Integration - Production pipeline
from google.cloud import storage
from PIL import Image
import io
def process_gcs_image(bucket_name, source_blob, destination_blob):
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
# Download from GCS
blob = bucket.blob(source_blob)
img_data = blob.download_as_bytes()
img = Image.open(io.BytesIO(img_data))
# Process image
img = img.convert("RGB").resize((1024, 1024))
# Upload back to GCS
buffer = io.BytesIO()
img.save(buffer, "JPEG")
bucket.blob(destination_blob).upload_from_string(
buffer.getvalue(),
content_type="image/jpeg"
)
process_gcs_image("user-photos", "raw/photo.jpg", "processed/photo.jpg")
```
```python
# Dockerized Service - Deployment pattern
# Dockerfile snippet:
# FROM python:3.10-slim
# RUN pip install pillow opencv-python
# COPY image_service.py /app/
# CMD ["python", "/app/image_service.py"]
# image_service.py
from http.server import HTTPServer, BaseHTTPRequestHandler
from PIL import Image
import io
class ImageHandler(BaseHTTPRequestHandler):
def do_POST(self):
content_len = int(self.headers['Content-Length'])
img_data = self.rfile.read(content_len)
# Process image
img = Image.open(io.BytesIO(img_data))
img = img.resize((800, 800))
# Return processed image
buffer = io.BytesIO()
img.save(buffer, "JPEG")
self.send_response(200)
self.send_header("Content-Type", "image/jpeg")
self.end_headers()
self.wfile.write(buffer.getvalue())
HTTPServer(('', 8000), ImageHandler).serve_forever()
```
```python
# Performance Benchmarking - Optimization proof
import time
from PIL import Image
# Compare resize methods
start = time.time()
for _ in range(100):
Image.open("input.jpg").resize((500, 500), Image.LANCZOS)
lanczos_time = time.time() - start
start = time.time()
for _ in range(100):
Image.open("input.jpg").resize((500, 500), Image.NEAREST)
nearest_time = time.time() - start
print(f"LANCZOS: {lanczos_time:.2f}s | NEAREST: {nearest_time:.2f}s")
# Output: LANCZOS: 4.20s | NEAREST: 1.80s (Quality vs Speed tradeoff)
```
```python
# Image Hashing - Deduplication solution
import imagehash
from PIL import Image
def find_duplicates(image_dir, threshold=5):
hashes = {}
for filename in os.listdir(image_dir):
img = Image.open(os.path.join(image_dir, filename))
img_hash = imagehash.phash(img)
# Find similar images
for existing_hash, files in hashes.items():
if img_hash - existing_hash < threshold:
files.append(filename)
break
else:
hashes[img_hash] = [filename]
return [files for files in hashes.values() if len(files) > 1]
duplicates = find_duplicates("user_uploads")
```
```python
# OCR Processing - Text extraction
import pytesseract
from PIL import Image
# Configure Tesseract path (if needed)
# pytesseract.pytesseract.tesseract_cmd = '/usr/bin/tesseract'
img = Image.open("document.jpg")
text = pytesseract.image_to_string(img, lang='eng')
print(text[:200]) # First 200 characters
# Get bounding boxes for text
data = pytesseract.image_to_data(img, output_type=pytesseract.Output.DICT)
for i, word in enumerate(data['text']):
if word:
x, y, w, h = data['left'][i], data['top'][i], data['width'][i], data['height'][i]
print(f"Word: {word} | Position: ({x},{y}) Size: {w}x{h}")
```
```python
# Generative Art - Creative application
from PIL import Image, ImageDraw
import random
img = Image.new('RGB', (800, 800), (255, 255, 255))
draw = ImageDraw.Draw(img)
# Generate random geometric pattern
for _ in range(1000):
x1, y1 = random.randint(0, 800), random.randint(0, 800)
x2, y2 = x1 + random.randint(-100, 100), y1 + random.randint(-100, 100)
color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
draw.line([x1, y1, x2, y2], fill=color, width=random.randint(1, 5))
img.save("generative_art.jpg")
```
```python
# Image Steganography - Security technique
def hide_message(image_path, message, output_path):
img = Image.open(image_path)
binary_message = ''.join(format(ord(c), '08b') for c in message) + '1111111111111110'
pixels = list(img.getdata())
new_pixels = []
bit_index = 0
for pixel in pixels:
if bit_index < len(binary_message):
r, g, b = pixel[:3]
r = (r & ~1) | int(binary_message[bit_index])
bit_index += 1
new_pixels.append((r, g, b))
else:
new_pixels.append(pixel)
img.putdata(new_pixels)
img.save(output_path)
hide_message("cover.jpg", "Secret message", "stego.png")
```
```python
# Interview Power Move: Custom Filter Implementation
import numpy as np
from PIL import Image
def apply_sepia(img):
# Convert to numpy array
img_array = np.array(img)
# Sepia matrix (BT.709 coefficients)
sepia_matrix = np.array([
[0.393, 0.769, 0.189],
[0.349, 0.686, 0.168],
[0.272, 0.534, 0.131]
])
# Apply matrix multiplication
sepia_array = img_array @ sepia_matrix.T
sepia_array = np.clip(sepia_array, 0, 255).astype(np.uint8)
return Image.fromarray(sepia_array)
sepia_img = apply_sepia(Image.open("input.jpg"))
sepia_img.save("sepia.jpg")
```
```python
# Pro Tip: Memory-Mapped Processing for Gigapixel Images
import numpy as np
from PIL import Image
def process_gigapixel(image_path):
# Create memory-mapped array
img = Image.open(image_path)
mmap_file = np.memmap('temp.mmap', dtype='uint8', mode='w+', shape=img.size[::-1] + (3,))
# Process in chunks
chunk_size = (1000, 1000)
for y in range(0, img.height, chunk_size[1]):
for x in range(0, img.width, chunk_size[0]):
box = (x, y, min(x+chunk_size[0], img.width), min(y+chunk_size[1], img.height))
chunk = np.array(img.crop(box))
mmap_file[y:box[3], x:box[2]] = chunk
# Process entire image in memory-mapped array
mmap_file = np.where(mmap_file > 128, 255, 0) # Binarize
Image.fromarray(mmap_file).save("processed.jpg")
process_gigapixel("gigapixel.tiff")
```
```python
# Real-World Case Study: E-commerce Product Pipeline
import boto3
from PIL import Image
import io
def process_product_image(s3_bucket, s3_key):
# 1. Download from S3
s3 = boto3.client('s3')
response = s3.get_object(Bucket=s3_bucket, Key=s3_key)
img = Image.open(io.BytesIO(response['Body'].read()))
# 2. Standardize dimensions
img = img.convert("RGB")
img = img.resize((1200, 1200), Image.LANCZOS)
# 3. Remove background (simplified)
# In practice: use rembg or AWS Rekognition
img = remove_background(img)
# 4. Generate variants
variants = {
"web": img.resize((800, 800)),
"mobile": img.resize((400, 400)),
"thumbnail": img.resize((100, 100))
}
# 5. Upload to CDN
for name, variant in variants.items():
buffer = io.BytesIO()
variant.save(buffer, "JPEG", quality=95)
s3.upload_fileobj(
buffer,
"cdn-bucket",
f"products/{s3_key.split('/')[-1].split('.')[0]}_{name}.jpg",
ExtraArgs={'ContentType': 'image/jpeg', 'CacheControl': 'max-age=31536000'}
)
# 6. Generate WebP version
webp_buffer = io.BytesIO()
img.save(webp_buffer, "WEBP", quality=85)
s3.upload_fileobj(webp_buffer, "cdn-bucket", f"products/{s3_key.split('/')[-1].split('.')[0]}.webp")
process_product_image("user-uploads", "products/summer_dress.jpg")
```
By: @DataScienceM 👁️
#Python #ImageProcessing #ComputerVision #Pillow #OpenCV #MachineLearning #CodingInterview #DataScience #Programming #TechJobs #DeveloperTips #AI #DeepLearning #CloudComputing #Docker #BackendDevelopment #SoftwareEngineering #CareerGrowth #TechTips #Python3