← All articles

Artificial Vision and Computer Vision: From Pixels to Understanding

An introduction to computer vision and image processing. From spatial domain operations to frequency transforms, with practical Python examples using OpenCV.

11 min read

Introduction

Computer vision, often called artificial vision, is the field of artificial intelligence that enables computers to interpret and understand the visual world. It processes digital images and videos to extract meaningful information, make decisions, and take actions based on visual input. From medical diagnoses to autonomous vehicles navigating highways, computer vision powers many of today’s most transformative technologies.

At its core, computer vision asks a fundamental question: how can we teach machines to “see” and understand images the way humans do? While human vision is intuitive, the computational challenges are immense. A digital image is just a matrix of numbers—pixel values—and extracting semantic meaning from these numbers requires sophisticated mathematical and computational techniques.

This article explores the foundational concepts of computer vision and image processing, starting with basic spatial domain operations and progressing to more advanced frequency domain techniques. We’ll examine practical applications and provide working code examples using OpenCV, a widely used computer vision library with Python bindings. The examples require OpenCV, NumPy and Matplotlib, input images at the stated paths, and a desktop GUIGraphical User Interface for cv2.imshow. They do not run unchanged in the browser runner. Later fragments reuse variables from earlier examples.

Understanding Visual Computing: Three Distinct Disciplines

Visual computing encompasses three closely related but distinct domains, each with different goals and methodologies.

Image Processing: Enhancing and Analyzing Images

Image processing is the transformation of an image to enhance it or extract useful information. It takes one image as input and produces another image (or data about that image) as output. Image processing focuses on improving image quality, extracting features, or preparing images for further analysis.

Common image processing tasks include:

  • Noise reduction and image denoising
  • Contrast enhancement
  • Feature extraction and edge detection
  • Image compression and restoration
  • Color space conversions

Image processing is domain-agnostic—the same techniques work across medical images, photographs, satellite imagery, and microscopy.

Computer Graphics: From 3D Models to 2D Display

Computer graphics creates or manipulates visual content, including 2D drawings and 3D rendering. In 3D rendering, models and scenes produce 2D images for display. Graphics rendering involves lighting calculations, texture mapping, perspective projection, and visual effects.

While computer vision asks “what is in this image?”, graphics asks “how do I create this image?” Applications include:

  • 3D scene rendering
  • Video game engines
  • Scientific visualization
  • Virtual and augmented reality

Computer Vision: Understanding and Interpreting Images

Computer vision goes beyond image processing to achieve understanding. It analyzes images to recognize objects, extract semantic meaning, track motion, reconstruct 3D scenes, and make intelligent decisions. Vision tasks include:

  • Object detection and classification
  • Facial recognition
  • Scene understanding
  • 3D reconstruction
  • Motion estimation

Image Processing in the Spatial Domain

Spatial domain processing operates directly on pixel values and their spatial relationships. Unlike frequency domain methods (which we’ll discuss later), spatial processing doesn’t transform images into other representations.

Geometric Transformations

Geometric transformations modify the spatial arrangement of pixels. These operations change position, size, or orientation without altering pixel intensities (in the ideal case).

Rotation

