Skip to content

Instantly share code, notes, and snippets.

@chpatrick
Last active June 23, 2025 01:04
Show Gist options
  • Save chpatrick/a6414f780a884bc2e508ff4ff5f52df6 to your computer and use it in GitHub Desktop.
Save chpatrick/a6414f780a884bc2e508ff4ff5f52df6 to your computer and use it in GitHub Desktop.
Interferogram segmentation
import cv2
import numpy as np
img = cv2.imread("data/P1273172.JPG")
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY).astype(np.float32)
ksize = 9 # Increase this to reduce noise before binarization.
point_sampling_factor = 50 # Take every nth point to speed up circle calculation.
# Compute variance around each pixel.
local_mean = cv2.blur(img, ksize=(ksize, ksize))
local_mean_of_squares = cv2.blur(img**2, ksize=(ksize, ksize))
local_variance = local_mean_of_squares - local_mean**2
# Find the high-variance region with Otsu's binarization
_threshold_val, variance_thresh = cv2.threshold(local_variance.astype(np.uint16), 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# Find the smallest enclosing circle for the binarized value
center, radius = cv2.minEnclosingCircle(cv2.findNonZero(variance_thresh)[::point_sampling_factor,0].astype(np.float32))
center_x, center_y = center
radius -= (ksize - 1) / 2 # Compensate for the blur exaggerating the size of the circle.
print(f"{center_x=}")
print(f"{center_y=}")
print(f"{radius=}")
result_viz = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
cv2.circle(result_viz, center=(int(center_x), int(center_y)), radius=int(radius), color=(0, 0, 255))
cv2.imwrite("segmented.jpg", result_viz)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment