5 Best Ways to Implement Shi-Tomasi Corner Detector in OpenCV Python

πŸ’‘ Problem Formulation: Detecting corners in images is a fundamental step in many computer vision tasks, such as object recognition, image registration, and tracking. The Shi-Tomasi corner detector is an effective technique used for this purpose. This article addresses the problem of implementing Shi-Tomasi corner detection using Python’s OpenCV library. We will explore various methods to detect corners with an example image as input and its corners highlighted as output.

Method 1: Basic Shi-Tomasi Corner Detection

In this method, we use OpenCV’s goodFeaturesToTrack function to find N strongest corners in the image as specified by the user. This function requires the input image, the number of corners we wish to detect, the quality level which is a parameter for minimal accepted quality of corner, and the minimum Euclidean distance between detected corners.

Here’s an example:

import cv2
import numpy as np

img = cv2.imread('example.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

corners = cv2.goodFeaturesToTrack(gray, 25, 0.01, 10)
corners = np.int0(corners)

for i in corners:
    x, y = i.ravel()
    cv2.circle(img, (x, y), 3, (255, 0, 0), -1)

cv2.imshow('Corners', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

The output is the supplied image with detected corners marked as red circles.

This code snippet loads an image, converts it to grayscale, and then applies the Shi-Tomasi corner detector. The detected corners are then marked on the original image with red circles. Lastly, the image is displayed to the user.

Method 2: Adjustable Parameters for Corner Detection

This method expands upon the first by adding adjustable parameters to fine-tune the corner detection process. This allows for dynamic tuning based on different image conditions such as lighting and contrast. It includes adjusting the maxCorners, qualityLevel, minDistance, and the optional blockSize parameter, which defines the size of the neighborhood considered for corner detection.

Here’s an example:

import cv2
import numpy as np

img = cv2.imread('example.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

maxCorners = 50
qualityLevel = 0.03
minDistance = 15
blockSize = 7

corners = cv2.goodFeaturesToTrack(gray, maxCorners, qualityLevel, minDistance, blockSize=blockSize)

# Process corners and display them as done in Method 1...

The output is an original image with a more refined set of detected corners, tailored to specific image characteristics.

This example demonstrates how to adjust the Shi-Tomasi detector parameters to improve the corner detection results for different images. By changing the parameters, we can balance between the number of corners detected and the precision of the detection.

Method 3: Incorporating Image Preprocessing

Before applying the Shi-Tomasi corner detector, preprocessing the input image can yield better results. This can include steps like noise reduction, contrast adjustment, or thresholding. For instance, applying Gaussian blur can help in reducing image noise which can improve the accuracy of corner detection.

Here’s an example:

import cv2
import numpy as np

img = cv2.imread('example.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)

# Now apply corner detection as done in Method 1 or 2...

The output is an image where corners are more accurately detected due to reduced noise levels.

Here, Gaussian blur is applied to the grayscale image before detecting corners. This smoothing step helps to minimize false corner detections caused by noise in the image.

Method 4: Visualizing Corners with Delaunay Triangulation

Visualizing the distribution of corners can be helpful for some applications. This method involves drawing Delaunay Triangulation among detected corners, which can give insights into the spatial relationships between corners. OpenCV provides functions to perform this such as Subdiv2D.

Here’s an example:

import cv2
import numpy as np

img = cv2.imread('example.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Detect corners using Method 1 or 2...

# Create an empty mask and draw the corners
mask = np.zeros_like(img)
corners = np.float32(corners)
for item in corners:
    cv2.circle(mask, (item[0][0], item[0][1]), 3, (255, 0, 0), -1)

# Delaunay triangulation
rect = (0, 0, img.shape[1], img.shape[0])
subdiv = cv2.Subdiv2D(rect)
for p in corners:
    subdiv.insert((p[0][0], p[0][1]))
    triangles = subdiv.getTriangleList()

# Draw the triangles on the mask.
for t in triangles:
    pts = t.reshape(-1, 2).astype(np.int32)
    cv2.polylines(mask, [pts], True, (0, 255, 0), 1, cv2.LINE_AA)

# Now we can display the image with the Delaunay Triangulation
cv2.imshow('Corners with Delaunay Triangulation', mask)
cv2.waitKey(0)
cv2.destroyAllWindows()

The output is an image with detected corners connected by green lines forming Delaunay Triangles.

After detecting corners, we draw them on a mask and perform Delaunay Triangulation to connect these points. The resulting image graphically displays the geometric relationships between corners.

Bonus One-Liner Method 5: Visualize Corners on a Single Line

For quick visualization, corners can be marked with minimalistic one-liner code that directly applies the Detector on grayscale images and draws with a fixed radius and color on the original image.

Here’s an example:

cv2.imshow('Corners', cv2.drawKeypoints(cv2.imread('example.jpg'), [cv2.KeyPoint(x, y, 1) for x, y in cv2.goodFeaturesToTrack(cv2.cvtColor(cv2.imread('example.jpg'), cv2.COLOR_BGR2GRAY), 25, 0.01, 10)[:,0]], None, (0, 0, 255)))

The output is an image with corners displayed using default settings by OpenCV’s convenience functions.

This compact code reads the image, detects corners, creates Keypoint objects, and then visualizes them directly over the read image, displaying the resulting corners in a single line of code.

Summary/Discussion

  • Method 1: Basic Shi-Tomasi Corner Detection. Straightforward implementation suitable for most cases. It may not be ideal for images with varying noise levels or corner densities.
  • Method 2: Adjustable Parameters for Corner Detection. Offers customization for more precise corner detection. Requires fine-tuning of parameters for optimal results, depending on the image.
  • Method 3: Incorporating Image Preprocessing. Enhances corner detection accuracy by reducing noise. Adds extra preprocessing steps that may increase computational load.
  • Method 4: Visualizing Corners with Delaunay Triangulation. Useful for understanding the spatial distribution of corners. Computationally intensive due to the additional step of triangulation.
  • Bonus Method 5: One-Liner Corner Visualization. Quick and easy, best for a simple direct visual of corners without need for customization or pre-processing. Less flexible and might not work well for all images.