# 📖 THE COMPLETE GUIDE TO BUILDING AN AI IMAGE COLORIZATION WEB APP
### From Zero to Hero — A Beginner's Big Book
---
> **Who is this for?**
> Someone who has NEVER written a single line of code. If you can browse the internet, you can follow this book. Every concept is explained from scratch with real-world analogies.
---
# TABLE OF CONTENTS
**PART 1 — Setting Up Your World**
- Chapter 1: What Are We Building?
- Chapter 2: Understanding Computers & Software
- Chapter 3: Installing Everything You Need
**PART 2 — Learning Python: The Language of AI**
- Chapter 4: Your First Python Program
- Chapter 5: Variables, Numbers & Text
- Chapter 6: Making Decisions (If/Else)
- Chapter 7: Loops — Doing Things Repeatedly
- Chapter 8: Functions — Teaching Python New Tricks
- Chapter 9: Lists & Dictionaries
- Chapter 10: Files — Reading and Writing Data
- Chapter 11: Classes & Objects
**PART 3 — The Science of Images**
- Chapter 12: What Is a Digital Image?
- Chapter 13: The RGB Color Model
- Chapter 14: The Lab Color Space — The Secret Sauce
- Chapter 15: OpenCV — The Image Processing Library
**PART 4 — The Brain: Deep Learning & Neural Networks**
- Chapter 16: What Is Artificial Intelligence?
- Chapter 17: How a Neural Network Works
- Chapter 18: Training vs. Using a Model
- Chapter 19: The Colorization Model (Caffe DNN)
- Chapter 20: OpenCV's DNN Module
**PART 5 — Building the Backend (The Engine)**
- Chapter 21: What Is a Server?
- Chapter 22: Flask — Python's Web Framework
- Chapter 23: APIs — How Software Talks to Software
- Chapter 24: Coding `colorizer.py` — Line by Line
- Chapter 25: Coding `app.py` — Line by Line
**PART 6 — Building the Frontend (The Face)**
- Chapter 26: What Is a Web Page?
- Chapter 27: HTML — The Skeleton
- Chapter 28: CSS — The Styling
- Chapter 29: JavaScript — The Behavior
- Chapter 30: React — Building Modern Interfaces
- Chapter 31: The Upload Component
- Chapter 32: The Before/After Comparison Slider
- Chapter 33: Connecting Frontend to Backend
**PART 7 — Sharing Your Work**
- Chapter 34: Version Control with Git
- Chapter 35: Pushing Everything to GitHub
- Chapter 36: What's Next?
---
# ═══════════════════════════════════════
# PART 1: SETTING UP YOUR WORLD
# ═══════════════════════════════════════
---
## CHAPTER 1: What Are We Building?
### The Goal
Imagine you find an old photograph of your grandparents from the 1920s. It is beautiful, but completely black and white. Wouldn't it be magical if a computer could look at that photo and intelligently add colors back — making the grass green, the sky blue, and the faces look warm and real?
That is exactly what we are building.
We are creating a **web application** — a program that runs in your browser, just like Google. This app will:
1. Let you upload any black and white photo.
2. Send it to an **Artificial Intelligence (AI)** model running quietly in the background.
3. The AI analyzes the photo and predicts what colors each part should be.
4. The app shows you the colorized result, with a beautiful interactive slider so you can compare before and after.
### The Three Layers of Our App
Think of our app like a restaurant:
| Layer | Restaurant Analogy | In Our Project |
|---|---|---|
| **Frontend** | The dining room — what you see and touch | React website in your browser |
| **Backend** | The kitchen — where real work happens | Python/Flask server |
| **AI Model** | The recipe — the secret knowledge | Caffe Neural Network |
You interact only with the dining room (Frontend). When you upload an image (place an order), it travels through the waiter (API) to the kitchen (Backend), which uses the recipe (AI Model) to colorize it, and the result comes back to you.
---
## CHAPTER 2: Understanding Computers & Software
### What Is a Computer?
A computer is a machine that follows instructions fast. It has:
- **CPU**: The "brain" — runs calculations.
- **RAM**: Short-term memory — stores things being used right now (like a whiteboard you erase daily).
- **Hard Disk/SSD**: Long-term memory — stores files permanently (like a filing cabinet).
### What Is Software?
Software is a set of instructions written in a **programming language**. Just like recipes tell a chef what to cook, code tells a CPU what to calculate.
### What Is the Internet?
A global network of computers talking to each other. When you visit a website, your computer (the **client**) sends a request to another computer (the **server**), which responds with the page.
```
YOU (Client) ---[Request]--> SERVER
<--[Response]-- SERVER
```
### What Is a Programming Language?
Humans speak English or Hindi. Computers speak binary (0s and 1s). A programming language sits in between — you write human-readable code, the computer converts it to binary.
We use three:
1. **Python** — AI and backend server logic
2. **JavaScript (React)** — Website frontend
3. **CSS** — Visual styling
---
## CHAPTER 3: Installing Everything You Need
### Step 1: Install Python
1. Go to https://www.python.org/downloads/
2. Download Python 3.11 or newer.
3. **IMPORTANT**: During installation, check "Add Python to PATH".
4. Click Install.
Verify in your terminal (search "cmd" on Windows, "Terminal" on Mac):
```
python --version
```
You should see: `Python 3.11.x`
### Step 2: Install Node.js
Node.js lets JavaScript run outside a browser, needed for React.
1. Go to https://nodejs.org/
2. Download the **LTS** version.
3. Install with default settings.
Verify:
```
node --version
npm --version
```
### Step 3: Install VS Code
VS Code is a free code editor — like Microsoft Word but for programming.
1. Go to https://code.visualstudio.com/
2. Download and install.
### Step 4: Install Git
Git is a "time machine" for your code.
1. Go to https://git-scm.com/downloads
2. Download and install.
Verify:
```
git --version
```
### Step 5: Install Python Libraries
In your terminal:
```bash
pip install opencv-python numpy flask flask-cors
```
What each does:
- `opencv-python` → image processing superpowers
- `numpy` → fast math on large grids of numbers
- `flask` → turns Python into a web server
- `flask-cors` → lets the website talk to the server safely
---
# ═══════════════════════════════════════
# PART 2: LEARNING PYTHON — THE LANGUAGE OF AI
# ═══════════════════════════════════════
---
## CHAPTER 4: Your First Python Program
Open VS Code, create a file called `hello.py`, and type:
```python
print("Hello, World!")
```
In the terminal:
```
python hello.py
```
Output: `Hello, World!`
You are now a programmer. `print()` displays something on screen. The text in quotes is called a **string**.
---
## CHAPTER 5: Variables, Numbers & Text
A **variable** is a labelled box that stores a value.
```python
# Lines starting with # are comments — Python ignores them
name = "Anannya" # string (text)
age = 20 # integer (whole number)
gpa = 9.5 # float (decimal)
is_student = True # boolean (True or False)
print(name) # Anannya
print(age) # 20
```
### Math
```python
a = 10
b = 3
print(a + b) # 13 (addition)
print(a - b) # 7 (subtraction)
print(a * b) # 30 (multiplication)
print(a / b) # 3.333... (division)
print(a ** b) # 1000 (10 to the power of 3)
print(a % b) # 1 (remainder)
```
### f-strings (embed variables in text)
```python
name = "Anannya"
msg = f"Hello, {name}! Welcome to AI."
print(msg) # Hello, Anannya! Welcome to AI.
```
---
## CHAPTER 6: Making Decisions (If / Else)
```python
temperature = 35
if temperature > 30:
print("Very hot! Stay hydrated.")
elif temperature > 20:
print("Warm outside.")
else:
print("Cool today.")
```
**Notice**: Python uses **indentation** (4 spaces) to group code. Everything indented under `if` belongs to that block.
```python
# Real example from our project:
file_extension = ".jpg"
if file_extension == ".jpg" or file_extension == ".png":
print("Valid image!")
else:
print("Error: Please upload a JPG or PNG.")
```
---
## CHAPTER 7: Loops — Doing Things Repeatedly
### The `for` Loop (repeat a fixed number of times)
```python
for i in range(1, 6):
print(f"Step: {i}")
# Output: Step: 1, Step: 2 ... Step: 5
```
### Loop through a list
```python
colors = ["red", "green", "blue"]
for color in colors:
print(f"Color: {color}")
```
### The `while` Loop (repeat until condition is False)
```python
count = 0
while count < 3:
print(f"Count: {count}")
count += 1 # same as: count = count + 1
```
---
## CHAPTER 8: Functions — Teaching Python New Tricks
A **function** is a named block of code you can run by calling its name. Write once, use many times.
```python
def greet(person_name):
message = f"Hello, {person_name}! Welcome to AI."
return message
result = greet("Anannya")
print(result)
result2 = greet("John")
print(result2)
```
Without functions, greeting 100 people means 100 lines of repetitive code. With a function, you write it once and call it 100 times. This is the **DRY principle** — Don't Repeat Yourself.
```python
def calculate_area(width, height):
return width * height
area = calculate_area(10, 5)
print(f"Area: {area} sq meters") # Area: 50 sq meters
```
---
## CHAPTER 9: Lists & Dictionaries
### Lists — Ordered collections
```python
fruits = ["apple", "banana", "cherry", "mango"]
print(fruits[0]) # "apple" — index starts at 0!
print(fruits[2]) # "cherry"
print(len(fruits)) # 4 — number of items
fruits.append("grape") # add to end
print(fruits[1:3]) # ["banana", "cherry"] — slicing
```
### Dictionaries — Key-Value pairs
Like a real dictionary: look up a word (key) to find its meaning (value).
```python
person = {
"name": "Anannya",
"age": 20,
"courses": ["Python", "AI"]
}
print(person["name"]) # "Anannya"
person["city"] = "Mumbai" # Add new key
```
**Why this matters:** When our server responds to the frontend, it sends a dictionary in JSON format:
```python
{
"image": "data:image/jpeg;base64,...",
"message": "Successfully colorized"
}
```
---
## CHAPTER 10: Files — Reading and Writing Data
```python
# Reading a text file
with open("story.txt", "r") as file:
content = file.read()
print(content)
# Writing a text file
with open("output.txt", "w") as file:
file.write("AI is amazing!\n")
```
Always use `with` — it automatically closes the file when done.
### Binary files (images)
Image files are not plain text — they are binary data.
```python
# Read an image as raw bytes
with open("photo.jpg", "rb") as file: # rb = read binary
image_bytes = file.read()
# Write bytes to a new file
with open("copy.jpg", "wb") as file: # wb = write binary
file.write(image_bytes)
```
This is exactly what our Flask server does — it receives an uploaded image as bytes, passes them to OpenCV, and returns colorized bytes.
---
## CHAPTER 11: Classes & Objects
### The Concept
Imagine building a game with 50 cars. Each car has properties (color, speed) and actions (drive, brake). Instead of 50 separate variables, you create one **class** — a blueprint — and make 50 **objects** from it.
```python
class Car:
def __init__(self, brand, color): # runs when object is created
self.brand = brand
self.color = color
self.fuel = 100
def drive(self, distance):
used = distance * 0.1
self.fuel -= used
print(f"{self.brand} drove {distance}km. Fuel: {self.fuel}L")
# Create two Car objects from the blueprint
car1 = Car("Toyota", "Red")
car2 = Car("BMW", "Blue")
car1.drive(50) # Toyota drove 50km. Fuel: 95.0L
car2.drive(100) # BMW drove 100km. Fuel: 90.0L
```
Our `ImageColorizer` class follows the same pattern:
```python
class ImageColorizer:
def __init__(self, model_dir): # Set up file paths
...
def load_model(self): # Load the neural network
...
def colorize(self, img_bytes): # Colorize an image
...
```
---
# ═══════════════════════════════════════
# PART 3: THE SCIENCE OF IMAGES
# ═══════════════════════════════════════
---
## CHAPTER 12: What Is a Digital Image?
A digital image is a grid of tiny colored squares called **pixels** (picture elements).
- A 1920×1080 image has 1,920 × 1,080 = **over 2 million pixels**.
- Each pixel stores a color as **numbers**.
A grayscale pixel uses ONE number:
- 0 = pure black
- 128 = medium gray
- 255 = pure white
Think of a mosaic of millions of tiny colored tiles. From far away you see a beautiful image. Up close, you see individual squares.
---
## CHAPTER 13: The RGB Color Model
Most screens mix **Red + Green + Blue** light. Each pixel has three values, each from 0-255:
| Color | R | G | B |
|---|---|---|---|
| Red | 255 | 0 | 0 |
| Green | 0 | 255 | 0 |
| Blue | 0 | 0 | 255 |
| White | 255 | 255 | 255 |
| Black | 0 | 0 | 0 |
| Yellow | 255 | 255 | 0 |
| Orange | 255 | 165 | 0 |
A 1920×1080 color image stores **1920 × 1080 × 3 = 6.2 million numbers**.
### The Problem for AI Colorization
A grayscale image has ONE number per pixel (brightness). To colorize, the AI must predict THREE numbers (R, G, B). The trouble: a medium-dark pixel could be dark red, dark green, dark blue, or dark brown. The AI must guess three interlinked values simultaneously. Scientists found a smarter approach...
---
## CHAPTER 14: The Lab Color Space — The Secret Sauce
Lab is a different way to describe color. Instead of R, G, B it uses:
- **L (Lightness)**: How bright or dark (0=black, 100=white)
- **a (Green-Red axis)**: Negative = green, Positive = red
- **b (Blue-Yellow axis)**: Negative = blue, Positive = yellow
### Why Lab Is Brilliant for AI
**A black and white photo is already the L channel.**
A grayscale image IS the L layer of Lab. We already have L. The AI only needs to predict **a and b** — two values instead of three, and they are mathematically independent of brightness.
```
RGB approach: grayscale (1 value) → predict R, G, B (3 guesses) = Harder
Lab approach: grayscale = L (known!) → predict a, b (2 guesses) = Easier!
```
The neural network takes L as input and outputs predicted a and b. We then combine L (original) + a (predicted) + b (predicted) = full color image.
---
## CHAPTER 15: OpenCV — The Image Processing Library
OpenCV (Open Source Computer Vision) is a massive library written over 20 years. Instead of writing all image math ourselves, we use its functions.
```python
import cv2
import numpy as np
# Load an image from disk
img = cv2.imread("photo.jpg")
# img is a NumPy array with shape (height, width, 3)
print(img.shape) # e.g., (480, 640, 3)
print(img.dtype) # uint8 (integers 0-255)
```
### Important: OpenCV uses BGR, not RGB!
OpenCV loads images as **Blue-Green-Red** — the channels are reversed from normal RGB. This is a historical quirk. Always be aware of this.
```python
# Convert from BGR to Lab color space
scaled = img.astype("float32") / 255.0
lab = cv2.cvtColor(scaled, cv2.COLOR_BGR2LAB)
# Split into 3 channels
L, a, b = cv2.split(lab) # Each is a 2D array (height, width)
```
---
# ═══════════════════════════════════════
# PART 4: THE BRAIN — DEEP LEARNING & NEURAL NETWORKS
# ═══════════════════════════════════════
---
## CHAPTER 16: What Is Artificial Intelligence?
### AI Is Pattern Recognition
A child sees thousands of apples and learns what an apple looks like. A child reads thousands of sentences and learns grammar. **AI does the same — it learns by analyzing massive data and finding mathematical patterns.**
AI is not magic. It is math — specifically statistics and linear algebra running at enormous speed on millions of data points.
### AI Hierarchy
```
Artificial Intelligence (broad category)
└── Machine Learning (AI that learns from data)
└── Deep Learning (AI with many layers)
└── CNNs (AI for images)
└── Our Colorization Model
```
---
## CHAPTER 17: How a Neural Network Works
### The Neuron
A biological brain neuron: receives signals → processes them → sends output.
An artificial neuron does the same mathematically:
```
Input 1 × Weight 1 ┐
Input 2 × Weight 2 ┤ → Sum → Activation Function → Output
Input 3 × Weight 3 ┘
```
- Each input is multiplied by a "weight" (how important it is)
- They are all added up
- The sum passes through an "activation function" to decide the output
### Layers of Neurons
A neural network chains neurons in layers:
```
INPUT LAYER HIDDEN LAYERS OUTPUT LAYER
(pixel brightness) (find patterns) (color prediction)
[255] [●] [●] [●]
[100] ────► [●] [●] [●] ────► [predicted_a]
[200] [●] [●] [●] [predicted_b]
[50 ] [●] [●] [●]
... ...
```
- **Input layer**: Raw L channel pixels
- **Hidden layers**: Where patterns emerge (edges, textures, objects)
- **Output layer**: Predicted ab color values
Every time the model makes a wrong prediction, the **weights** are slightly adjusted. After millions of images and millions of adjustments, the weights settle into values that make accurate predictions. That process is called **training**.
### Convolutional Neural Networks (CNNs)
For images we use CNNs. Instead of connecting every pixel to every neuron (billions of connections!), a CNN uses small filters that slide across the image, detecting local patterns:
- Early layers → edges and lines
- Middle layers → textures and shapes
- Deep layers → high-level concepts (sky, skin, grass)
This is how the AI "knows" that blue-ish areas of appropriate brightness are sky.
---
## CHAPTER 18: Training vs. Using a Model
### Training — The Long, Expensive Process
1. Show the neural network millions of color photos
2. Convert each to grayscale (remove a and b)
3. Ask the network to predict a and b back
4. Compare prediction to the real answer
5. Adjust weights to be slightly more accurate
6. Repeat millions of times
Training can take **weeks** on powerful GPU servers. The result is saved to a `.caffemodel` file — all the learned weights in one file.
We use a **pre-trained model** created by researchers at UC Berkeley. Training it ourselves would cost thousands of dollars in cloud computing.
### Inference — Just Using the Model
Inference = using the trained model to make predictions.
1. Load the `.caffemodel` weights
2. Give it a grayscale image (L channel)
3. Data flows through all layers (forward pass)
4. The model outputs predicted ab channels
This takes **less than a second** on a modern laptop.
---
## CHAPTER 19: The Colorization Model (Caffe DNN)
Our model was created by Richard Zhang, Phillip Isola, and Alexei Efros at UC Berkeley, published at ECCV 2016.
### Key Innovation: Color Probability Distribution
Instead of predicting a single exact color, the model predicts a **probability distribution across 313 color buckets**.
Imagine asking: "Given this dark-medium brightness pixel, what color is most likely?"
- Dark blue sky: 55% likely
- Dark green leaf: 30% likely
- Dark brown earth: 15% likely
This distribution approach produces more vivid, realistic results than predicting a single value.
The `pts_in_hull.npy` file stores the coordinates of those 313 color buckets in Lab space.
### The Three Required Files
| File | Size | Purpose |
|---|---|---|
| `colorization_deploy_v2.prototxt` | ~10KB | Blueprint of the neural network architecture |
| `colorization_release_v2.caffemodel` | ~123MB | The learned weights (the "brain") |
| `pts_in_hull.npy` | ~5KB | The 313 color cluster centers |
---
## CHAPTER 20: OpenCV's DNN Module
OpenCV includes a DNN module that can load and run pre-trained models from Caffe, TensorFlow, and PyTorch — without needing those frameworks installed.
```python
import cv2
import numpy as np
# Load the model
net = cv2.dnn.readNetFromCaffe("model.prototxt", "model.caffemodel")
# Insert the cluster center points as layer weights
kernel = np.load("pts_in_hull.npy")
class8 = net.getLayerId("class8_ab")
pts = kernel.transpose().reshape(2, 313, 1, 1)
net.getLayer(class8).blobs = [pts.astype("float32")]
# Prepare image as a 4D "blob" the DNN expects
blob = cv2.dnn.blobFromImage(L_channel)
# Run the forward pass (inference!)
net.setInput(blob)
ab_output = net.forward() # Returns predicted ab channels
```
---
# ═══════════════════════════════════════
# PART 5: BUILDING THE BACKEND (THE ENGINE)
# ═══════════════════════════════════════
---
## CHAPTER 21: What Is a Server?
A **server** is a computer (or program) that listens for requests and sends responses.
When you visit a website:
1. Your browser sends a request
2. The server receives it
3. The server processes it
4. The server sends back a response
5. Your browser displays it
Our server is **local** — it runs on your own computer, not on the internet. `localhost` means "this computer." Port `5000` is the specific "door" our server listens on.
```
Browser (localhost:5173) --- Upload image --> Server (localhost:5000)
<-- Colorized image --
```
---
## CHAPTER 22: Flask — Python's Web Framework
Flask makes it easy to create a web server in Python. Without it, you'd write hundreds of lines of networking code. Flask lets you define **routes** (URLs the server handles) cleanly.
```python
from flask import Flask
app = Flask(__name__) # Create the Flask application
@app.route('/') # Handle requests to http://localhost:5000/
def home():
return "Server is running!"
if __name__ == '__main__':
app.run(port=5000) # Start listening on port 5000
```
Run `python app.py` and visit http://localhost:5000/ — you see "Server is running!"
The `@app.route('/')` is a **decorator** — it tells Flask which function to call for each URL.
### Request Types
- **GET** — "Give me something" (loading a page)
- **POST** — "Take this data and do something with it" (uploading a file)
---
## CHAPTER 23: APIs — How Software Talks to Software
**API** = Application Programming Interface. A set of rules for how two programs communicate.
Think of a restaurant menu:
- The menu lists what you can order (API endpoints)
- You tell the waiter (make a request)
- The kitchen makes it (server processes)
- The waiter brings it to you (response)
Our app's API:
| URL | Method | What It Does |
|---|---|---|
| `/api/status` | GET | Is the server running? |
| `/api/colorize` | POST | Upload B&W image, get colorized image |
### JSON — The Language of APIs
JSON (JavaScript Object Notation) is the standard data format for APIs:
```json
{
"image": "data:image/jpeg;base64,...",
"message": "Successfully colorized"
}
```
It looks exactly like a Python dictionary.
---
## CHAPTER 24: Coding `colorizer.py` — Line by Line
```python
import numpy as np # Fast math on grids of numbers
import cv2 # Image processing
import os # File path and directory operations
import urllib.request # Download files from the internet
class ImageColorizer:
"""
Manages the AI colorization model:
- Downloads model files if missing
- Loads the neural network
- Colorizes images
"""
def __init__(self, model_dir='Model'):
# Store paths to each required file
self.model_dir = model_dir
self.prototxt = os.path.join(model_dir, "colorization_deploy_v2.prototxt")
self.caffemodel= os.path.join(model_dir, "colorization_release_v2.caffemodel")
self.pts_hull = os.path.join(model_dir, "pts_in_hull.npy")
# Download URLs
self.urls = {
self.prototxt: "https://storage.openvinotoolkit.org/...prototxt",
self.caffemodel: "https://storage.openvinotoolkit.org/...caffemodel",
self.pts_hull: "https://storage.openvinotoolkit.org/...pts_in_hull.npy"
}
self.net = None # Neural network (loaded on first use)
self.pts = None # Cluster center points
# Create the Model/ folder if it doesn't exist
if not os.path.exists(self.model_dir):
os.makedirs(self.model_dir)
def _download_file(self, url, filepath):
"""Download a file only if it doesn't already exist."""
if not os.path.exists(filepath):
print(f"Downloading {os.path.basename(filepath)}...")
try:
# Add User-Agent header so servers don't block the download
req = urllib.request.Request(url,
headers={'User-Agent': 'Mozilla/5.0'})
with urllib.request.urlopen(req) as response:
with open(filepath, 'wb') as f:
f.write(response.read()) # Write all bytes to disk
return True
except Exception as e:
print(f"Download failed: {e}")
return False
return True # Already exists
def load_model(self):
"""Load the neural network into memory. Must call before colorizing."""
# Download files if needed
for filepath, url in self.urls.items():
self._download_file(url, filepath)
# Load the Caffe network:
# prototxt = architecture (the skeleton/blueprint)
# caffemodel = weights (the learned knowledge)
self.net = cv2.dnn.readNetFromCaffe(self.prototxt, self.caffemodel)
self.pts = np.load(self.pts_hull)
# Inject the 313 cluster center points into the network layers
# This teaches the network HOW to turn its 313-class output into ab values
class8 = self.net.getLayerId("class8_ab")
conv8 = self.net.getLayerId("conv8_313_rh")
# Reshape from (313, 2) → (2, 313, 1, 1) — the format DNN expects
pts = self.pts.transpose().reshape(2, 313, 1, 1)
self.net.getLayer(class8).blobs = [pts.astype("float32")]
# 2.606 is a color rebalancing factor from the original research paper
# It encourages more vivid, saturated colors in the output
self.net.getLayer(conv8).blobs = [np.full([1, 313], 2.606, dtype="float32")]
def colorize(self, img_bytes):
"""
Take raw image bytes, return colorized image as bytes.
Steps:
1. Decode bytes → NumPy array
2. Convert BGR → Lab, scale to 0-1
3. Extract L channel, resize to 224x224
4. Run neural network inference
5. Recombine L + predicted ab
6. Convert back to BGR, encode as JPEG bytes
"""
# Load the model on first use
if self.net is None:
self.load_model()
# STEP 1: Decode image bytes into a NumPy array
nparr = np.frombuffer(img_bytes, np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
if img is None:
raise ValueError("Could not decode image.")
# STEP 2: Scale pixel values from 0-255 to 0.0-1.0
# Neural networks work better with small decimal numbers
scaled = img.astype("float32") / 255.0
# STEP 3: Convert BGR → Lab color space
lab = cv2.cvtColor(scaled, cv2.COLOR_BGR2LAB)
# STEP 4: Resize to 224x224 — the size the model was trained on
resized = cv2.resize(lab, (224, 224))
# STEP 5: Extract L channel alone
L = cv2.split(resized)[0] # split returns [L, a, b]; [0] = L
# STEP 6: Subtract mean L value (~50) to center the data around zero
# The training data was preprocessed this way, so we must match it
L -= 50
# STEP 7: Run neural network inference
# blobFromImage wraps L into shape: (1, 1, 224, 224)
self.net.setInput(cv2.dnn.blobFromImage(L))
# forward() runs all the layers and returns shape: (1, 2, 224, 224)
ab_raw = self.net.forward()
# Rearrange axes from (1, 2, H, W) → (H, W, 2) for OpenCV
ab = ab_raw[0, :, :, :].transpose((1, 2, 0))
# STEP 8: Resize predicted ab back to original image dimensions
ab = cv2.resize(ab, (img.shape[1], img.shape[0]))
# STEP 9: Get the L channel from the FULL RESOLUTION lab image
L_full = cv2.split(lab)[0]
# STEP 10: Combine L (original, full res) + ab (predicted)
# np.newaxis adds a dimension: (H,W) → (H,W,1) so we can concatenate
colorized = np.concatenate((L_full[:, :, np.newaxis], ab), axis=2)
# STEP 11: Convert Lab → BGR for saving
colorized = cv2.cvtColor(colorized, cv2.COLOR_LAB2BGR)
# STEP 12: Clip to valid range, convert back to 0-255 integers
colorized = np.clip(colorized, 0, 1)
colorized = (255 * colorized).astype("uint8")
# STEP 13: Encode as JPEG bytes to send over the network
_, buffer = cv2.imencode('.jpg', colorized)
return buffer.tobytes()
```
---
## CHAPTER 25: Coding `app.py` — Line by Line
```python
from flask import Flask, request, jsonify
from flask_cors import CORS
import base64
from colorizer import ImageColorizer
app = Flask(__name__)
# CORS = Cross-Origin Resource Sharing
# Browsers block requests between different "origins" by default
# localhost:5173 (React) and localhost:5000 (Flask) are different origins
# CORS(app) allows them to communicate
CORS(app)
# Create one shared colorizer object
colorizer = ImageColorizer()
@app.route('/api/status', methods=['GET'])
def check_status():
"""Health check — confirms the server is running."""
return jsonify({"status": "running"})
@app.route('/api/colorize', methods=['POST'])
def colorize_image():
"""
Main endpoint.
Expects: multipart form data with an image file under key 'image'
Returns: JSON with base64-encoded colorized image
"""
# Check the request includes a file
if 'image' not in request.files:
return jsonify({"error": "No image uploaded"}), 400 # 400 = Bad Request
file = request.files['image']
if file.filename == '':
return jsonify({"error": "No file selected"}), 400
try:
img_bytes = file.read() # Read file as bytes
colorized_bytes = colorizer.colorize(img_bytes) # Run AI
# Encode bytes as base64 string
# JSON cannot hold raw binary, but can hold base64 text
encoded = base64.b64encode(colorized_bytes).decode('utf-8')
# Build a data URL — directly usable by HTML
return jsonify({
"image": f"data:image/jpeg;base64,{encoded}",
"message": "Successfully colorized!"
})
except Exception as e:
return jsonify({"error": str(e)}), 500 # 500 = Internal Server Error
if __name__ == '__main__':
app.run(port=5000)
```
---
# ═══════════════════════════════════════
# PART 6: BUILDING THE FRONTEND (THE FACE)
# ═══════════════════════════════════════
---
## CHAPTER 26: What Is a Web Page?
Every website is three technologies working together:
- **HTML** — Structure and content (the skeleton)
- **CSS** — Appearance (the clothes)
- **JavaScript** — Behavior (the muscles)
A browser reads these three and renders the interactive page you see.
---
## CHAPTER 27: HTML — The Skeleton
HTML uses **tags** to define content elements:
```html
A paragraph.
```
In our React app, there is one small `index.html`. React builds the entire rest of the page dynamically with JavaScript.
---
## CHAPTER 28: CSS — The Styling
CSS applies visual styles to HTML elements:
```css
/* Dark background, white text */
body {
background-color: #050505;
color: white;
font-family: 'Inter', sans-serif;
margin: 0;
}
/* Glassmorphism effect */
.glass {
background: rgba(255, 255, 255, 0.03); /* very faint white */
backdrop-filter: blur(12px); /* blur background */
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 24px; /* rounded corners */
}
/* Gradient text */
.hero-text {
background: linear-gradient(135deg, #fff 30%, #3b82f6);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent; /* show gradient through text */
font-size: 4rem;
font-weight: 800;
}
/* Hover: lift and glow on button */
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 15px -3px rgba(59, 130, 246, 0.4);
}
```
### CSS Animations
```css
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.animate-fade-in {
animation: fadeIn 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
```
---
## CHAPTER 29: JavaScript — The Behavior
JavaScript runs in the browser and makes pages interactive.
```javascript
// Variables
let count = 0; // can change (let)
const PI = 3.14; // cannot change (const)
// Functions (arrow syntax)
const greet = (name) => `Hello, ${name}!`;
// Sending a network request
fetch('http://localhost:5000/api/status')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
```
The `fetch()` function sends an HTTP request to a URL and returns a Promise (a value that will arrive in the future). `.then()` handles the result when it arrives.
---
## CHAPTER 30: React — Building Modern Interfaces
### What Is React?
React (by Meta/Facebook) is a JavaScript library for **component-based** user interfaces. Instead of one massive HTML file, you build small reusable **components** (like Lego bricks) and compose them together.
### Components
A React component is a function that returns JSX (HTML inside JavaScript):
```jsx
function MyButton({ label, onClick }) { // props = inputs to the component
return (
);
}
// Use it
Count: {count}
` automatically shows the new number. You never touch the DOM manually. --- ## CHAPTER 31: The Upload Component Our upload zone handles two interactions: drag-and-drop and click-to-browse. ```jsx // State const [image, setImage] = useState(null) const [originalUrl, setOriginalUrl] = useState(null) const [dragging, setDragging] = useState(false) const processFile = (file) => { setImage(file) // createObjectURL creates a temporary local URL for instant preview setOriginalUrl(URL.createObjectURL(file)) } const handleDragOver = (e) => { e.preventDefault() // REQUIRED to allow dropping setDragging(true) } const handleDrop = (e) => { e.preventDefault() setDragging(false) const file = e.dataTransfer.files[0] if (file && file.type.startsWith('image/')) processFile(file) } // JSX
Drop your B&W photo here or click to browse
}