# How to Use OpenCV for Image Preprocessing in Computer Vision: A Four-Stage Pipeline

> Learn how to use OpenCV for image preprocessing in computer vision with our four-stage pipeline. Enhance images for neural networks using key functions.

- Repository: [Microsoft/AI-For-Beginners](https://github.com/microsoft/AI-For-Beginners)
- Tags: how-to-guide
- Published: 2026-08-08

---

**OpenCV provides a four-stage preprocessing workflow—loading, color-space conversion, photometric adjustments, and geometric transforms—that prepares raw images for neural networks using functions like `cv2.imread`, `cv2.cvtColor`, and `cv2.warpAffine`.**

The microsoft/AI-For-Beginners curriculum demonstrates how to use OpenCV for image preprocessing in computer vision tasks ranging from basic classification to specialized Braille-symbol extraction. According to the source code in [`lessons/4-ComputerVision/06-IntroCV/README.md`](https://github.com/microsoft/AI-For-Beginners/blob/main/lessons/4-ComputerVision/06-IntroCV/README.md) (lines 26–60), preprocessing bridges the gap between raw image files and the normalized tensor inputs required by deep learning models.

## The Four Stages of OpenCV Preprocessing

The curriculum organizes image preprocessing into four logical stages. Each stage addresses specific data quality requirements and is implemented using precise OpenCV function calls that operate on NumPy arrays.

### Stage 1: Loading Images with cv2.imread

OpenCV reads image files using `cv2.imread`, which returns a NumPy array in **BGR color order** by default. This differs from the RGB format expected by most Python visualization libraries, necessitating an immediate conversion.

```python
import cv2
import matplotlib.pyplot as plt

# Load image in BGR format (OpenCV default)

im = cv2.imread('image.jpeg')

# Convert to RGB for display

plt.imshow(cv2.cvtColor(im, cv2.COLOR_BGR2RGB))
plt.title('Original BGR → RGB')
plt.show()

```

### Stage 2: Color-Space Conversion

The `cv2.cvtColor` function transforms images between color spaces to match model requirements or visualization tools. Converting BGR to RGB ensures compatibility with Matplotlib, while grayscale conversion (`COLOR_BGR2GRAY`) reduces dimensionality for thresholding operations.

### Stage 3: Photometric Adjustments

This stage improves signal-to-noise ratio through resizing, blurring, and intensity adjustments. The curriculum demonstrates `cv2.resize` with Lanczos interpolation for quality preservation, `cv2.medianBlur` for noise reduction, and `cv2.convertScaleAbs` for contrast and brightness modifications.

```python

# Resize using high-quality interpolation

resized = cv2.resize(im, (320, 200), interpolation=cv2.INTER_LANCZOS)

# Apply median blur (ksize must be odd)

blurred = cv2.medianBlur(resized, ksize=3)

# Adjust contrast (alpha) and brightness (beta)

alpha = 1.2   # contrast factor

beta = 30     # brightness offset

adjusted = cv2.convertScaleAbs(blurred, alpha=alpha, beta=beta)

plt.imshow(cv2.cvtColor(adjusted, cv2.COLOR_BGR2RGB))
plt.title('Resized, Blurred, and Adjusted')
plt.show()

```

### Stage 4: Geometric Transforms and Thresholding

Final preprocessing steps include spatial alignment and binarization. `cv2.threshold` and `cv2.adaptiveThreshold` create binary masks for segmentation, while `cv2.warpAffine` and `cv2.warpPerspective` correct perspective distortion or align objects.

```python

# Convert to grayscale for thresholding

gray = cv2.cvtColor(adjusted, cv2.COLOR_BGR2GRAY)

# Binary thresholding (Otsu-like)

_, binary = cv2.threshold(gray, thresh=127, maxval=255, type=cv2.THRESH_BINARY)

plt.imshow(binary, cmap='gray')
plt.title('Binary Threshold Result')
plt.show()

```

For geometric alignment, affine transformations rotate or shear images using transformation matrices:

```python
import numpy as np

rows, cols = binary.shape[:2]
pts1 = np.float32([[0,0], [cols-1,0], [0,rows-1]])
pts2 = np.float32([[0,0], [int(0.8*cols), int(0.2*rows)], [int(0.2*cols), int(0.9*rows)]])

M = cv2.getAffineTransform(pts1, pts2)
affine = cv2.warpAffine(binary, M, (cols, rows))

plt.imshow(affine, cmap='gray')
plt.title('Affine Warp')
plt.show()

```

Perspective correction uses homography matrices to rectify tilted documents:

```python

# Define source and destination points

pts_src = np.float32([[100,100], [400,80], [80,400], [400,420]])
pts_dst = np.float32([[0,0], [300,0], [0,300], [300,300]])

# Calculate and apply perspective transform

H = cv2.getPerspectiveTransform(pts_src, pts_dst)
perspective = cv2.warpPerspective(im, H, (300,300))

plt.imshow(cv2.cvtColor(perspective, cv2.COLOR_BGR2RGB))
plt.title('Perspective Corrected')
plt.show()

```

## Implementation Resources in AI-For-Beginners

The complete preprocessing workflow is documented in the following repository files:

- **[`lessons/4-ComputerVision/06-IntroCV/README.md`](https://github.com/microsoft/AI-For-Beginners/blob/main/lessons/4-ComputerVision/06-IntroCV/README.md)** (lines 26–60): Contains the conceptual overview and function documentation for loading and processing images.
- **`lessons/4-ComputerVision/06-IntroCV/OpenCV.ipynb`**: An executable Jupyter notebook that combines all preprocessing stages into workflows for Braille extraction and motion detection (referenced in README.md lines 61–85).
- **[`lessons/4-ComputerVision/06-IntroCV/lab/README.md`](https://github.com/microsoft/AI-For-Beginners/blob/main/lessons/4-ComputerVision/06-IntroCV/lab/README.md)**: Provides advanced lab assignments applying these techniques to optical flow and video analysis.

## Summary

- **OpenCV for image preprocessing** follows a four-stage pipeline: loading, color-space conversion, photometric adjustment, and geometric transformation.
- **`cv2.imread`** loads images as BGR NumPy arrays, requiring **`cv2.cvtColor`** for RGB compatibility with visualization tools.
- **Photometric operations** include **`cv2.resize`** for scaling, **`cv2.medianBlur`** for denoising, and **`cv2.convertScaleAbs`** for intensity adjustments.
- **Segmentation tasks** rely on **`cv2.threshold`** or **`cv2.adaptiveThreshold`** for binarization.
- **Spatial alignment** uses **`cv2.warpAffine`** and **`cv2.warpPerspective`** with matrices generated by **`cv2.getAffineTransform`** and **`cv2.getPerspectiveTransform`**.

## Frequently Asked Questions

### What is the difference between cv2.imread and other image loading methods?

**`cv2.imread`** specifically loads images into NumPy arrays in BGR channel order rather than RGB. This distinction is critical because most Python visualization libraries like Matplotlib expect RGB format, necessitating immediate conversion using `cv2.cvtColor(im, cv2.COLOR_BGR2RGB)` before display.

### When should I use median blur versus Gaussian blur in OpenCV?

**`cv2.medianBlur`** is optimal for removing salt-and-pepper noise while preserving edges, making it ideal for preprocessing text or symbol recognition tasks demonstrated in the Braille extraction examples. **`cv2.GaussianBlur`** applies a weighted average better suited for general noise reduction in natural photographs where edge preservation is less critical.

### How do I correct perspective distortion using OpenCV?

Use **`cv2.getPerspectiveTransform`** to compute a 3x3 homography matrix from four corresponding source and destination points, then apply it with **`cv2.warpPerspective`**. This technique rectifies tilted documents or objects viewed from oblique angles, transforming them into a frontal planar view as shown in the document correction code example.

### Why does OpenCV use BGR instead of RGB color format?

OpenCV uses BGR format for historical reasons related to early camera hardware and Windows API conventions. When using OpenCV for image preprocessing in computer vision workflows, you must convert to RGB using **`cv2.cvtColor`** before visualization or when interfacing with libraries that expect standard RGB ordering, such as Matplotlib or most PyTorch/TensorFlow data loaders.