Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -5,6 +5,9 @@ import gradio as gr
|
|
| 5 |
|
| 6 |
|
| 7 |
def detect_baseline_and_solvent_front(image):
|
|
|
|
|
|
|
|
|
|
| 8 |
try:
|
| 9 |
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
| 10 |
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
|
|
@@ -15,11 +18,14 @@ def detect_baseline_and_solvent_front(image):
|
|
| 15 |
solvent_front_y = None
|
| 16 |
|
| 17 |
for i, value in enumerate(row_sums):
|
| 18 |
-
if value > 50:
|
| 19 |
if baseline_y is None:
|
| 20 |
baseline_y = i
|
| 21 |
solvent_front_y = i
|
| 22 |
|
|
|
|
|
|
|
|
|
|
| 23 |
return baseline_y, solvent_front_y
|
| 24 |
except Exception as e:
|
| 25 |
print(f"Error in detecting baseline and solvent front: {e}")
|
|
@@ -27,6 +33,9 @@ def detect_baseline_and_solvent_front(image):
|
|
| 27 |
|
| 28 |
|
| 29 |
def detect_spots(image):
|
|
|
|
|
|
|
|
|
|
| 30 |
try:
|
| 31 |
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
| 32 |
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
|
|
@@ -36,7 +45,7 @@ def detect_spots(image):
|
|
| 36 |
spots = []
|
| 37 |
for contour in contours:
|
| 38 |
x, y, w, h = cv2.boundingRect(contour)
|
| 39 |
-
if w > 5 and h > 5:
|
| 40 |
spots.append((x, y, w, h))
|
| 41 |
return spots
|
| 42 |
except Exception as e:
|
|
@@ -45,24 +54,42 @@ def detect_spots(image):
|
|
| 45 |
|
| 46 |
|
| 47 |
def calculate_rf(spots, solvent_front_y, baseline_y):
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
|
| 56 |
|
| 57 |
def annotate_image(image, spots, rf_values):
|
|
|
|
|
|
|
|
|
|
| 58 |
try:
|
| 59 |
annotated_image = image.copy()
|
| 60 |
for (x, y, w, h), rf in zip(spots, rf_values):
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
cv2.putText(
|
| 62 |
annotated_image, f"Rf={rf:.2f}", (x, y - 10),
|
| 63 |
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1
|
| 64 |
)
|
|
|
|
| 65 |
cv2.rectangle(annotated_image, (x, y), (x + w, y + h), (0, 255, 0), 2)
|
|
|
|
|
|
|
|
|
|
| 66 |
return annotated_image
|
| 67 |
except Exception as e:
|
| 68 |
print(f"Error in annotate_image: {e}")
|
|
@@ -70,24 +97,32 @@ def annotate_image(image, spots, rf_values):
|
|
| 70 |
|
| 71 |
|
| 72 |
def process_tlc(image):
|
|
|
|
|
|
|
|
|
|
| 73 |
try:
|
| 74 |
if image is None or not isinstance(image, np.ndarray):
|
| 75 |
return "Error: Invalid image uploaded. Please try again with a valid image.", None
|
| 76 |
|
|
|
|
| 77 |
baseline_y, solvent_front_y = detect_baseline_and_solvent_front(image)
|
| 78 |
if baseline_y is None or solvent_front_y is None:
|
| 79 |
return "Error: Unable to detect baseline or solvent front.", None
|
| 80 |
|
|
|
|
| 81 |
spots = detect_spots(image)
|
| 82 |
if not spots:
|
| 83 |
return "Error: No spots detected on the TLC plate.", None
|
| 84 |
|
|
|
|
| 85 |
rf_values = calculate_rf(spots, solvent_front_y, baseline_y)
|
| 86 |
-
annotated_image = annotate_image(image, spots, rf_values)
|
| 87 |
|
|
|
|
|
|
|
| 88 |
if annotated_image is None:
|
| 89 |
return "Error: Could not annotate the TLC plate image.", None
|
| 90 |
|
|
|
|
| 91 |
report_data = {"Spot": list(range(1, len(spots) + 1)), "Rf Value": rf_values}
|
| 92 |
report = pd.DataFrame(report_data).to_csv(index=False)
|
| 93 |
|
|
@@ -97,6 +132,7 @@ def process_tlc(image):
|
|
| 97 |
return "Error: Processing failed. Check inputs and try again.", None
|
| 98 |
|
| 99 |
|
|
|
|
| 100 |
interface = gr.Interface(
|
| 101 |
fn=process_tlc,
|
| 102 |
inputs=gr.Image(type="numpy", label="Upload TLC Plate Image"),
|
|
@@ -105,7 +141,8 @@ interface = gr.Interface(
|
|
| 105 |
gr.File(label="Download Rf Report (CSV)"),
|
| 106 |
],
|
| 107 |
title="TLC Analyzer",
|
| 108 |
-
description="Upload a TLC plate image to automatically calculate Rf values.
|
|
|
|
| 109 |
)
|
| 110 |
|
| 111 |
if __name__ == "__main__":
|
|
|
|
| 5 |
|
| 6 |
|
| 7 |
def detect_baseline_and_solvent_front(image):
|
| 8 |
+
"""
|
| 9 |
+
Detect the baseline and solvent front in the TLC plate image.
|
| 10 |
+
"""
|
| 11 |
try:
|
| 12 |
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
| 13 |
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
|
|
|
|
| 18 |
solvent_front_y = None
|
| 19 |
|
| 20 |
for i, value in enumerate(row_sums):
|
| 21 |
+
if value > 50: # Threshold for significant edge detection
|
| 22 |
if baseline_y is None:
|
| 23 |
baseline_y = i
|
| 24 |
solvent_front_y = i
|
| 25 |
|
| 26 |
+
if baseline_y is None or solvent_front_y is None:
|
| 27 |
+
raise ValueError("Could not detect baseline or solvent front.")
|
| 28 |
+
|
| 29 |
return baseline_y, solvent_front_y
|
| 30 |
except Exception as e:
|
| 31 |
print(f"Error in detecting baseline and solvent front: {e}")
|
|
|
|
| 33 |
|
| 34 |
|
| 35 |
def detect_spots(image):
|
| 36 |
+
"""
|
| 37 |
+
Detect spots on the TLC plate.
|
| 38 |
+
"""
|
| 39 |
try:
|
| 40 |
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
| 41 |
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
|
|
|
|
| 45 |
spots = []
|
| 46 |
for contour in contours:
|
| 47 |
x, y, w, h = cv2.boundingRect(contour)
|
| 48 |
+
if w > 5 and h > 5: # Filter small noise
|
| 49 |
spots.append((x, y, w, h))
|
| 50 |
return spots
|
| 51 |
except Exception as e:
|
|
|
|
| 54 |
|
| 55 |
|
| 56 |
def calculate_rf(spots, solvent_front_y, baseline_y):
|
| 57 |
+
"""
|
| 58 |
+
Calculate the Rf values for detected spots.
|
| 59 |
+
"""
|
| 60 |
+
try:
|
| 61 |
+
rf_values = []
|
| 62 |
+
for _, y, _, _ in spots:
|
| 63 |
+
distance_compound = y - baseline_y
|
| 64 |
+
distance_solvent = solvent_front_y - baseline_y
|
| 65 |
+
rf = distance_compound / distance_solvent if distance_solvent > 0 else 0
|
| 66 |
+
rf_values.append(round(rf, 2))
|
| 67 |
+
return rf_values
|
| 68 |
+
except Exception as e:
|
| 69 |
+
print(f"Error in calculate_rf: {e}")
|
| 70 |
+
return []
|
| 71 |
|
| 72 |
|
| 73 |
def annotate_image(image, spots, rf_values):
|
| 74 |
+
"""
|
| 75 |
+
Annotate the image with detected spots and their Rf values.
|
| 76 |
+
"""
|
| 77 |
try:
|
| 78 |
annotated_image = image.copy()
|
| 79 |
for (x, y, w, h), rf in zip(spots, rf_values):
|
| 80 |
+
if x < 0 or y < 0 or x + w > image.shape[1] or y + h > image.shape[0]:
|
| 81 |
+
continue # Skip invalid spots
|
| 82 |
+
|
| 83 |
+
# Annotate with Rf value
|
| 84 |
cv2.putText(
|
| 85 |
annotated_image, f"Rf={rf:.2f}", (x, y - 10),
|
| 86 |
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1
|
| 87 |
)
|
| 88 |
+
# Draw rectangle around the spot
|
| 89 |
cv2.rectangle(annotated_image, (x, y), (x + w, y + h), (0, 255, 0), 2)
|
| 90 |
+
|
| 91 |
+
# Convert to RGB for Gradio compatibility
|
| 92 |
+
annotated_image = cv2.cvtColor(annotated_image, cv2.COLOR_BGR2RGB)
|
| 93 |
return annotated_image
|
| 94 |
except Exception as e:
|
| 95 |
print(f"Error in annotate_image: {e}")
|
|
|
|
| 97 |
|
| 98 |
|
| 99 |
def process_tlc(image):
|
| 100 |
+
"""
|
| 101 |
+
Process the TLC plate image and calculate Rf values.
|
| 102 |
+
"""
|
| 103 |
try:
|
| 104 |
if image is None or not isinstance(image, np.ndarray):
|
| 105 |
return "Error: Invalid image uploaded. Please try again with a valid image.", None
|
| 106 |
|
| 107 |
+
# Detect baseline and solvent front
|
| 108 |
baseline_y, solvent_front_y = detect_baseline_and_solvent_front(image)
|
| 109 |
if baseline_y is None or solvent_front_y is None:
|
| 110 |
return "Error: Unable to detect baseline or solvent front.", None
|
| 111 |
|
| 112 |
+
# Detect spots on the TLC plate
|
| 113 |
spots = detect_spots(image)
|
| 114 |
if not spots:
|
| 115 |
return "Error: No spots detected on the TLC plate.", None
|
| 116 |
|
| 117 |
+
# Calculate Rf values
|
| 118 |
rf_values = calculate_rf(spots, solvent_front_y, baseline_y)
|
|
|
|
| 119 |
|
| 120 |
+
# Annotate the image with detected spots and Rf values
|
| 121 |
+
annotated_image = annotate_image(image, spots, rf_values)
|
| 122 |
if annotated_image is None:
|
| 123 |
return "Error: Could not annotate the TLC plate image.", None
|
| 124 |
|
| 125 |
+
# Generate a CSV report of Rf values
|
| 126 |
report_data = {"Spot": list(range(1, len(spots) + 1)), "Rf Value": rf_values}
|
| 127 |
report = pd.DataFrame(report_data).to_csv(index=False)
|
| 128 |
|
|
|
|
| 132 |
return "Error: Processing failed. Check inputs and try again.", None
|
| 133 |
|
| 134 |
|
| 135 |
+
# Define Gradio Interface
|
| 136 |
interface = gr.Interface(
|
| 137 |
fn=process_tlc,
|
| 138 |
inputs=gr.Image(type="numpy", label="Upload TLC Plate Image"),
|
|
|
|
| 141 |
gr.File(label="Download Rf Report (CSV)"),
|
| 142 |
],
|
| 143 |
title="TLC Analyzer",
|
| 144 |
+
description="Upload a TLC plate image to automatically calculate Rf values. "
|
| 145 |
+
"The application detects the solvent front and baseline automatically.",
|
| 146 |
)
|
| 147 |
|
| 148 |
if __name__ == "__main__":
|