← All work
Case study · 2024

Potol Detector

A small Next.js app that tells you if an uploaded photo contains potol (pointed gourd), using a custom-trained image classifier.

Next.jsTypeScriptTailwind CSSAzure Custom VisionLive site ↗Source ↗
potol-detector.vercel.app
Potol Detector — screenshot of the live site

Overview

A one-page joke app inspired by an April 2024 event: upload a photo and it says whether there is potol (pointed gourd) in it. The frontend sends the image to a custom image classification prediction endpoint and shows a yes or no answer.

What I built

  • An ImageUploader client component that previews the chosen file with URL.createObjectURL.
  • Posts the raw image bytes as application/octet-stream to a prediction URL with a Prediction-Key header, both read from environment variables.
  • Finds the potol tag in the returned predictions and only answers yes when its probability is at least 0.99.
  • Loading and error states, styled with Tailwind, deployed on Vercel.

Architecture

Everything runs in the browser; the classifier is a hosted prediction endpoint.

flowchart LR
  subgraph client["Browser"]
    up["ImageUploader component"]
    view["Result message"]
  end
  subgraph ext["External"]
    cvapi["Custom Vision prediction API"]
  end
  up -->|"POST image bytes"| cvapi
  cvapi -->|"tag probabilities"| up
  up --> view

System design

Request flow for a single upload.

sequenceDiagram
  participant U as User
  participant A as Next.js page
  participant V as Prediction API
  U->>A: choose image
  A->>A: show preview and loading
  A->>V: POST octet-stream with Prediction-Key
  V-->>A: predictions list
  alt potol probability at least 0.99
    A-->>U: has potol
  else otherwise
    A-->>U: no potol
  end

Learnings

  • A high threshold (0.99) kept false positives down for a single-class model, at the cost of missing some real potols.
  • Calling the prediction endpoint from the client exposes the key; a Next.js route handler should proxy the request.