Image segmentation partitions digital raster data into homogeneous regions to facilitate feature extraction and object isolation. Two widely adopted strategies utilize statistical threshold optimization and unsupervised vector clustering.
Inter-Class Variance Maximization (Otsu Algorithm)
This approach determines an optimal binary split point by maximizing the between-class variance across all possible intensity levels. The algorithm computes background and foreground weights alongside their respective means for every candidate threshold, selecting the value that yields the highest dispersion metric.
import numpy as np
import cv2
import matplotlib.pyplot as plt
def compute_otsu_threshold(image_path):
raw_frame = cv2.imread(image_path)
# Apply standard luminance conversion formula
gray_channel = (0.2126 * raw_frame[:, :, 2] + 0.7152 * raw_frame[:, :, 1] + 0.0722 * raw_frame[:, :, 0]).astype(np.uint8)
pixel_counts, _ = np.histogram(gray_channel.flatten(), bins=256, range=(0, 256))
total_samples = gray_channel.size
sum_intensity = np.sum(gray_channel * pixel_counts)
best_split = 0
peak_variance = 0.0
for t in range(1, 255):
w_low = np.sum(pixel_counts[:t])
w_high = total_samples - w_low
if w_low == 0 or w_high == 0:
continue
m_low = np.sum((np.arange(t) * pixel_counts[:t])) / w_low
m_high = (sum_intensity - np.sum((np.arange(t) * pixel_counts[:t]))) / w_high
current_var = w_low * w_high * (m_low - m_high) ** 2
if current_var > peak_variance:
peak_variance = current_var
best_split = t
binary_mask = (gray_channel >= best_split).astype(np.uint8) * 255
return binary_mask, best_split
result_mask, opt_thresh = compute_otsu_threshold("segmentation_input.png")
print(f"Calculated threshold: {opt_thresh}")
plt.figure(figsize=(6, 3))
plt.subplot(1, 2, 1)
plt.imshow(result_mask, cmap="gray")
plt.title(f"Optimized Binary Mask (Threshold={opt_thresh})")
plt.axis('off')
plt.tight_layout()
plt.show()
Chromatic Vector Partitioning (K-Means Approach)
Unsupervised spatial grouping operates by treating RGB coordinates as points in a three-dimensional Euclidean space. The procedure initializes random centroids, assigns each pixel to its nearest neighbor based on squared Euclidean distance, and iteratively recomputes centroid positions as the arithmetic mean of assigned pixels until convergence is achieved.
import numpy as np
import cv2
def execute_color_clustering(img_path, cluster_count=5, iteration_limit=100):
source = cv2.imread(img_path)
flattened = source.reshape(-1, 3).astype(np.float32)
# Initialize cluster centers via random sampling
seed_indices = np.random.choice(flattened.shape[0], cluster_count, replace=False)
current_centers = flattened[seed_indices].copy()
membership = np.zeros(flattened.shape[0], dtype=np.int32)
for step in range(iteration_limit):
# Calculate distances from each point to all centers
dist_matrix = np.linalg.norm(flattened[:, np.newaxis] - current_centers[np.newaxis, :], axis=2)
next_assignments = np.argmin(dist_matrix, axis=1)
if np.array_equal(next_assignments, membership):
break
membership = next_assignments
# Update centers based on newly assigned members
for c_id in range(cluster_count):
active_mask = membership == c_id
if np.any(active_mask):
current_centers[c_id] = np.mean(flattened[active_mask], axis=0)
reconstructed_image = current_centers[membership].reshape(source.shape).astype(np.uint8)
return reconstructed_image, membership
distorted_output, label_map = execute_color_clustering("image_source.png", cluster_count=4, iteration_limit=150)
plt.imshow(cv2.cvtColor(distorted_output, cv2.COLOR_BGR2RGB))
plt.title("Cluster-Based Color Partitioning")
plt.axis('off')
plt.show()
Both methodologies provide scalable pathways for extracting structural boundaries from unprocessed visual inputs. Histogram-driven splitting excels in high-contrast monochrome distributions, while coordinate-space clustering adapts dynamical to multi-channel chromatic variations.