Så känner Glimt igen ditt barn – på iPhonen

Peter Theill · 4 november 2026

Glimt gör en sekund från varje dag till en film. Det intressanta är att du inte behöver filma den sekunden: Glimt hittar den i videorna du redan har tagit och väljer sekunden där ditt barn är med i bild, även i en fullsatt kalasvideo med fem andra barn. Allt körs på iPhonen: ingen server, inget konto, ingen uppladdning. Så här fungerar det, med modellerna, matematiken och riktiga tidsmätningar.

Pipelinen

Glimts pipeline från kamerarullen till den beskurna sekunden, i åtta steg1Din kamerarullePhotoKit: dagens videor och Live Photos, videor först, högst 162Plocka bildrutorca 2 per sekund, högst 16 per video (6 per Live Photo), 1024 px3Hitta ansiktenVision: ansiktsrutor + kvalitet, ansikten under 36 px hoppas över4Justera varje ansikteVision-landmärken: ögon, näsa, mungipor → 112 × 112, upprätt5EmbeddingSFace (MobileFaceNet, Core ML): 128 tal per ansikte, ca 2 ms6Jämförcosinuslikhet mot varje referensfoto, det bästa räknas7Poängsätt och väljbarnet 60 %, utseende + skärpa + ansikte 40 %, bästa 1-sekundsfönstret8Beskärfölj barnets ansikte, zooma in när det är litet
Steg 4–6 är ansiktsigenkänningen; resten handlar om att välja en bra sekund och beskära den.

Varför inte bara använda Apples Vision?

Vision gör mycket här: det hittar ansikten (VNDetectFaceCaptureQualityRequest, som också bedömer hur skarpt och hur rakt framifrån varje ansikte är), deras landmärken (VNDetectFaceLandmarksRequest) och, på iOS 18, hur bra en bildruta ser ut (CalculateImageAestheticsScoresRequest, som också flaggar kvitton och skärmavbilder). Det som saknas är vem ett ansikte är. People-albumet i Photos vet det, men det indexet är inte öppet för appar.

Den första versionen av Glimt använde VNGenerateImageFeaturePrintRequest på ett utsnitt av ansiktet. Det är ett generellt bildfingeravtryck: det jämför hår, ljus, färger och bakgrund lika mycket som själva ansiktet. I praktiken matchade det gärna syskon, och vilket barn som helst som fotograferats i samma rum vid samma tid på dagen. Det var fel verktyg.

Modellen för ansiktsigenkänning

Nu har Glimt en egen: SFace (Zhong et al., 2021, ”Sigmoid-Constrained Hypersphere Loss for Robust Face Recognition”), med en MobileFaceNet-backbone, publicerad i OpenCV Zoo under licensen Apache 2.0. Den når 99,40 % på LFW. Den tar ett ansikte på 112 × 112 och returnerar 128 tal, en embedding; två foton av samma person ger embeddings som pekar åt samma håll.

Konverteringen gick ONNX → PyTorch (onnx2torch) → Core ML (coremltools, ML Program, float16), och sedan linjär 8-bitarskvantisering av vikterna. Resultatet är 9,8 MB, laddas på ungefär 0,5 s första gången, och utdata stämmer med den ursprungliga ONNX-modellen med cosinus 0,998 på en testindata. Normaliseringen av indata ligger inuti grafen, så appen skickar in vanliga RGB-pixlar på 0–255.

Justeringen spelar större roll än man tror

SFace tränades på ansikten som justerats mot en fast mall: ögon, nästipp och mungipor på kända platser i kvadraten på 112 × 112. Ett ansikte som lutar eller sitter snett ger en märkbart sämre embedding. Visions landmärken ger de fem punkterna (pupillerna, mitten av näspartiet, läpparnas yttersta punkter); Glimt hittar sedan den rotation, likformiga skalning och förskjutning som bäst flyttar dem till mallen. I två dimensioner har det minstakvadratproblemet en sluten lösning om man behandlar punkterna som komplexa tal:

a = Σ conj(zᵢ − z̄) · (wᵢ − w̄) / Σ |zᵢ − z̄|²      // rotation + scale, one complex number
w = a · z + (w̄ − a · z̄)                          // the transform for any point z

Core Image tillämpar den (en affin transform, mjukvarurenderare, 112 pixlar ut), och utsnittet går till modellen. Referensfoton bäddas in två gånger, som de är och spegelvända, och de två medelvärdesbildas: en lite stabilare referens på köpet.

Är det samma barn? Att kalibrera tröskeln

Appen jämför varje ansiktes embedding med referensfotona med cosinuslikhet och behåller den bästa matchningen. Var gränsen skulle gå mättes i stället för att gissas, på porträtt från Vita huset som är allmän egendom (officiella porträtt med flera års mellanrum och ett familjeporträtt med båda föräldrarna och två döttrar):