Rotation pivots an image around a center point by a specified angle. When rotating, we face a fundamental challenge: pixel coordinates in the rotated image often fall between integer positions of the original image, requiring interpolationEstimating a pixel value between known pixels from its neighbors..

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Read image
image = cv2.imread('photo.jpg')
height, width = image.shape[:2]
center = (width // 2, height // 2)

# Rotate 45 degrees clockwise (negative angle)
rotation_matrix = cv2.getRotationMatrix2D(center, -45, 1.0)
rotated = cv2.warpAffine(image, rotation_matrix, (width, height))

cv2.imshow('Rotated Image', rotated)
cv2.waitKey(0)

The rotation matrix is a 2×3 affine transformationA transformation that keeps straight and parallel lines: rotation, scaling, translation and shear. matrix that OpenCV applies using warpAffine. The third parameter (1.0) is a scale factor for zooming during rotation.

Scaling (Zoom)

Scaling resizes an image by a factor. Upscaling (enlarging) requires interpolation. Downscaling also resamples the image; area interpolation is often useful for reducing aliasingArtifacts such as jagged edges or moiré patterns, caused by sampling fine detail too coarsely., but not every resize method averages neighborhoods.

# Scale to 50% of original size
scaled_down = cv2.resize(image, (width // 2, height // 2),
                         interpolation=cv2.INTER_AREA)

# Scale to 200% of original size
scaled_up = cv2.resize(image, (width * 2, height * 2),
                       interpolation=cv2.INTER_CUBIC)

Different interpolation methods offer speed-quality tradeoffs:

  • INTER_NEAREST: Preserves discrete labels; may look blocky on photos.
  • INTER_LINEAR: Bilinear interpolation, a common general-purpose option.
  • INTER_AREA: Area-based resampling, often useful for shrinking.
  • INTER_CUBIC and INTER_LANCZOS4: Use larger neighborhoods and may improve some enlargements, but can introduce ringingRipples that appear next to sharp edges after some filters or resampling methods.. There is no universal best method. See OpenCV geometric transformsdocs.opencv.orgOpenCV reference for geometric image transformations, such as resize, warpAffine and the interpolation flags..

Translation

Translation shifts an image horizontally and vertically using a 2×3 translation matrix.

# Translate 100 pixels right and 50 pixels down
translation_matrix = np.float32([[1, 0, 100], [0, 1, 50]])
translated = cv2.warpAffine(image, translation_matrix, (width, height))

Histogram Processing and Equalization

A histogram represents the distribution of pixel intensity values. For grayscale 8-bit images, it shows how many pixels have each intensity from 0 (black) to 255 (white).

Histogram equalization redistributes pixel intensities to use the full range more uniformly, improving contrast in low-contrast images.

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Read in grayscale
gray = cv2.imread('photo.jpg', cv2.IMREAD_GRAYSCALE)

# Apply histogram equalization
equalized = cv2.equalizeHist(gray)

# For color images, convert to HSV and equalize the V channel
color_image = cv2.imread('photo.jpg')
hsv = cv2.cvtColor(color_image, cv2.COLOR_BGR2HSV)
hsv[:, :, 2] = cv2.equalizeHist(hsv[:, :, 2])
equalized_color = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR)

# Compare histograms visually
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
axes[0].hist(gray.ravel(), 256, [0, 256])
axes[0].set_title('Original Histogram')
axes[1].hist(equalized.ravel(), 256, [0, 256])
axes[1].set_title('Equalized Histogram')
plt.show()

Histogram equalization works by computing a cumulative distribution function (CDF) and using it to map old intensity values to new ones, spreading them across the full range. This technique is particularly valuable for medical imaging, where subtle intensity differences may contain diagnostic information.

Arithmetic Operations on Images

Arithmetic operations combine two or more images element-wise or apply mathematical functions to pixel values.

Addition

Adding images can blend or composite them together:

image1 = cv2.imread('photo1.jpg').astype(np.float32)
image2 = cv2.imread('photo2.jpg').astype(np.float32)

# Weighted average: 70% image1, 30% image2
blended = cv2.addWeighted(image1, 0.7, image2, 0.3, 0)

# Convert back to uint8 for display
blended = np.clip(blended, 0, 255).astype(np.uint8)
cv2.imshow('Blended', blended)

Image addition is useful for averaging multiple noisy measurements of the same scene to reduce noise.

Subtraction

Subtracting images reveals differences:

# Detect motion between frames
frame1 = cv2.imread('frame1.jpg').astype(np.float32)
frame2 = cv2.imread('frame2.jpg').astype(np.float32)

difference = cv2.absdiff(frame1, frame2)
# Keep intensity units: frame inputs are 8-bit images converted to float32.
difference = cv2.cvtColor(difference, cv2.COLOR_BGR2GRAY)
difference = np.clip(difference, 0, 255).astype(np.uint8)

# Use threshold to identify regions of significant change
_, motion_mask = cv2.threshold(difference, 30, 255, cv2.THRESH_BINARY)
cv2.imshow('Motion', motion_mask)

Difference images highlight changes and are fundamental to motion detection and change analysis.

Multiplication

Pixel-wise multiplication can apply gain or create masks:

# Create a mask (values 0-1)
mask = (image > 100).astype(np.float32)

# Apply mask to isolate bright regions
masked_image = image.astype(np.float32) * mask
masked_image = np.clip(masked_image, 0, 255).astype(np.uint8)

Spatial Filtering and Convolution

Spatial filters process each pixel using information from its neighborhood. Linear filters can be implemented using convolution or correlation. Nonlinear filters, such as the median filter, are not convolutions.

Convolution Concept

Convolution slides a small kernel (filter matrix) over the image, computing a weighted sum at each position. For a 2D image, the discrete convolution is:

Convolution: Output[i,j] = Σu Σv Kernel[u,v] × Image[i-u, j-v]
Correlation: Output[i,j] = Σu Σv Kernel[u,v] × Image[i+u, j+v]

The indices here are offsets from the kernel center. Convolution flips the kernel; correlation does not. cv2.filter2D and the explorable below use correlation. A symmetric blur kernel gives the same result either way; an asymmetric derivative kernel can change sign. See the OpenCV filtering referencedocs.opencv.orgOpenCV reference for image filtering, such as filter2D, blur, the median filter and Sobel..

The kernel defines what features the filter detects or what effect it applies.

Input image, 7×7

20202020202020202020202020202020200200200202020202002002002020202020020020020202020202020202020202020202020

Sobel x kernel

-101-202-101

Output, 5×5 (pick one)

(-1×20) + (0×200) + (1×200) + (-2×20) + (0×200) + (2×200) + (-1×20) + (0×200) + (1×200)= 720

A Sobel x kernel on a bright square. Pick any output pixel to see the 3×3 window it reads and the weighted sum it computes. The response is strongly positive on the square's left edge, negative on its right edge, and zero where the window sees no horizontal change.

Common Spatial Filters

Blur (Averaging Filter)

A simple averaging kernel reduces noise but also softens edges:

# Gaussian blur: weighted average with Gaussian kernel
blurred = cv2.GaussianBlur(image, (5, 5), 1.0)

# Simple box blur: equal weights
box_blurred = cv2.boxFilter(image, -1, (5, 5))

# Median filter: excellent for salt-and-pepper noise
median_filtered = cv2.medianBlur(image, 5)
Edge Detection

Edges are detected by computing image gradients. The Sobel operator approximates derivatives:

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

# Compute horizontal and vertical gradients
sobel_x = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)

