File size: 2,966 Bytes
8312ddd d28c822 3cf3c0d 67b1d32 b5ba092 67b1d32 b5ba092 67b1d32 b5ba092 67b1d32 b5ba092 67b1d32 b5ba092 67b1d32 b5ba092 67b1d32 b5ba092 67b1d32 b5ba092 67b1d32 b5ba092 67b1d32 cfb7ff1 67b1d32 8f2167b 67b1d32 8f2167b 67b1d32 d28c822 67b1d32 d28c822 67b1d32 8312ddd 67b1d32 8312ddd 67b1d32 8312ddd 67b1d32 8312ddd 67b1d32 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
import cv2
import numpy as np
import pandas as pd
import gradio as gr
import matplotlib.pyplot as plt
from datetime import datetime
def preprocess_image(image):
"""Convert image to HSV and apply adaptive thresholding for better detection."""
if len(image.shape) == 2:
image = cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)
hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV)
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
# Adaptive thresholding for better contrast
adaptive_thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
# Morphological operations to remove noise
kernel = np.ones((3,3), np.uint8)
clean_mask = cv2.morphologyEx(adaptive_thresh, cv2.MORPH_CLOSE, kernel, iterations=2)
clean_mask = cv2.morphologyEx(clean_mask, cv2.MORPH_OPEN, kernel, iterations=2)
return clean_mask
def detect_blood_cells(image):
"""Detect blood cells using contour analysis with refined filtering."""
mask = preprocess_image(image)
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
features = []
for i, contour in enumerate(contours, 1):
area = cv2.contourArea(contour)
perimeter = cv2.arcLength(contour, True)
circularity = 4 * np.pi * area / (perimeter * perimeter) if perimeter > 0 else 0
if 100 < area < 5000 and circularity > 0.7:
M = cv2.moments(contour)
if M["m00"] != 0:
cx = int(M["m10"] / M["m00"])
cy = int(M["m01"] / M["m00"])
features.append({'label': i, 'area': area, 'perimeter': perimeter, 'circularity': circularity, 'centroid_x': cx, 'centroid_y': cy})
return contours, features, mask
def process_image(image):
if image is None:
return None, None, None, None
contours, features, mask = detect_blood_cells(image)
vis_img = image.copy()
for feature in features:
contour = contours[feature['label'] - 1]
cv2.drawContours(vis_img, [contour], -1, (0, 255, 0), 2)
cv2.putText(vis_img, str(feature['label']), (feature['centroid_x'], feature['centroid_y']), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
df = pd.DataFrame(features)
return vis_img, mask, df
def analyze(image):
vis_img, mask, df = process_image(image)
plt.style.use('dark_background')
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
if not df.empty:
axes[0].hist(df['area'], bins=20, color='cyan', edgecolor='black')
axes[0].set_title('Cell Size Distribution')
axes[1].scatter(df['area'], df['circularity'], alpha=0.6, c='magenta')
axes[1].set_title('Area vs Circularity')
return vis_img, mask, fig, df
# Gradio Interface
demo = gr.Interface(fn=analyze, inputs=gr.Image(type="numpy"), outputs=[gr.Image(), gr.Image(), gr.Plot(), gr.Dataframe()])
demo.launch() |