Inspiration

What it does

How we built it

Challenges we ran into

Accomplishments that we're proud of

What we learned

What's next for SolarScan

Problem

Rooftop solar is growing fast, but checking what is really installed still needs a site visit or trust in paperwork. Installers, small owners, energy co-ops and community-solar networks need a quick, cheap first check.

What it does

Upload a drone or aerial image and give the scale (metres per pixel). SolarScan:

  • finds the PV arrays;
  • draws them with a confidence score;
  • returns the panel area, an estimated kWp and an estimated kWh per year, as JSON and as an annotated image.

OpenCV 5 implementation

A pure OpenCV 5.0 pipeline (opencv-python-headless==5.0.0.93):

  1. CLAHE on the Lab L channel.
  2. HSV colour candidates.
  3. Morphology.
  4. Contours with rectangularity (minAreaRect) and solidity (convexHull) filters.
  5. A Canny grid-texture check: solar modules have a cell grid, while shadows, cars and dark roofs don't.
  6. A confidence score and area → kWp → kWh, then polylines / putText annotation.

It takes about 10–60 ms per image on a CPU.

Evaluation

We used 9 real CC-licensed Wikimedia Commons images: drone shots, oblique photos and a solar-thermal negative. Each candidate was hand-labelled, with the threshold tuned on 2 images and tested on 7. On the held-out images, the texture check raised precision from 0.72 to 0.89: it removed 11 of 16 false positives and lost 2 of 42 true detections. Failures are documented: the curved Apple Park roof is missed, some cars and shadows still pass, oblique photos split arrays, and recall is not measured yet. All of it is reproducible with python eval/evaluate.py.

Architecture & AWS

  • app.py is a small HTTP API: /analyze, /health, plus an upload page.
  • The AWS target is a Lambda container on arm64/Graviton behind a Function URL, with the image in ECR and logs in CloudWatch (aws/).
  • Live on AWS: https://xfusd3bjr5owlzbrrt2dzoelfy0zidza.lambda-url.us-east-1.on.aws/ . This is AWS Lambda (Python 3.12, arm64/Graviton, 1024 MB) behind a public Function URL in us-east-1, with the code package in S3 and logs in CloudWatch. The whole OpenCV 5 pipeline runs inside Lambda: GET / serves the upload page, GET /health returns {"opencv":"5.0.0"}, and POST /analyze?mpp= does the analysis. A warm request takes about 0.5 s.

Responsible use

  • Only use images you have rights to.
  • Nothing is stored.
  • Results are estimates with confidence scores, and a person must confirm before any payment or reward depends on them.

What's next

  • A small cv2.dnn segmentation model trained on an open PV dataset, with this heuristic as a fallback.
  • PVGIS yield per location.
  • A recall benchmark with polygon labels.

Built With

Share this project:

Updates

Submission history