Spaces:
Build error
Build error
| import numpy as np | |
| import cv2 | |
| import matplotlib.pyplot as plt | |
| from PIL import Image | |
| import io | |
| def otsu_threshold(image): | |
| hist, bin_edges = np.histogram(image.flatten(), bins=256, range=[0, 256]) | |
| hist = hist.astype(float) | |
| total_pixels = image.size | |
| pixel_probability = hist / total_pixels | |
| max_variance = 0 | |
| optimal_threshold = 0 | |
| for threshold in range(1, 256): | |
| weight_background = np.sum(pixel_probability[:threshold]) | |
| weight_foreground = np.sum(pixel_probability[threshold:]) | |
| if weight_background == 0 or weight_foreground == 0: | |
| continue | |
| mean_background = np.sum(np.arange(threshold) * pixel_probability[:threshold]) / weight_background | |
| mean_foreground = np.sum(np.arange(threshold, 256) * pixel_probability[threshold:]) / weight_foreground | |
| variance = weight_background * weight_foreground * (mean_background - mean_foreground) ** 2 | |
| if variance > max_variance: | |
| max_variance = variance | |
| optimal_threshold = threshold | |
| segmented_image = np.zeros_like(image) | |
| segmented_image[image >= optimal_threshold] = 255 | |
| return optimal_threshold, segmented_image | |
| def generate_segmented_image(image_path): | |
| # Convert PIL to OpenCV format | |
| print(f"Image path: {image_path}") | |
| image = Image.open(image_path) | |
| image_np = np.array(image) | |
| original_image = cv2.cvtColor(image_np, cv2.COLOR_RGB2BGR) | |
| if len(original_image.shape) == 3: | |
| gray_image = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY) | |
| else: | |
| gray_image = original_image.copy() | |
| blurred = cv2.GaussianBlur(gray_image, (5, 5), 0) | |
| # Our implementation | |
| our_threshold, our_segmented = otsu_threshold(blurred) | |
| # OpenCV's implementation | |
| opencv_threshold, opencv_segmented = cv2.threshold( | |
| blurred, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU | |
| ) | |
| # Create histogram figure | |
| fig, ax = plt.subplots(figsize=(6, 4)) | |
| ax.hist(gray_image.ravel(), 256, [0, 256], color='gray') | |
| ax.axvline(x=our_threshold, color='red', linestyle='--', label=f'Ours: {our_threshold}') | |
| ax.axvline(x=opencv_threshold, color='green', linestyle='--', label=f'OpenCV: {opencv_threshold}') | |
| ax.set_title("Histogram with Thresholds") | |
| ax.legend() | |
| # Convert Matplotlib figure to image | |
| buf = io.BytesIO() | |
| plt.savefig(buf, format='png') | |
| buf.seek(0) | |
| hist_image = Image.open(buf) | |
| plt.close(fig) # Close the figure to free memory | |
| return ( | |
| image, | |
| Image.fromarray(our_segmented), | |
| Image.fromarray(opencv_segmented), | |
| hist_image, | |
| f"Our Threshold: {our_threshold}\nOpenCV Threshold: {opencv_threshold}", | |
| ) | |
| if __name__ == "__main__": | |
| #example usage | |
| # Ensure you have the image path set correctly | |
| image_path = '/home/akshat/projects/CSL7360_Project/bird.jpeg' | |
| image = cv2.imread('/home/akshat/projects/CSL7360_Project/bird.jpeg') | |
| # Call the function | |
| generate_segmented_image(image) | |
| # # Optionally, save results to files | |
| # cv2.imwrite("our_segmented.png", our_segmented) | |
| # cv2.imwrite("opencv_segmented.png", opencv_segmented) | |