# Magnitude of gradient
edge_magnitude = np.sqrt(sobel_x**2 + sobel_y**2)
maximum = edge_magnitude.max()
if maximum > 0:
    edge_magnitude = edge_magnitude / maximum * 255
edge_magnitude = edge_magnitude.astype(np.uint8)

# Canny edge detector (more sophisticated)
smoothed = cv2.GaussianBlur(gray, (5, 5), 1.4)
edges = cv2.Canny(smoothed, 100, 200)

cv2.imshow('Edges', edges)

The conceptual Canny pipeline smooths the image, computes gradients, performs non-maximum suppressionThinning edges by keeping only the pixels whose gradient is the largest along the gradient direction., and uses hysteresis thresholdingKeeping strong edges, and weak edges only when they connect to strong ones, with two thresholds.—it’s a complete edge detection pipeline. The example smooths explicitly before calling cv2.Canny.

Sharpening

Sharpening enhances edges by subtracting a blurred version from the original:

# Unsharp mask: sharpening via subtraction
blurred = cv2.GaussianBlur(gray, (0, 0), 2.0)
sharpened = cv2.addWeighted(gray, 1.5, blurred, -0.5, 0)
sharpened = np.clip(sharpened, 0, 255).astype(np.uint8)

Image Processing in the Frequency Domain

