import cv2
import numpy as np
# Load image in grayscale
img = cv2.imread('chessboard.png', cv2.IMREAD_GRAYSCALE)
# Convert to float32
img_float = np.float32(img)
# Parameters tuned for better corner detection
block_size = 3 # size of neighborhood considered for corner detection
aperture_size = 3 # aperture parameter for Sobel operator
k = 0.04 # Harris detector free parameter
# Detect Harris corners
harris_response = cv2.cornerHarris(img_float, block_size, aperture_size, k)
# Dilate corner points to enhance
harris_response = cv2.dilate(harris_response, None)
# Threshold for an optimal value, it may vary depending on the image.
threshold = 0.02 * harris_response.max()
# Create a copy of the original image to draw corners
img_corners = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
# Mark corners in red
img_corners[harris_response > threshold] = [0, 0, 255]
# Save or display the result
cv2.imwrite('chessboard_corners.png', img_corners)
# For evaluation, assume ground truth corners are known (mock example)
ground_truth_corners = [(50, 50), (100, 100), (150, 150)] # example points
detected_points = np.argwhere(harris_response > threshold)
def evaluate_corners(detected, truth, tolerance=5):
true_positives = 0
for gx, gy in truth:
for dx, dy in detected:
if abs(gx - dx) <= tolerance and abs(gy - dy) <= tolerance:
true_positives += 1
break
precision = true_positives / len(detected) if detected.size > 0 else 0
recall = true_positives / len(truth) if len(truth) > 0 else 0
false_positive_rate = 1 - precision
return precision * 100, recall * 100, false_positive_rate * 100
precision, recall, fpr = evaluate_corners(detected_points, ground_truth_corners)
print(f'Precision: {precision:.1f}%, Recall: {recall:.1f}%, False positive rate: {fpr:.1f}%')