From 3510f637ba6df881b5a36edbc0656faa6a391642 Mon Sep 17 00:00:00 2001 From: Barely Removable Date: Tue, 25 Aug 2026 08:30:39 -0700 Subject: [PATCH] Stop telling the model to give up on corners/edges just for being in a holder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The framing caveat added earlier told the model to find the card's real edge inside each mis-cut crop, then immediately offered 'say cannot_assess if the close-up doesn't clearly contain it' — wrapped in alarming language about cases. On a Fleer Ultra Jordan shot in a clear toploader it took the escape hatch for corners AND edges, returning three of four categories as 'can't tell from photo' on a card whose corners are plainly visible through the plastic. That was a regression I introduced, not a limit of the photo. A toploader is transparent: corner sharpness, corner whitening, edge chipping and edge whitening all read through it, and the card's cut line is visible as a distinct boundary inside the holder's (confirmed in the pixel profile — the card's own edge shows as a clear step ~75px inside the detected holder boundary). Those categories now get judged normally, with cannot_assess reserved for genuinely hidden geometry. Surface keeps the escape hatch, because there it's correct: scratches, dust and glare on a holder sit directly over the card's surface and can't be separated from it in a photo. --- vision.py | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/vision.py b/vision.py index 9b8dfdc..2a20113 100644 --- a/vision.py +++ b/vision.py @@ -1001,18 +1001,32 @@ def grade_card(images, api_key=None, model=None, effort=None, zoom_details=True) "read resampling softness as card wear.") if framing: prompt_parts.append( - "IMPORTANT CAVEAT ON THOSE CROPS: {} Because the crop " - "rectangle is derived from that same detection, each close-up " - "is cut relative to the wrong boundary — a corner close-up may " - "well be showing the CORNER OF A CASE, SLEEVE OR HOLDER with " - "the card's own corner sitting somewhere inside the frame, or " - "out of it. Do not assume the crop's own edge is the card's " - "edge. Find the actual card edge inside each close-up first " - "and judge only that; if a given close-up doesn't clearly " - "contain the card's real corner or edge, say cannot_assess " - "for that category rather than grading the holder. Damage, " - "scuffing or whitening on a case is not damage to the " - "card.".format(framing)) + "CAVEAT ON THOSE CROPS: {} The crop rectangle comes from that " + "same detection, so each close-up is cut against the wrong " + "boundary — most often because the card is in a toploader, " + "sleeve or case and the detection found the HOLDER's outline " + "instead of the card's. The card's own corner or edge is " + "therefore sitting inside the frame rather than at the crop's " + "own corner. Locate it and judge that.\n" + "Being in a holder is NOT by itself a reason to give up on " + "corners or edges. A toploader or penny sleeve is clear " + "plastic: corner sharpness, corner whitening, edge chipping " + "and edge whitening all read straight through it, and the " + "card's cut line is normally plainly visible as a distinct " + "boundary inside the holder's. Judge those categories " + "normally — just make sure you are reading the CARD's " + "boundary and not the holder's, and never count scuffing, " + "scratching or whitening that belongs to the plastic as " + "damage to the card. Reserve cannot_assess for a corner or " + "edge genuinely hidden — obscured by a label, blown out by " + "glare, or out of frame — not merely for being behind clear " + "plastic.\n" + "SURFACE is the real exception. Scratches, dust, haze and " + "glare on a holder sit directly over the card's own surface " + "and cannot be separated from it in a photo, so " + "cannot_assess IS the honest answer for surface on a card " + "shot through a scratched or dusty holder — say so plainly " + "and name the holder as the reason.".format(framing)) prompt_parts.append("Estimate the PSA grade this trading card would likely receive.") parsed, usage = _call_vision(