ReleaseInsight · On RadarHabr AI→ original

Convolution in Pure PHP: Four Loops Find Edges in an Image

Convolutional networks seem like a black box until you write a convolution by hand. The author of part eight of the series for PHP developers takes a 5×5 image, a 3×3 kernel and four nested loops. The filter slides across the pixels, multiplies values by weights and sums them up: a dark area yields 0, while the edge yields 570.

AI-processed from Habr AI; edited by Hamidun News
Convolution in Pure PHP: Four Loops Find Edges in an Image
Source: Habr AI. Collage: Hamidun News.
Listen to article
Article Fact Sheet & Key Figures
ParameterDetails
Primary sourceHabr AI ↗
Editor-in-Chief
Convolution in a CNNfour loops, multiplication and a sum
Key metric #2A kernel with weights -1, 0, 1 responds to a vertical edge
Key metric #3One edge produces two responses because of the window size

Most developers have heard of convolutional neural networks, but few understand what happens inside the layer. Part eight of the series "AI for PHP Developers" clears away that fog: the author implements convolution in pure PHP 8.1+, with no libraries or ready-made ML algorithms.

How a Computer Sees an Image

For a machine, an image is a matrix of numbers. In grayscale, each pixel takes a value from 0 (black) to 255 (white). The example uses a 5×5 image: the three left columns have the value 10 and the two right columns have the value 200. A vertical edge runs between the third and fourth columns, and that is what needs to be found.

For this, a convolution kernel is used, a small 3×3 matrix of weights. The left column holds -1, the center 0, the right 1. The kernel compares the brightness of the left and right parts of a patch: if they are similar, the terms cancel each other out; if they differ, the result is large in absolute value.

How It Works in Code

The convolve() function takes an input matrix and a kernel. The size of the result is simple to compute: input width minus kernel width plus one, and the same for height. For 5×5 and 3×3, this gives a 3×3 feature map. The two outer loops move the window across the image, and the two inner loops multiply pixels by weights and accumulate the sum.

In this implementation, stride is 1, padding is 0, and the kernel is not flipped. Strictly speaking, this is cross-correlation rather than mathematical convolution, but in deep learning it is conventionally called convolution. The result values are not clipped to the 0–255 range: a feature map can contain negative numbers and values above 255.

The output is a matrix whose first column consists of zeros, while the other two equal 570. For a uniform dark region, the filter sees no change, and the result is zero. When the window covers both dark and light pixels, each row yields 190, and the three rows sum to 570.

Why Two Responses for One Edge

Two values of 570 do not mean two edges. A window 3 pixels wide, shifted by one, captures the dark-to-light transition twice, so the response persists in two adjacent positions. This is normal kernel behavior, not a bug.

Later in the article, the author changes the weights and searches for horizontal edges, showing that changing the filter changes what the layer responds to.

What to Do With This

The practical takeaway is modest but honest. This code is not suitable for production: four nested loops in PHP will be slow on real images, and serious work requires optimized libraries or calls to external models. However, if you work with computer vision through APIs or extensions, understanding convolution helps you read documentation, debug unexpected results and understand what exactly the network learns: in a CNN, kernel weights are not set by hand but are tuned during training.

The article is useful as learning material for PHP teams who want to understand the basis of CNNs without switching to Python.

Story

Key Questions Answered

How a Computer Sees an Image?

For a machine, an image is a matrix of numbers. In grayscale, each pixel takes a value from 0 (black) to 255 (white). The example uses a 5×5 image: the three left columns have the value 10 and the two right columns have the value 200. A vertical edge runs between the third and fourth columns, and that is what needs to be found. For this, a convolution kernel is used, a small 3×3 matrix of weights. The left column holds -1, the center 0, the right 1.

How It Works in Code?

The convolve() function takes an input matrix and a kernel. The size of the result is simple to compute: input width minus kernel width plus one, and the same for height. For 5×5 and 3×3, this gives a 3×3 feature map. The two outer loops move the window across the image, and the two inner loops multiply pixels by weights and accumulate the sum. In this implementation, stride is 1, padding is 0, and the kernel is not flipped.

Why Two Responses for One Edge?

Two values of 570 do not mean two edges. A window 3 pixels wide, shifted by one, captures the dark-to-light transition twice, so the response persists in two adjacent positions. This is normal kernel behavior, not a bug. Later in the article, the author changes the weights and searches for horizontal edges, showing that changing the filter changes what the layer responds to.

ZK
Zhemal Khamidun — CPO at Alpina Digital, product manager of AlpinaGPT. Building AI products since 2019. Hamidun News is a pet project that grew into a production aggregator with 6,000+ readers.
✦ Unified AI Workspace · Nomad

Test Frontier LLMs & Autonomous Agents in One Workspace

Run Claude Opus 5.5, GPT-6, Gemini 3.1, and DeepSeek side-by-side in Nomad AI (nomadnet.ai) — unified model routing, deep research, and multimodal workflows under one subscription.

Try Nomad AI →Launch Nomad Agent
What do you think?
Loading comments…