Spaces:
Sleeping
Sleeping
File size: 4,675 Bytes
19bd8b9 |
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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
import sys
import json
import cv2
import numpy as np
from skimage import color as skimage_color
import os
class WaterQualityAnalyzer:
def __init__(self):
self.lab_calibration = {
'ph': [
((54, 81, 69), 4.0),
((63, 60, 59), 5.0),
((75, 24, 79), 6.0),
((88, -8, 86), 6.5),
((97, -15, 94), 7.0),
((91, -26, 85), 7.5),
((88, -76, 81), 8.0),
((91, -48, -14), 8.5),
((54, 57, -100), 9.0),
],
'chlorine': [
((100, 0, 0), 0.0),
((97, 5, 2), 0.5),
((91, 15, 5), 1.0),
((76, 34, 4), 2.0),
((60, 49, -4), 3.0),
((54, 69, 36), 4.0),
],
'nitrates': [
((100, 0, 0), 0),
((97, 6, 4), 5),
((92, 14, 6), 10),
((76, 33, 5), 25),
((63, 60, 58), 50),
],
'hardness': [
((100, 0, 0), 0),
((98, -3, 3), 50),
((91, -21, 20), 100),
((88, -76, 81), 150),
((54, -39, 36), 200),
((46, -51, 49), 300),
],
'alkalinity': [
((100, 0, 0), 0),
((98, -9, 0), 40),
((91, -16, -11), 80),
((91, -48, -14), 120),
((87, -42, -15), 160),
((60, -29, -29), 240),
],
'bacteria': [
((100, 0, 0), 0),
((97, -1, 12), 0.5),
((97, -15, 94), 1),
],
}
def _color_distance_lab(self, lab1, lab2):
return np.sqrt(np.sum((np.array(lab1) - np.array(lab2)) ** 2))
def analyze_parameter(self, avg_lab_color, parameter):
if parameter not in self.lab_calibration: return 0, 0
calibration_data = self.lab_calibration[parameter]
if not calibration_data: return 0, 0
distances = [(self._color_distance_lab(avg_lab_color, cal_lab), value) for cal_lab, value in calibration_data]
distances.sort()
closest_dist, best_value = distances[0]
confidence = max(0, 100 - (closest_dist * 2.5))
if len(distances) >= 2:
d1, v1 = distances[0]
d2, v2 = distances[1]
if (d1 + d2) == 0: return v1, confidence
weight1 = d2 / (d1 + d2)
weight2 = d1 / (d1 + d2)
interpolated_value = v1 * weight1 + v2 * weight2
return interpolated_value, confidence
return best_value, confidence
def analyze_water_quality(self, image_path, water_source='unknown'):
image = cv2.imread(image_path)
if image is None: raise ValueError(f"Could not load image: {image_path}")
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
height = image_rgb.shape[0]
pad_height = height // 6
regions_of_interest = [image_rgb[i * pad_height:(i + 1) * pad_height, :] for i in range(6)]
parameter_names = ['ph', 'chlorine', 'nitrates', 'hardness', 'alkalinity', 'bacteria']
results, confidences = {}, {}
for i, param in enumerate(parameter_names):
roi_rgb = regions_of_interest[i]
roi_lab = skimage_color.rgb2lab(roi_rgb)
avg_lab_color = np.mean(roi_lab.reshape(-1, 3), axis=0)
value, confidence = self.analyze_parameter(avg_lab_color, param)
results[param] = value
confidences[param] = round(confidence)
overall_confidence = round(np.mean(list(confidences.values())))
return {
"ph": results.get('ph', 0), "chlorine": results.get('chlorine', 0),
"nitrates": results.get('nitrates', 0), "hardness": results.get('hardness', 0),
"alkalinity": results.get('alkalinity', 0), "bacteria": results.get('bacteria', 0),
"confidence": overall_confidence, "individualConfidences": confidences,
"processingMethod": "Python CV (LAB Space)",
}
def main():
if len(sys.argv) < 2:
print(json.dumps({"error": "No image path provided"}), file=sys.stderr)
sys.exit(1)
image_path = sys.argv[1]
water_source = sys.argv[2] if len(sys.argv) > 2 else 'unknown'
if not os.path.exists(image_path):
print(json.dumps({"error": f"Image file not found: {image_path}"}), file=sys.stderr)
sys.exit(1)
try:
analyzer = WaterQualityAnalyzer()
results = analyzer.analyze_water_quality(image_path, water_source)
print(json.dumps(results, indent=4))
except Exception as e:
print(json.dumps({"error": str(e)}), file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main() |