Spaces:
Sleeping
Sleeping
| import easyocr | |
| from PIL import Image | |
| from io import BytesIO | |
| from typing import Dict, Any, List | |
| import logging | |
| # Initialize the reader. This is done once when the app starts. | |
| reader = easyocr.Reader(['en']) | |
| def parse_survey_from_image(image_bytes: bytes) -> Dict[str, Any]: | |
| """Extracts key-value pairs from an image using EasyOCR.""" | |
| try: | |
| results = reader.readtext(image_bytes) | |
| text = '\n'.join([res[1] for res in results]) | |
| answers = {} | |
| confidences = [] | |
| for res in results: | |
| if ':' in res[1]: | |
| line = res[1] | |
| confidences.append(res[2]) | |
| key, val = line.split(':', 1) | |
| key = key.strip().lower().replace(" ", "").replace("-", "") | |
| val = val.strip().lower() | |
| if key in ["age"]: | |
| try: | |
| answers["age"] = int(val) | |
| except ValueError: | |
| logging.warning(f"Invalid age value: {val}") | |
| elif key in ["smoker", "smoking"]: | |
| answers["smoker"] = val in ["yes", "true", "y", "1"] | |
| elif key in ["exercise", "activity"]: | |
| answers["exercise"] = val | |
| elif key in ["diet", "food"]: | |
| answers["diet"] = val | |
| confidence = sum(confidences) / len(confidences) if confidences else 0.0 | |
| logging.info(f"Parsed answers from image: {answers}, confidence: {confidence}") | |
| return {"answers": answers, "confidence": confidence} | |
| except Exception as e: | |
| logging.error(f"OCR Error: {e}") | |
| return {"answers": {}, "confidence": 0.0} | |
| def extract_factors(answers: Dict[str, Any]) -> List[str]: | |
| """Converts survey answers into standardized risk factors.""" | |
| factors = [] | |
| if answers.get("smoker"): | |
| factors.append("smoking") | |
| if answers.get("diet") in ["high sugar", "processed", "high-fat"]: | |
| factors.append("poor diet") | |
| if answers.get("exercise") in ["rarely", "never", "infrequently"]: | |
| factors.append("low exercise") | |
| return factors | |
| FACTOR_RISK_SCORES = { "smoking": 35, "poor diet": 25, "low exercise": 20 } | |
| def classify_risk(factors: List[str]) -> Dict[str, Any]: | |
| """Calculates a risk score and level based on factors.""" | |
| score = sum(FACTOR_RISK_SCORES.get(factor, 0) for factor in factors) | |
| risk_level = "low" | |
| if score > 60: risk_level = "high" | |
| elif score > 30: risk_level = "medium" | |
| return {"risk_level": risk_level, "score": score, "rationale": factors} | |
| RECOMMENDATION_MAP = { | |
| "smoking": "Quit smoking", | |
| "poor diet": "Reduce sugar", | |
| "low exercise": "Walk 30 mins daily" | |
| } | |
| def generate_recommendations(risk_level: str, factors: List[str]) -> Dict[str, Any]: | |
| """Generates actionable recommendations based on factors.""" | |
| recs = [RECOMMENDATION_MAP.get(factor) for factor in factors if factor in RECOMMENDATION_MAP] | |
| return {"risk_level": risk_level, "factors": factors, "recommendations": recs, "status": "ok"} |