Cosinuslikhet mellan ansikts-embeddings: samma person 0,70 till 0,85, familjemedlemmar 0,20 till 0,43, främlingar 0,01 till 0,25. En bildruta räknas som barnet från 0,45.0,45 = barnetSamma person0,830,850,790,70Familj, samma foto0,430,410,370,270,20Familj, annat foto0,300,26Främlingar0,250,180,150,140,120,080,060,030,0100,250,50,751
Varje prick är ett par ansikten; ”samma person” betyder samma person på ett annat foto. Det skuggade bandet är där Glimts ”likhet” stiger från 0 (0,30) till 1 (0,60); en bildruta räknas som barnet från 0,45.

Samma man på porträtt tagna med fyra års mellanrum får 0,83; samma personer utplockade ur familjefotot 0,70–0,85. Främlingar stannar under 0,25. Det svåra fallet är familj: två systrar i samma bild får 0,43 mot varandra, mamma och döttrar upp till 0,41 (samma ljus och pose får släktingar att likna varandra mer), medan mamman mot sina döttrar på ett annat foto sjunker till 0,26–0,30. Så gränsen ligger på 0,45: över systrarna, en bra bit under samma person. Fem foton är en rimlighetskontroll, inte en utvärdering, och gränsen kommer att finjusteras på riktiga familjevideor.

Två regler till håller dubbelgångare ute: i en video räcker inte en lyckosam bildruta (det krävs två bildrutor på 0,45, eller en klart över på 0,57), och när flera ansikten finns i en bildruta räknas bara det som matchar bäst.

Flera referensfoton

Ett referensfoto är en vinkel, ett ljus och en ålder. Barn förändras snabbt. I Glimt kan du lägga till upp till fem foton, och ansiktet i en bildruta behöver bara likna ett av dem, så en profilbild eller förra vinterns ansikte kan ändå kännas igen. När ett foto har flera personer trycker du på rätt ansikte; Glimt gissar aldrig på ”det största”.

Att välja sekunden och beskära den

Varje bildruta får en poäng: 35 % hur bra den ser ut, 20 % skärpa (variansen av en Laplace-operator på en grå kopia på 96 × 96: suddiga bildrutor ändras långsamt från pixel till pixel), 45 % om det finns ett tydligt ansikte. Med referensfoton väger hela den poängen 40 % och ”är det barnet” 60 %: en vanlig bildruta av ditt barn slår en fin bildruta av någon annan. Den valda sekunden är fönstret med bäst medelvärde, så en bra bildruta bredvid en suddig vinner inte.

Beskärningen för en film i porträttformat hade en egen bugg som är värd att dela. Varje bildruta pekade ut det tydligaste ansiktet, och appen tog medelvärdet av positionerna över sekunden. Med två barn växlade det tydligaste ansiktet mellan dem, och medelvärdet hamnade på väggen mittemellan. Nu pekar varje bildruta ut barnet (eller det mest framträdande ansiktet: storlek × kvalitet, vilket är stabilare), och appen tar den största gruppen positioner som ligger nära varandra, inte medelvärdet. När ansiktet är litet zoomar utsnittet in tills det är ungefär en femtedel av bildrutans höjd, högst 1,6× för video.

Hur snabbt går det?

Median i millisekunder per steg på en iPhone 15 Pro: att avkoda bildrutan tar 30 ms, att känna igen ett ansikte 2 msAvkoda en bildruta (1024 px)30 msEstetikpoäng (Vision)7,2 msHitta ansikten + kvalitet5,4 msSkärpa (Laplace)2,1 msKänn igen ansikte (SFace)2 msAnsiktslandmärken1,5 ms
Median per bildruta, iPhone 15 Pro, iOS 27.2, 12 videor, 167 bildrutor. En hel bildruta tar 47 ms; en hel video (16 bildrutor plus inläsning) 0,9 s.

Överraskningen: att känna igen ett ansikte är den billiga delen, ungefär 2 ms på Neural Engine. Att avkoda videobildrutan kostar femton gånger mer. I praktiken tar sig Glimt igenom en fullspäckad dag med videor på några sekunder, och en månad på några minuter.

Körning i bakgrunden

Att fylla ett år av saknade dagar tar en stund, så det bör fortsätta när du lämnar appen. I iOS 26 är BGContinuedProcessingTask gjord för just det: iOS visar förloppet i Dynamic Island och på låsskärmen. Tre saker vi lärde oss den hårda vägen, alla från en liten logg på enheten:

Integritet

Glimt har ingen nätverkskod. Ansikten, embeddings och val stannar i appens egen lagring på iPhonen. Det enda som kan röra nätverket är Photos självt, när det hämtar dina egna videor från din egen iCloud Photos om de inte finns på telefonen.

Tack till: SFace av Yaoyao Zhong med kollegor; ONNX-konvertering av Chengrui Wang; OpenCV Zoo (Apache 2.0). Frågor eller idéer: glimt@theill.com.