Inspiration

I run a photography business. After every event I spend hours culling: going through hundreds of photos to pick the few dozen I deliver. For this project I used a real shoot of this hackathon. I took 749 photos, delivered 26, and culling took me two hours.

AI culling tools already exist. They score every photo and keep the top N. When we ran that approach on my shoot, it put 21 of 26 picks into just two parts of the event. It kept zero photos from the opening ceremony, even though I delivered three from it. Clients don't want the 26 sharpest photos. They want every part of their event covered.

What it does

Cull is an AI culling agent. The photographer types an instruction in plain English, for example:

cull this shoot to about 26, at least one photo from every moment, no blinks, favor candids

Cull then:

  1. Scores every photo once for focus, exposure, bursts, faces, closed eyes, smiles and scene type.
  2. Groups photos into moments of the event based on time gaps.
  3. Turns the instruction into rules using Claude.
  4. Solves the rules. Every moment gets covered first, then caps apply, then the best remaining photos fill the count.
  5. Shows a review grid where every photo has a reason it was kept or cut, and any pick can be overridden.
  6. Exports to Lightroom Classic. Picks get star ratings, color labels and keywords in .xmp sidecar files. Original photos are never modified.

Results on the real shoot

Top-N tool Cull
Moments I delivered from that were covered 4 of 9 9 of 9
All moments covered 5 of 14 14 of 14
Time to cull 749 photos 8 minutes (vs 2 hours by hand)

How we built it

  • Python pipeline for ingest, EXIF, Sony ARW previews and burst detection, plus local sharpness and exposure scoring
  • Amazon Rekognition for faces, eyes, smiles and scene tags
  • Claude on Amazon Bedrock in two roles: a taste score on finalist photos, and an agent that converts the plain-English instruction into a rule list in one call
  • Deterministic solver in pure Python that runs over cached scores, so changing a rule re-solves in seconds with no new AI calls
  • Web review UI with a moment-by-moment grid, reasons on hover, overrides and full-resolution previews
  • XMP writer so Lightroom Classic reads the results natively

Challenges we ran into

  • Choosing the demo shoot. Our first test shoot did not reflect how I actually deliver, so we switched to a shoot where the coverage problem was real and measurable.
  • Defining a "moment." Splitting by scene tags produced 37 fragmented moments. Switching to time gaps of 90 seconds produced 14 that matched the real event.
  • Moments with only bad photos. Two moments had nothing but overexposed frames. Instead of dropping them, Cull keeps the best available frame and labels it as a weak pick, so the photographer sees the gap.
  • Honest evaluation. Cull matched my exact frame choices 3 of 26 times, the same as Top-N. Exact frame choice is taste. We report that number as it is and never tuned scoring to my picks.

What we learned

  • The real failure of AI culling is not picking a worse photo. It is silently dropping an entire part of the event.
  • Keeping the language model to one job (instruction to rules) and leaving selection to a deterministic solver makes results explainable, repeatable and fast to change.
  • Measuring against a real delivery keeps you honest about which claims actually hold up.

What's next

  • Moment grouping that understands event structure, not only time gaps
  • Learning a photographer's taste from their past deliveries
  • A Lightroom plugin so culling happens without leaving the editor

Built With

Share this project:

Updates

Submission history