<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Sharpness on RawCull</title><link>https://rawcull.netlify.app/tags/sharpness/</link><description>Recent content in Sharpness on RawCull</description><generator>Hugo</generator><language>en</language><lastBuildDate>Mon, 06 Apr 2026 08:12:10 +0200</lastBuildDate><atom:link href="https://rawcull.netlify.app/tags/sharpness/index.xml" rel="self" type="application/rss+xml"/><item><title>Sharpness Scoring</title><link>https://rawcull.netlify.app/blog/2026/03/25/sharpness-scoring/</link><pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/blog/2026/03/25/sharpness-scoring/</guid><description>&lt;h1 id="updated-sharpness-scoring-in-rawcull"&gt;Updated Sharpness Scoring in RawCull&lt;a class="td-heading-self-link" href="#updated-sharpness-scoring-in-rawcull" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;This document describes how RawCull computes sharpness scores, what each parameter does, and a boundary-value test procedure for validating parameter behaviour. This applies to version 1.3.7 of RawCull&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="how-the-scoring-pipeline-works"&gt;How the Scoring Pipeline Works&lt;a class="td-heading-self-link" href="#how-the-scoring-pipeline-works" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;pre class="mermaid"&gt;flowchart TD
 A([ARW File]) --&amp;gt; B[Thumbnail decode\nthumbnailMaxPixelSize]
 A --&amp;gt; C[Saliency detection\nApple Vision]

 B --&amp;gt; D[Gaussian pre-blur\npreBlurRadius × isoFactor × resFactor]
 D --&amp;gt; E[Laplacian Metal kernel\nfocusLaplacian]
 E --&amp;gt; F[Amplify\nenergyMultiplier]
 F --&amp;gt; G[Border suppression\nborderInsetFraction]
 G --&amp;gt; H[Render to Float32 buffer]

 H --&amp;gt; I[Full-frame samples\nborder-inset region]
 C --&amp;gt;|bounding box ≥ 3% area| J[Salient-region samples\nVision bounding box]
 H --&amp;gt; J

 I --&amp;gt; K[p95 winsorized tail score\nfull-frame f]
 J --&amp;gt; L[p95 winsorized tail score\nsubject s]

 K --&amp;gt; M{Fusion}
 L --&amp;gt; M
 C --&amp;gt;|area| M

 M --&amp;gt; N[finalScore]
 N --&amp;gt; O([Badge: score / maxScore × 100])

 style A fill:#2d2d2d,color:#fff
 style O fill:#2d2d2d,color:#fff&lt;/pre&gt;
&lt;p&gt;Each ARW file goes through the following stages in detail:&lt;/p&gt;</description></item><item><title>Sharpness Scoring</title><link>https://rawcull.netlify.app/docs/sharpness/</link><pubDate>Wed, 25 Mar 2026 00:00:00 +0000</pubDate><guid>https://rawcull.netlify.app/docs/sharpness/</guid><description>&lt;h1 id="sharpness-scoring"&gt;Sharpness Scoring&lt;a class="td-heading-self-link" href="#sharpness-scoring" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;RawCull can automatically rank every image in a catalog by sharpness, so the sharpest frames rise to the top and out-of-focus or motion-blurred shots sink to the bottom. This page explains what the score means, how to run it, and how to interpret the results.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="overview"&gt;Overview&lt;a class="td-heading-self-link" href="#overview" aria-label="Heading self-link"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When you click &lt;strong&gt;Sharpness&lt;/strong&gt;, RawCull analyses each RAW file using a multi-step pipeline:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A small thumbnail is extracted directly from the ARW file — fast, no full RAW decode needed.&lt;/li&gt;
&lt;li&gt;Apple Vision locates the main subject in the frame and, when classification is enabled, identifies what that subject is (bird, person, animal, etc.). A salient region is accepted when it covers more than 3 % of the frame &lt;strong&gt;or&lt;/strong&gt; when Vision&amp;rsquo;s confidence is ≥ 0.9 — the high-confidence path means a small but clearly identifiable subject (a bird on a stick, a distant raptor) is never discarded for being too small.&lt;/li&gt;
&lt;li&gt;A Gaussian pre-blur smooths the image to suppress high-ISO noise before edge detection. The radius adapts automatically: it scales proportionally with √(ISO/400) to compensate for noise at high ISO values, and with √(imageWidth/512) to maintain consistent spatial-frequency selectivity on larger images. Both factors are capped at 3×.&lt;/li&gt;
&lt;li&gt;A Laplacian edge-detection kernel measures per-pixel sharpness energy across the entire frame. The outer 4 % of each border is excluded from the full-frame score to prevent Gaussian edge artifacts from inflating the result.&lt;/li&gt;
&lt;li&gt;The edge response is amplified, then scored with a &lt;strong&gt;robust tail score&lt;/strong&gt; — the mean of values above the 95th percentile, clipped at the 99.5th — so a single sharp feather edge cannot carry a blurry frame.&lt;/li&gt;
&lt;li&gt;Two scores are computed separately: one for the full frame (minus the border strip) and one for the salient subject region. They are fused as &lt;strong&gt;25 % full-frame + 75 % subject region&lt;/strong&gt;. If no salient region is found, the full-frame score is used directly. A small proportional bonus is applied for subjects that fill more of the frame.&lt;/li&gt;
&lt;li&gt;All scores are normalised against the p90 of the catalog: that anchor becomes &lt;strong&gt;100&lt;/strong&gt;, and every other frame is expressed as a percentage of it. Using p90 rather than the maximum prevents a single noise spike from collapsing the rest of the scale.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Because scores are &lt;strong&gt;relative to your catalog&lt;/strong&gt;, a score of 60 does not mean the image is soft — it means it is 60 % as sharp as the sharpest typical frame in that session. Opening a catalog of sharper images will recalibrate the scale.&lt;/p&gt;</description></item></channel></rss>