While spatial domain processing is intuitive and direct, frequency domain analysis provides powerful insights by decomposing images into sine and cosine waves of different frequencies.

Introduction to the Fourier Transform

The Fourier transform converts an image from the spatial domain (pixel intensity as a function of position) to the frequency domain (amplitude and phase as a function of frequency). This fundamental tool reveals which patterns and frequencies dominate an image.

The 2D Discrete Fourier Transform (DFT) is:

F[u,v] = Σ(x=0..M-1) Σ(y=0..N-1) f[x,y] × exp(-2πi(ux/M + vy/N))

where f[x,y] is the pixel value and F[u,v] is the frequency component.

Why Use the Frequency Domain?

Frequency domain processing offers advantages:

  • Efficient filtering: Some operations are faster in the frequency domain
  • Insight: Visualizing the frequency spectrum reveals image properties
  • Compression: Many compression algorithms work in the frequency domain (e.g., JPEGJoint Photographic Experts Group, the committee that created the format uses DCTDiscrete Cosine Transform)
  • Analysis: Periodic patterns and noise characteristics become obvious
import numpy as np
import matplotlib.pyplot as plt

# Compute FFT
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY).astype(np.float32)
fft = np.fft.fft2(image_gray)
fft_shifted = np.fft.fftshift(fft)  # Move zero frequency to center

# Magnitude spectrum (logarithmic scale for visualization)
magnitude = 20 * np.log1p(np.abs(fft_shifted))

# Phase spectrum
phase = np.angle(fft_shifted)

# Display
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.imshow(magnitude, cmap='gray')
plt.title('Magnitude Spectrum')
plt.colorbar()

plt.subplot(1, 2, 2)
plt.imshow(phase, cmap='gray')
plt.title('Phase Spectrum')
plt.colorbar()
plt.show()

The magnitude spectrum shows which frequencies are strong; the phase carries information about where features are located. Phase-only reconstructions can preserve recognizable structure for some images, but both magnitude and phase are needed for exact reconstruction; this is not a universal ranking of importance.

Practical Example: Building a Complete Image Processing Pipeline

Let’s combine multiple techniques in a realistic scenario: enhancing a low-contrast grayscale photograph. This is an image-processing demonstration, not a clinically validated medical-imaging workflow.

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Read image
image = cv2.imread('photo.jpg', cv2.IMREAD_GRAYSCALE)
if image is None:
    raise FileNotFoundError('photo.jpg')

# Step 1: Denoise using bilateral filter
# (preserves edges while smoothing)
denoised = cv2.bilateralFilter(image, 9, 75, 75)

# Step 2: Enhance contrast using CLAHE
# (Contrast Limited Adaptive Histogram Equalization)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
enhanced = clahe.apply(denoised)

# Step 3: Edge enhancement using high-pass filter
blurred = cv2.GaussianBlur(enhanced, (0, 0), 2.0)
high_pass = enhanced.astype(np.float32) - blurred.astype(np.float32)
sharpened = np.clip(enhanced.astype(np.float32) + 0.5 * high_pass, 0, 255)

# Step 4: Normalize intensity
normalized = cv2.normalize(sharpened, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)

# Display results
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
axes[0, 0].imshow(image, cmap='gray')
axes[0, 0].set_title('Original')
axes[0, 1].imshow(denoised, cmap='gray')
axes[0, 1].set_title('Denoised')
axes[0, 2].imshow(enhanced, cmap='gray')
axes[0, 2].set_title('Enhanced')
axes[1, 0].imshow(high_pass, cmap='gray')
axes[1, 0].set_title('High-Pass Filter')
axes[1, 1].imshow(sharpened, cmap='gray')
axes[1, 1].set_title('Sharpened')
axes[1, 2].imshow(normalized, cmap='gray')
axes[1, 2].set_title('Normalized')

