I once worked with a jewelry retailer sitting on more than 50,000 high-res product photos. They wanted an automated “smart crop” that framed the most detailed part of a ring or a necklace. The previous developer had built it on a basic edge detection script, and every tiny reflection on a diamond came back flagged as an “important edge,” so the crops landed all over the place. I rebuilt it around Harris Corner Detection to find the structural points instead.
Basic gradients, including the ones from earlier parts of this series, are too sensitive to noise. Anyone who has had to manage high-resolution image libraries knows how much trouble noise causes. My first idea was to crank up the Sobel threshold and hope for the best, which gave me an edge for every speck of dust while still missing the corners that defined the product’s shape.
Why Harris corner detection beats standard edges
A corner carries more information than an edge. In a jigsaw puzzle an edge piece narrows things down, while a corner piece tells you exactly where you are. Harris Corner Detection looks for regions where the image intensity changes sharply in every direction. Change in one direction only is an edge, no change at all is a flat region, and change along both X and Y at once is a corner.
A formula gives each region an “R” score, which sorts it into one of three cases:
- R > 0 means a corner.
- R ~ 0 means a flat region, which is boring.
- R < 0 means an edge.
On a production pipeline, say building a real image optimization CDN, CPU cost matters. Harris dates to 1988 and it is still cheap to run, because there is no machine learning model behind it. It is arithmetic on the eigenvalues of the second-moment matrix, and it runs faster than most people expect.
Implementing Harris corner detection with OpenCV
In Python with OpenCV the implementation is short. The one thing to watch is that Harris Corner Detection wants the input in grayscale and in float32. Skip the float conversion and the output is garbage.
import cv2
import numpy as np
def bbioon_detect_corners(image_path):
# Load the image
img = cv2.imread(image_path)
# Harris works with intensities, so grayscale is a must
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Crucial step: convert to float32
gray = np.float32(gray)
# The actual Harris Corner Detection function
# blockSize: Neighborhood size
# ksize: Aperture parameter for Sobel operator
# k: Harris detector free parameter
dst = cv2.cornerHarris(gray, 2, 3, 0.04)
# Result is dilated for marking the corners, not strictly necessary
dst = cv2.dilate(dst, None)
# Threshold for an optimal value, it may vary depending on the image
img[dst > 0.01 * dst.max()] = [0, 0, 255]
return img
cv2.cornerHarris does the actual work, and the OpenCV documentation covers its parameters in detail. For the theory, the Wikipedia page summarizes the original 1988 paper, and there is another take on the math in this post on Towards Data Science.
When to reach for it
If you need to identify structural landmarks in an image, basic edge detection is the wrong tool. Harris Corner Detection handles something like 90% of the computer vision tasks that do not call for a full neural network, and it stays fast and interpretable while it does.
This gets complicated fast. If you are tired of debugging someone else’s mess and you just want your site to work, send me a note. Odds are I have seen it before.
Need help with a custom image processing pipeline or some messy WooCommerce logic? Let’s talk.