Created
December 10, 2023 22:10
-
-
Save cheadrian/365ca2ae4997cec28790ab88a042b9d5 to your computer and use it in GitHub Desktop.
Adaptive Threshold, Sobel, Morph Close comparison with Matplotlib sliders
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
import cv2 as cv | |
import matplotlib.pyplot as plt | |
from matplotlib.widgets import Slider | |
def sobel_edge_detector(img, threshold=50): | |
grad_x = cv.Sobel(img, cv.CV_64F, 1, 0) | |
grad_y = cv.Sobel(img, cv.CV_64F, 0, 1) | |
grad = np.sqrt(grad_x**2 + grad_y**2) | |
grad_norm = (grad * 255 / grad.max()).astype(np.uint8) | |
_, binary_edge = cv.threshold(grad_norm, threshold, 255, cv.THRESH_BINARY) | |
return binary_edge | |
def update(val): | |
# Get current slider values | |
block_size = int(block_size_slider.val) | |
C = int(C_slider.val) | |
blur_size = int(blur_size_slider.val) | |
closing_size = int(closing_size_slider.val) | |
sobel_threshold = int(sobel_threshold_slider.val) | |
# Apply Sobel edge detection | |
sobel_edges = sobel_edge_detector(gray, sobel_threshold) | |
# Apply blur | |
blurred_image = cv.GaussianBlur(gray, (blur_size, blur_size), 0) | |
# Apply adaptive thresholding | |
adaptive_threshold = cv.adaptiveThreshold( | |
blurred_image, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV, block_size, C | |
) | |
# Apply morphological closing to close contours | |
kernel = np.ones((closing_size, closing_size), np.uint8) | |
closed_contours = cv.morphologyEx(adaptive_threshold, cv.MORPH_CLOSE, kernel) | |
# Update the displayed images | |
ax2.imshow(closed_contours, cmap='gray') | |
ax2.set_title('Adaptive Thresholded with Blur and Closed Contours') | |
ax3.imshow(sobel_edges, cmap='gray') | |
ax3.set_title('Sobel Edge Detection') | |
fig.canvas.draw_idle() | |
# Load the image | |
img = cv.imread('capture.png') | |
assert img is not None, "file could not be read, check with os.path.exists()" | |
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY) | |
# Create figure and axes | |
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(18, 5)) | |
fig.subplots_adjust(left=0.1, right=0.9, bottom=0.45) | |
# Display the original image | |
ax1.imshow(gray, cmap='gray') | |
ax1.set_title('Original Image') | |
# Initial values for adaptive threshold parameters | |
initial_block_size = 3 | |
initial_C = 3 | |
initial_blur_size = 3 | |
initial_closing_size = 3 | |
initial_sobel_threshold = 50 | |
# Create sliders | |
axcolor = 'lightgoldenrodyellow' | |
ax_block_size = plt.axes([0.1, 0.35, 0.65, 0.03], facecolor=axcolor) | |
ax_C = plt.axes([0.1, 0.3, 0.65, 0.03], facecolor=axcolor) | |
ax_blur_size = plt.axes([0.1, 0.25, 0.65, 0.03], facecolor=axcolor) | |
ax_closing_size = plt.axes([0.1, 0.2, 0.65, 0.03], facecolor=axcolor) | |
ax_sobel_threshold = plt.axes([0.1, 0.15, 0.65, 0.03], facecolor=axcolor) | |
block_size_slider = Slider(ax_block_size, 'Block Size', 3, 31, valinit=initial_block_size, valstep=2) | |
C_slider = Slider(ax_C, 'C', -10, 20, valinit=initial_C, valstep=1) | |
blur_size_slider = Slider(ax_blur_size, 'Blur Size', 1, 21, valinit=initial_blur_size, valstep=2) | |
closing_size_slider = Slider(ax_closing_size, 'Closing Size', 1, 21, valinit=initial_closing_size, valstep=2) | |
sobel_threshold_slider = Slider(ax_sobel_threshold, 'Sobel Threshold', 0, 255, valinit=initial_sobel_threshold, valstep=1) | |
# Register the update function with the sliders | |
block_size_slider.on_changed(update) | |
C_slider.on_changed(update) | |
blur_size_slider.on_changed(update) | |
closing_size_slider.on_changed(update) | |
sobel_threshold_slider.on_changed(update) | |
# Initial blur and adaptive thresholding | |
blurred_image = cv.GaussianBlur(gray, (initial_blur_size, initial_blur_size), 0) | |
adaptive_threshold = cv.adaptiveThreshold( | |
blurred_image, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV, initial_block_size, initial_C | |
) | |
# Initial morphological closing to close contours | |
kernel = np.ones((initial_closing_size, initial_closing_size), np.uint8) | |
closed_contours = cv.morphologyEx(adaptive_threshold, cv.MORPH_CLOSE, kernel) | |
# Initial Sobel edge detection | |
sobel_edges = sobel_edge_detector(gray, initial_sobel_threshold) | |
# Display the adaptive thresholded image with closed contours | |
ax2.imshow(closed_contours, cmap='gray') | |
ax2.set_title('Adaptive Thresholded with Blur and Closed Contours') | |
# Display the Sobel edge detection | |
ax3.imshow(sobel_edges, cmap='gray') | |
ax3.set_title('Sobel Edge Detection') | |
plt.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment