CoolFace
Apppublic

himanithattil/casting-defect-detector

sourceHugging Facemitupdated 4mo agoView on Hugging Face
0likes
app.py99 linesDownload Raw Back to root
1import gradio as gr2import google.generativeai as genai3import json4import base645from PIL import Image6import io7 8API_KEYS = [9    "AIzaSyCGXMZfEXCSnrnpgjKR4SWfxmDOKlDb8Hw",10    "AIzaSyDU9obviYZuOCv9ZfZ5MCKknNzehzg-t0s",11    "AIzaSyC2jMIqXg0_YsWW4auDICBfq492YQZR9gk",12    "AIzaSyAtZxL_93uJtkDYRxJdm5uIJmP_Jn85eJA",13    "AIzaSyCsrX1yc60oYXQDmzs5W3EgRIrCQD8JE0s",14    "AIzaSyCOYn9vyn9YzNMNNA7mCiyBI-Xp-hFOHmE",15    "AIzaSyAUCnobLkJ00HVr1zNWnXLfEGFOuJNNlvc",16    "AIzaSyCuxS3UOu5ELWQ5GM98lpuomnLL8bgk_ps"17]18 19PROMPT = """You are an experienced casting quality inspector with 20 years of experience. Analyze this casting component image.20 21UNDERSTAND THIS FIRST:22- Investment cast components naturally have a rough grainy surface — this is NORMAL and NOT a defect23- Sand cast components have an even rougher surface — this is NORMAL and NOT a defect24- Machined components have smooth uniform surfaces — this is NORMAL25- Logos, text, symbols and design features on components are NORMAL26- Parting lines from molds are NORMAL27 28PASS the component if:29- It has normal casting surface texture even if rough or grainy30- It has logos symbols or text markings on it31- It has defined curves and design features32- It looks structurally complete with no damage33 34FAIL the component ONLY if you can clearly see:35- CRACKS — irregular jagged fracture lines clearly going through the material36- GAS POROSITY — multiple clearly visible holes or pits that go INTO the material37- COLD SHUT — a clear seam line where two metal flows did not bond38- SHRINKAGE CAVITY — a clearly sunken collapsed area39- BROKEN SECTION — a missing or broken chunk of the component40- MISRUN — incomplete filling with missing sections41 42KEY RULE:43- Rough grainy surface = NORMAL = PASS44- Logos and markings = NORMAL = PASS  45- Only structural damage = FAIL46- When in doubt always PASS47 48Respond with ONLY this JSON, no extra text:49{"verdict":"PASS or FAIL","defects":[{"type":"exact defect name like Gas Porosity / Shrinkage Cavity / Cold Shut / Hot Tear / Surface Crack","cause":"technical cause","remedy":"technical remedy"}],"summary":"one technical sentence"}50If PASS use empty defects array. Max 2 defects. Return ONLY JSON."""51 52def analyze_casting(image):53    if image is None:54        return json.dumps({"verdict": "ERROR", "defects": [], "summary": "No image provided"})55    56    # Convert PIL image to bytes57    img_byte_arr = io.BytesIO()58    image.save(img_byte_arr, format='JPEG')59    img_byte_arr = img_byte_arr.getvalue()60    img_base64 = base64.b64encode(img_byte_arr).decode('utf-8')61    62    # Try each API key63    for key in API_KEYS:64        try:65            genai.configure(api_key=key)66            model = genai.GenerativeModel('gemini-2.5-flash')67            68            response = model.generate_content([69                PROMPT,70                {"mime_type": "image/jpeg", "data": img_base64}71            ])72            73            raw = response.text.strip()74            clean = raw.replace('```json', '').replace('```', '').strip()75            76            # Extract JSON77            import re78            json_match = re.search(r'\{[\s\S]*\}', clean)79            if json_match:80                result = json.loads(json_match.group())81                return json.dumps(result)82        except Exception as e:83            continue84    85    return json.dumps({86        "verdict": "ERROR",87        "defects": [],88        "summary": "All API keys quota exceeded. Please try again later."89    })90 91iface = gr.Interface(92    fn=analyze_casting,93    inputs=gr.Image(type="pil", label="Upload Casting Image"),94    outputs=gr.Textbox(label="Result"),95    title="Casting Defect Detector",96    description="Upload a casting image to detect defects"97)98 99iface.launch()