for ax in axes.flat:
    ax.axis('off')
plt.tight_layout()
plt.show()

This pipeline demonstrates how combining multiple techniques—denoising, contrast enhancement, sharpening, and normalization—changes an image. Whether it helps depends on the task; it may also amplify noise or distort useful information.

Common Applications of Computer Vision

Computer vision technology powers countless real-world applications:

Medical Imaging

Computer vision assists in diagnosis and treatment planning. Algorithms detect tumors, segment organs, measure anatomical structures, and register images across time or modalities (CTComputed Tomography, MRIMagnetic Resonance Imaging, ultrasound). Performance depends on the specific task, data and clinical validation; success on a benchmark does not establish safe use in a clinical workflow.

Autonomous Driving

Self-driving vehicles rely on multiple cameras and sophisticated vision algorithms. Tasks include lane detection, vehicle and pedestrian detection, traffic sign recognition, and 3D scene understanding from monocular or stereo cameras. Real-time performance is critical—decisions must be made in milliseconds.

Quality Control and Inspection

Manufacturing facilities use vision systems for automated quality inspection. Cameras detect defects, measure dimensions, verify component assembly, and identify damaged products at production speeds—faster and more consistently than human inspectors.

Robotics and Manipulation

Robots use vision for navigation, obstacle avoidance, object grasping, and hand-eye coordination. Industrial robots identify parts, calculate grasp poses, and verify task completion using sophisticated vision systems.

Surveillance and Security

Security systems analyze video feeds for intrusion detection, crowd monitoring, anomaly detection, and forensic investigation. Modern systems use deep learning for person tracking, behavior analysis, and event detection.

Face Recognition and Biometrics

Face detection and recognition unlock phones, control access to buildings, identify individuals in photos, and power law enforcement applications. Similar techniques work for iris recognition, fingerprint analysis, and gait recognition.

Remote Sensing and GIS

Satellite and aerial imagery analysis supports agriculture (crop monitoring, yield prediction), urban planning, environmental monitoring, disaster response, and climate change analysis.

Conclusion

Computer vision transforms raw pixels into actionable insights and intelligent decisions. Understanding the foundational techniques—geometric transformations, histogram processing, spatial filtering, and frequency domain analysis—provides the conceptual foundation for more advanced methods like deep learning.

Modern computer vision increasingly relies on deep neural networks that automatically learn visual features from data. However, the classical techniques discussed here remain important: they’re computationally efficient, interpretable, and foundational to understanding how modern methods work.

Whether you’re processing medical images, building autonomous systems, or developing creative visual applications, the principles and code examples in this article provide a practical starting point for your computer vision journey.

References

  • OpenCV Documentation: https://docs.opencv.org/docs.opencv.orgOpenCV documentation: tutorials and the API reference for each release of the library. - Comprehensive reference for the OpenCV library with tutorials and APIApplication Programming Interface documentation.

  • Gonzalez, R. C., & Woods, R. E. (2018). Digital Image Processing (4th ed.). Pearson. - The definitive textbook on digital image processing, covering both spatial and frequency domain techniques with rigorous mathematical foundations.

  • Stanford CS231n: Convolutional Neural Networks for Visual Recognition: https://cs231n.stanford.edu/cs231n.stanford.eduStanford's CS231n course, Deep Learning for Computer Vision, with lecture notes and assignments. - Excellent course covering image classification, feature extraction, and the connection between classical image processing and modern deep learning.

  • Bradski, G., & Kaehler, A. (2008). Learning OpenCV: Computer Vision with the OpenCV Library. O’Reilly Media. - Practical guide to OpenCV with real-world examples and applications.

  • Forsyth, D. A., & Ponce, J. (2003). Computer Vision: A Modern Approach. Pearson. - Comprehensive textbook covering geometry, features, recognition, and 3D vision.