analysis: inspect the current sun-hat clip at 25fps and narrow flicker candidates

这个提交包含在:
dayu 于 2026-10-22 20:02:23 +08:00 提交
1 父节点 623dcb878b
当前提交 a0c5357efd
6 个文件已更改
+458 -11

没有与搜索条件相匹配的文件

@@ -0,0 +1,318 @@
{
"decodedSize": [
1920,
1080
],
"decodeOrVisionErrors": 0,
"duplicateSourceFramePairs": 0,
"durationSeconds": 18.752066666666668,
"emptyDetectionFrames": 0,
"frames": 469,
"heldFrames": 0,
"landmarkConfidenceBelow055Frames": 0,
"largestContourChanges": [
{
"actualSeconds": 5.7057,
"bboxCenterStep": 0.010612391844050412,
"bboxRelativeSizeStep": 0.07225176667426436,
"faceConfidence": 1,
"faceCount": 1,
"frame": 143,
"held": false,
"landmarkConfidence": 0.85870361328125,
"outputAllShapeStep": 0.05320087993361461,
"outputContourShapeStep": 0.0524041977802718,
"points76Count": 76,
"rawAllShapeStep": 0.06465122287331607,
"rawContourShapeStep": 0.06330400492305996,
"rawEyeShapeStep": 0.07106297705037405,
"requestedSeconds": 5.72
},
{
"actualSeconds": 5.538866666666666,
"bboxCenterStep": 0.011085862886644501,
"bboxRelativeSizeStep": 0.06308677201537605,
"faceConfidence": 1,
"faceCount": 1,
"frame": 139,
"held": false,
"landmarkConfidence": 0.86663818359375,
"outputAllShapeStep": 0.05242709853363116,
"outputContourShapeStep": 0.046564814499130476,
"points76Count": 76,
"rawAllShapeStep": 0.06161259278352428,
"rawContourShapeStep": 0.05478966859045086,
"rawEyeShapeStep": 0.06493439304604706,
"requestedSeconds": 5.56
},
{
"actualSeconds": 5.6723333333333334,
"bboxCenterStep": 0.009899754844891629,
"bboxRelativeSizeStep": 0.07041863176014063,
"faceConfidence": 1,
"faceCount": 1,
"frame": 142,
"held": false,
"landmarkConfidence": 0.86846923828125,
"outputAllShapeStep": 0.0504812129727618,
"outputContourShapeStep": 0.04661140849311553,
"points76Count": 76,
"rawAllShapeStep": 0.05657646866920014,
"rawContourShapeStep": 0.05209665662633769,
"rawEyeShapeStep": 0.0633232078503364,
"requestedSeconds": 5.68
},
{
"actualSeconds": 18.7187,
"bboxCenterStep": 0.012083635671277248,
"bboxRelativeSizeStep": 0.045801810508214524,
"faceConfidence": 1,
"faceCount": 1,
"frame": 468,
"held": false,
"landmarkConfidence": 0.813995361328125,
"outputAllShapeStep": 0.034052174045594144,
"outputContourShapeStep": 0.043147628575738506,
"points76Count": 76,
"rawAllShapeStep": 0.04111983043006513,
"rawContourShapeStep": 0.05091513919680358,
"rawEyeShapeStep": 0.029191044989766733,
"requestedSeconds": 18.72
},
{
"actualSeconds": 5.739066666666667,
"bboxCenterStep": 0.0096878552974905,
"bboxRelativeSizeStep": 0.050414751769179866,
"faceConfidence": 1,
"faceCount": 1,
"frame": 144,
"held": false,
"landmarkConfidence": 0.86083984375,
"outputAllShapeStep": 0.036875562148072825,
"outputContourShapeStep": 0.036457754092126635,
"points76Count": 76,
"rawAllShapeStep": 0.0466359793805061,
"rawContourShapeStep": 0.04577259881583104,
"rawEyeShapeStep": 0.05000862947922753,
"requestedSeconds": 5.76
},
{
"actualSeconds": 0.8675333333333334,
"bboxCenterStep": 0.003874961092189615,
"bboxRelativeSizeStep": 0.07178938570952054,
"faceConfidence": 1,
"faceCount": 1,
"frame": 22,
"held": false,
"landmarkConfidence": 0.8583984375,
"outputAllShapeStep": 0.031532331820470494,
"outputContourShapeStep": 0.0381074357036598,
"points76Count": 76,
"rawAllShapeStep": 0.03707185765347939,
"rawContourShapeStep": 0.04568537667821508,
"rawEyeShapeStep": 0.034575716035532285,
"requestedSeconds": 0.88
},
{
"actualSeconds": 18.651966666666667,
"bboxCenterStep": 0.007272824106484237,
"bboxRelativeSizeStep": 0.03719342311108376,
"faceConfidence": 1,
"faceCount": 1,
"frame": 467,
"held": false,
"landmarkConfidence": 0.8199462890625,
"outputAllShapeStep": 0.03952595504917539,
"outputContourShapeStep": 0.0403761896420276,
"points76Count": 76,
"rawAllShapeStep": 0.04399124673462057,
"rawContourShapeStep": 0.0450952404425199,
"rawEyeShapeStep": 0.04542945579876513,
"requestedSeconds": 18.68
},
{
"actualSeconds": 0.9009,
"bboxCenterStep": 0.0017162987254983866,
"bboxRelativeSizeStep": 0.014351427482534596,
"faceConfidence": 1,
"faceCount": 1,
"frame": 23,
"held": false,
"landmarkConfidence": 0.85809326171875,
"outputAllShapeStep": 0.026103724683818753,
"outputContourShapeStep": 0.04109990769809984,
"points76Count": 76,
"rawAllShapeStep": 0.028649663225073875,
"rawContourShapeStep": 0.04465304774876588,
"rawEyeShapeStep": 0.02979010461963986,
"requestedSeconds": 0.92
},
{
"actualSeconds": 0.7007,
"bboxCenterStep": 0.007675079557145801,
"bboxRelativeSizeStep": 0.059965605197173644,
"faceConfidence": 1,
"faceCount": 1,
"frame": 18,
"held": false,
"landmarkConfidence": 0.877166748046875,
"outputAllShapeStep": 0.038188462475739905,
"outputContourShapeStep": 0.040855905682333056,
"points76Count": 76,
"rawAllShapeStep": 0.04142583196750897,
"rawContourShapeStep": 0.04413941822893812,
"rawEyeShapeStep": 0.04424396634844577,
"requestedSeconds": 0.72
},
{
"actualSeconds": 0.8341666666666666,
"bboxCenterStep": 0.0019315279136915449,
"bboxRelativeSizeStep": 0.03041757827231506,
"faceConfidence": 1,
"faceCount": 1,
"frame": 21,
"held": false,
"landmarkConfidence": 0.861602783203125,
"outputAllShapeStep": 0.023950562918532762,
"outputContourShapeStep": 0.0391113963086702,
"points76Count": 76,
"rawAllShapeStep": 0.026769304364061126,
"rawContourShapeStep": 0.043656761461571575,
"rawEyeShapeStep": 0.021617825564847367,
"requestedSeconds": 0.84
},
{
"actualSeconds": 5.9726333333333335,
"bboxCenterStep": 0.0076538482284609945,
"bboxRelativeSizeStep": 0.009531954788836172,
"faceConfidence": 1,
"faceCount": 1,
"frame": 150,
"held": false,
"landmarkConfidence": 0.85198974609375,
"outputAllShapeStep": 0.03696981884576201,
"outputContourShapeStep": 0.038389239030267384,
"points76Count": 76,
"rawAllShapeStep": 0.04143716031529852,
"rawContourShapeStep": 0.042871635488955444,
"rawEyeShapeStep": 0.0428226737500748,
"requestedSeconds": 6
},
{
"actualSeconds": 16.649966666666668,
"bboxCenterStep": 0.006605729070676864,
"bboxRelativeSizeStep": 0.025478189396700213,
"faceConfidence": 1,
"faceCount": 1,
"frame": 417,
"held": false,
"landmarkConfidence": 0.8674774169921875,
"outputAllShapeStep": 0.03284710686769975,
"outputContourShapeStep": 0.036339332152690744,
"points76Count": 76,
"rawAllShapeStep": 0.037116421558418974,
"rawContourShapeStep": 0.04240155312389841,
"rawEyeShapeStep": 0.03197382659897345,
"requestedSeconds": 16.68
}
],
"multipleFaceFrames": 0,
"nominalSourceFPS": 29.970029830932617,
"outputWithout76Frames": 0,
"partial76Frames": 0,
"samplingFPS": 25,
"scope": "Independent offline decoding and the current production detector/tracker; not FCP render logs or target execution. Shape steps remove previous bbox translation/scale, but still include actual pose/expression changes.",
"sourceBasename": "girl-in-sun-hat-smiling-in-rural-field-2026-10-03-13-54-14-utc.mov",
"statistics": {
"bboxCenterStep": {
"max": 0.012083635671277248,
"median": 0.0025497870742485452,
"min": 0.00020005997144872253,
"n": 468,
"p95": 0.006821726779186577
},
"bboxRelativeSizeStep": {
"max": 0.07225176667426436,
"median": 0.009157247402053037,
"min": 6.255832853296894e-06,
"n": 468,
"p95": 0.03431959948374386
},
"landmarkConfidence": {
"max": 0.9240875244140625,
"median": 0.867706298828125,
"min": 0.813995361328125,
"n": 469,
"p95": 0.902191162109375
},
"outputAllShapeStep": {
"max": 0.05320087993361461,
"median": 0.009735492145012412,
"min": 0.0029755122029975372,
"n": 468,
"p95": 0.026782532902396017
},
"outputContourShapeStep": {
"max": 0.0524041977802718,
"median": 0.011810624254892923,
"min": 0.002450992809745613,
"n": 468,
"p95": 0.028720841841711312
},
"rawAllShapeStep": {
"max": 0.06465122287331607,
"median": 0.01108023509780489,
"min": 0.0031002818411607846,
"n": 468,
"p95": 0.030464142596339925
},
"rawContourShapeStep": {
"max": 0.06330400492305996,
"median": 0.013550650249078297,
"min": 0.002692092571665042,
"n": 468,
"p95": 0.03357642027607019
},
"rawEyeShapeStep": {
"max": 0.07106297705037405,
"median": 0.010302814344493833,
"min": 0.0013460890263982167,
"n": 468,
"p95": 0.02979010461963986
}
},
"timelineOffsetSeconds": 18.72,
"nativeContext": {
"app": "Final Cut Pro",
"project": "大鱼人像美化验收-20261021",
"format": "1080p25",
"selectedClipStartTimecode": "00:00:18:18",
"selectedClipEndTimecode": "00:00:37:11",
"timelinePlayheadAX": "00:00:24:11",
"viewerLCD": "00:00:35:22",
"faceThin": 1,
"faceBigEye": 0.9035486629353234,
"fastMultiFace": false,
"sourceResolvedBy": "Selected timeline clip > File > Reveal in Finder",
"timelineMediaMapping": "Offset18.72 is inferred from clip placement; source in-point/retiming not exported, so source5.72 -> timeline24:11 is approximate. Viewer LCD differs from AX playhead; displayed frame not asserted."
},
"interpretation": {
"partialTopologySwitchObserved": false,
"candidate": "Fully detected geometry changes retained by the current box-remapping and 90% current-frame point blend; eye effect also active",
"notProven": [
"Observed geometric change includes actual head motion, rotation and expression; not all measured change is detector noise",
"No target output frames or live target internal geometry captured",
"Native FCP arrival order and detection/color/scale can differ from the independent decode",
"Big-eye contribution not measured independently on the native timeline"
]
},
"referenceProcessIdentity": {
"observedAlreadyRunning": true,
"outerApp": "/Library/Plug-Ins/FxPlug/MSE18V2.app",
"version": "2.4.0",
"pluginSha256": "577303e0de72e07feb576c882e82382b3f056b023a7e987d990ffb37f6b16109",
"matchesRequestedDownloadsBinary": true,
"analysisLaunchedTarget": false,
"internalTargetGeometryCaptured": false
}
}
@@ -1,5 +1,5 @@
{ {
"scope": "Source and isolated authored synthetic diagnostics plus static REA of the requested 2.4.0 binary; no native host comparison", "scope": "Current source review, isolated authored diagnostics, static REA of requested2.4.0, and independent25fps scan of the user-selected current clip; no native dual-plugin comparison",
"sourceBaseline": "b58fec1a86db7a2e474e1cc65a5911447b5906b9", "sourceBaseline": "b58fec1a86db7a2e474e1cc65a5911447b5906b9",
"installedVersion": "1.3.2 (17)", "installedVersion": "1.3.2 (17)",
"productSourceUnchanged": true, "productSourceUnchanged": true,
@@ -18,14 +18,19 @@
"scripts/diagnose-tracking.m": "bc758bf5ec4825006930be8997889404f63c28da1fe06ad8872b0901b2795d2c", "scripts/diagnose-tracking.m": "bc758bf5ec4825006930be8997889404f63c28da1fe06ad8872b0901b2795d2c",
"docs/analysis/tracking-flicker-20261022/synthetic-results.json": "5fdbad4887dd78658c06f5c6d8e70c9e53fd7b54e11a9cc31ee1958631cbc1a8", "docs/analysis/tracking-flicker-20261022/synthetic-results.json": "5fdbad4887dd78658c06f5c6d8e70c9e53fd7b54e11a9cc31ee1958631cbc1a8",
"docs/analysis/tracking-flicker-20261022/rea-evidence.json": "4b367759388c8e061e138623184ae8a6875dbab22659eefd4e474b141b8868fa", "docs/analysis/tracking-flicker-20261022/rea-evidence.json": "4b367759388c8e061e138623184ae8a6875dbab22659eefd4e474b141b8868fa",
"scripts/diagnose-tracking.sh": "c1993ca91cee596a21db1e4f86ba224be85c37495c783f9c3b21872aff210765" "scripts/diagnose-tracking.sh": "c1993ca91cee596a21db1e4f86ba224be85c37495c783f9c3b21872aff210765",
"scripts/inspect-tracking-sequence.m": "0b94fc92669acf4d36861ccb25077b767189b8a72647e0d304627dbda5d052eb",
"docs/analysis/tracking-flicker-20261022/current-clip-summary.json": "043ba688c606fb9e56449fd02108b34789fd41c4d9a2552cd07f4d3bf78a00f0"
}, },
"limits": [ "limits": [
"No user frames or complete user landmark arrays used or uploaded",
"No target process executed or host UI controlled",
"Static reachable/default-configuration branches do not prove runtime branch execution", "Static reachable/default-configuration branches do not prove runtime branch execution",
"Same-frame raw cache, hold and out-of-order behavior were isolated using our actual current implementation", "Same-frame raw cache, hold and out-of-order behavior were isolated using our actual current implementation",
"No APP rebuild, install, package or article publication for this analysis", "No APP rebuild, install, package or article publication for this analysis",
"User clarified current FCP timeline: sun-hat subject, 1080p25, fast multi off, faceThin1, bigEye about0.90; exact source/frame analysis in progress" "User source decoded only locally; no source frames or complete real landmark arrays uploaded",
] "User current FCP clip confirmed, all469 offline samples have full76; earlier missing-point synthetic case is not established as this clip cause",
"Only scalar clip summary retained; full scalar per-frame diagnostics remain in ignored build",
"Approximate timeline offset is not a substitute for verified source in-point/retiming",
"Reference was already running; only process executable identity read. Native UI read/reveal/raise only, no effect/timeline edits; no target launch, debugger or geometry trace."
],
"currentClipSummary": "current-clip-summary.json"
} }
+18 -3
查看文件
@@ -1,12 +1,12 @@
# 瘦脸跟踪闪烁:1.3.2 与目标 2.4.0 的对齐缺口 # 瘦脸跟踪闪烁:1.3.2 与目标 2.4.0 的对齐缺口
2026-10-22。用户实测同一段素材,本插件瘦脸跟踪闪烁,目标插件稳定。本次分析基线为 `b58fec1a86db7a2e474e1cc65a5911447b5906b9`,已安装版仍为 1.3.2(17)。只做源码审查、隔离合成复现和静态二进制对照,没有修改产品源码、重新编译 APP 或操作宿主。 2026-10-22。用户实测同一段素材,本插件瘦脸跟踪闪烁,目标插件稳定。本次分析基线为 `b58fec1a86db7a2e474e1cc65a5911447b5906b9`,已安装版仍为 1.3.2(17)。完成源码审查、隔离合成复现、静态二进制对照和当前素材的独立连续帧采样;通过宿主界面读取状态并定位源文件,没有修改参数/片段、产品源码或重新编译 APP。
主要缺口在跨帧几何的有效性判定、坏帧保持与缓存更新。此前恢复单帧瘦脸位移场,并没有完整对齐新版目标的连续跟踪链。以下区分已经复现的本品行为、目标的静态分支,以及尚未定位到用户素材具体帧的部分。 主要缺口在跨帧几何的有效性判定、坏帧保持与缓存更新。此前恢复单帧瘦脸位移场,并没有完整对齐新版目标的连续跟踪链。以下区分已经复现的本品行为、目标的静态分支,以及尚未定位到用户素材具体帧的部分。
## 目标版本与旧分析的边界 ## 目标版本与旧分析的边界
本次目标是用户指定的 `/Users/dayu/Downloads/MSE18V2.app`,版本 **2.4.0 / 20260724150000**。插件通用二进制 SHA-256 为 `577303e0de72e07feb576c882e82382b3f056b023a7e987d990ffb37f6b16109`,arm64 切片为 `afc71d0d21fd3c1ca95ca745ddafcd729e36ad95f17d8638009f2e45d9b7e8df`。切片逐字节核对过本次目标,REA 使用 Ghidra 12.1.4;未执行目标。 本次目标是用户指定的 `/Users/dayu/Downloads/MSE18V2.app`,版本 **2.4.0 / 20260724150000**。插件通用二进制 SHA-256 为 `577303e0de72e07feb576c882e82382b3f056b023a7e987d990ffb37f6b16109`,arm64 切片为 `afc71d0d21fd3c1ca95ca745ddafcd729e36ad95f17d8638009f2e45d9b7e8df`。切片逐字节核对过本次目标,REA 使用 Ghidra 12.1.4。随后仅读取已运行的系统 FxPlug 目标进程,其2.4.0可执行文件摘要与Downloads目标一致;本次没有启动目标、附加调试器或采集其内部几何。
原有 [auto-follow-report.json](auto-follow-report.json) 分析的是 `/Applications/MSE18V2.app` 的旧版 `1.0.20260617-170517`,通用二进制 SHA 为 `6c5d74bc844a5c5f745718b48ea10ec6635d08aa08a5b6dc6e62653980849f8a`。其中 temporal 混合系数和历史优先级不能直接当成 2.4.0 的默认瘦脸实现。 原有 [auto-follow-report.json](auto-follow-report.json) 分析的是 `/Applications/MSE18V2.app` 的旧版 `1.0.20260617-170517`,通用二进制 SHA 为 `6c5d74bc844a5c5f745718b48ea10ec6635d08aa08a5b6dc6e62653980849f8a`。其中 temporal 混合系数和历史优先级不能直接当成 2.4.0 的默认瘦脸实现。
@@ -14,6 +14,21 @@
对应 Evidence:render `ev_2330b66132cd6539b8c66313c8dc43ca6ff5eb3e0881abbbe26857f99de6a83b`;pin-style `ev_58dee36fddf4e4c98ce3d880a0bb98190351d1269c960b3ccc275aef81265e8f`;直接调用关系 `ev_568a93f2165e5dc5046e610f47c23e9cebc33f55b5d12d3ee005a1e99a7191f6`、`ev_a8cf6f3aec6fbcf2b698ab8ec52313e20a6a5e0d636bc922c4293e436861db7e`、`ev_7c53c39d245e0063cab89358ab8948cdd734488460464d5f455674bb80a1515a`。 对应 Evidence:render `ev_2330b66132cd6539b8c66313c8dc43ca6ff5eb3e0881abbbe26857f99de6a83b`;pin-style `ev_58dee36fddf4e4c98ce3d880a0bb98190351d1269c960b3ccc275aef81265e8f`;直接调用关系 `ev_568a93f2165e5dc5046e610f47c23e9cebc33f55b5d12d3ee005a1e99a7191f6`、`ev_a8cf6f3aec6fbcf2b698ab8ec52313e20a6a5e0d636bc922c4293e436861db7e`、`ev_7c53c39d245e0063cab89358ab8948cdd734488460464d5f455674bb80a1515a`。
## 当前时间线素材的连续帧核对
用户补充截图后,在 Final Cut Pro 当前时间线选中片段,通过“文件 → 在访达中显示”确认源视频为 `girl-in-sun-hat-smiling-in-rural-field-2026-10-03-13-54-14-utc.mov`。项目为 1080p25,选中片段从18:18到37:11,瘦脸1.00、大眼0.90355、多人模式关闭。没有修改参数或片段;检查结束返回 FCP。
直接调用当前产品检测器与跟踪器,在独立1920×1080解码上按25fps采样源文件全长18.752秒,共 **469帧**。源帧率为29.97003,因此这里模拟项目的采样节奏,并非逐一处理所有源帧,也不等同于FCP的实时请求/色彩/尺寸路径。
- 469帧全部为单脸且完整76点;空检测、部分点、held、Vision/解码错误均为0,关键点置信度最低0.814。**本段离线检查没有触发上文合成的“缺点使瘦脸归零”路径,也没有触发低于0.55的置信度条件。不能将它直接认定为当前素材的主因。**
- 最大轮廓形状步幅出现在请求源时间5.72秒(实际取到5.7057秒)附近。扣除前后检测框的平移/缩放后,raw轮廓RMS步幅为脸框尺度的6.33%,当前稳定输出仍为5.24%;眼部区域步幅7.11%。同一步检测框尺寸变化7.23%,框中心变化0.01061(全图归一化距离)。
- 变化较大的连续区间包括源5.56–5.76秒,另有0.7–0.92秒与片尾。按照所选片段位置、假设源入点为0且未变速,5.72秒约对应时间线24:11,与AX播放头24:11相近;未导出源入点/重定时,且检视器LCD同时为35:22,不能断言用户截图就是该源帧。
- 数值包含真实头部旋转和表情变化;平移/缩放抵消并未消除这些运动。因此它证明“检测仍成功时,几何变化大部分继续进入变形”,尚未量出其中多少属于错误检测。瘦脸和接近0.90的大眼都开启,大眼实现仍为近似,需要独立排查其视觉贡献。
这次素材的排查优先级应先放在**完整有效帧的框/点变化如何进入瘦脸,以及高强度大眼叠加**,再核对新版目标的连续框、几何质量判定与时间状态。一般性的部分失检、空缓存和蒙版缺口仍成立,但不能拿其他情境的合成失败代替这段素材的逐帧归因。
[当前素材标量摘要](tracking-flicker-20261022/current-clip-summary.json) 保存计数、分布和峰值时间;原视频、截图和完整真实关键点没有上传。通用诊断源码为 `scripts/inspect-tracking-sequence.m`;包含生产 .m 以复用真实静态几何转换和跟踪器,编译时只编译该诊断入口,不再重复链接 PGFaceProcessor.m。
## 已确定的差异 ## 已确定的差异
| 环节 | 当前 1.3.2 | 目标 2.4.0 的静态证据 | 对闪烁的意义 | | 环节 | 当前 1.3.2 | 目标 2.4.0 的静态证据 | 对闪烁的意义 |
@@ -48,7 +63,7 @@ pin-style 的接纳分支复制本帧合格点,保持分支使用旧有效点
- **补齐缓存和外观同步。** 明确同帧结果与新增前帧历史的失效关系、源切换隔离及默认蒙版跟随;以顺序/倒序/重复/多线程请求对照输出。 - **补齐缓存和外观同步。** 明确同帧结果与新增前帧历史的失效关系、源切换隔离及默认蒙版跟随;以顺序/倒序/重复/多线程请求对照输出。
- **用同一段素材做连续帧验收。** 锁定宿主、原始帧率、预览/导出条件和相同单项参数;记录检测有效性、保持原因、框/点扰动与效果开关变化,和目标逐帧对照。单张图正常、自动用例通过都不足以宣布闪烁修复。 - **用同一段素材做连续帧验收。** 锁定宿主、原始帧率、预览/导出条件和相同单项参数;记录检测有效性、保持原因、框/点扰动与效果开关变化,和目标逐帧对照。单张图正常、自动用例通过都不足以宣布闪烁修复。
用户随后指定当前时间线的草帽人物素材,已在 Final Cut Pro 确认项目为1080p25、多人模式关闭、瘦脸1.00,且大眼约0.90;正在对源素材做连续帧核对。现有结论已定位实现缺口与可复现机制,尚未将某一种机制认定为该素材闪烁的唯一原因。本次不构建新 APP,不更新安装包或文章。 当前素材、宿主和可见参数已确认,并完成469帧独立采样;有效点短暂缺失未在该采样中出现。实现缺口与几何变化已定位,目标与本品的原生同帧输出、源入点映射和大眼贡献仍未分离,尚未认定唯一原因。本次不构建新 APP,不更新安装包或文章。
## 保留资料 ## 保留资料
+1 -1
查看文件
@@ -10,7 +10,7 @@
## 最新待修问题:瘦脸跟踪闪烁(2026-10-22) ## 最新待修问题:瘦脸跟踪闪烁(2026-10-22)
用户实测同一段素材,本插件有闪烁、目标稳定。本次完成源码/合成诊断和 Downloads 2.4.0 的静态复核,未修改产品源码或安装版。新版单主要人脸的渲染路径为 pin-style 质量筛选、条件连续框跟踪和坏帧保持;原 auto-follow-report 的旧 Applications 版本 temporal 系数不能直接沿用。已复现部分76点缺失导致瘦脸归零、框抖动无衰减、首次请求空帧缓存不随补入前帧修正,以及几何保持时默认外观蒙版清零。用户已确认当前FCP时间线的草帽人物素材(1080p25、瘦脸1、大眼约0.9、多人关闭),具体连续帧触发率和宿主实际请求序列尚未测量,不宣称已修复。见[跟踪闪烁对齐分析](analysis/跟踪闪烁对齐分析.md),复现入口 `zsh scripts/diagnose-tracking.sh`;这次不是新发行版,无需重发安装包或文章。 用户实测同一段素材,本插件有闪烁、目标稳定。本次完成源码/合成诊断和 Downloads 2.4.0 的静态复核,未修改产品源码或安装版。新版单主要人脸的渲染路径为 pin-style 质量筛选、条件连续框跟踪和坏帧保持;原 auto-follow-report 的旧 Applications 版本 temporal 系数不能直接沿用。已复现部分76点缺失导致瘦脸归零、框抖动无衰减、首次请求空帧缓存不随补入前帧修正,以及几何保持时默认外观蒙版清零。已确认当前FCP草帽素材(1080p25、瘦脸1、大眼约0.9、多人关闭):独立469帧均单脸/完整76点,没有触发缺点归零;源5.56–5.76秒几何变化较大,5.72秒raw/稳定后轮廓步幅6.33%/5.24%。这些还含真实运动,原生请求与大眼贡献未分离,不宣称已修复。见[跟踪闪烁对齐分析](analysis/跟踪闪烁对齐分析.md),复现入口 `zsh scripts/diagnose-tracking.sh`;这次不是新发行版,无需重发安装包或文章。
## 先读和先查 ## 先读和先查
+1 -1
查看文件
@@ -165,4 +165,4 @@ origin/github 的 main、工作分支和 v1.3.2 标签已推送并回读。匿
用户报告目标稳定而本插件闪烁。新目标2.4.0的静态REA复核发现瘦脸单主要人脸改走 pin-style 筛选与保持,条件可达连续对象框跟踪。现有旧版自动跟随报告不能作为该新版主路径完全对齐的依据。直接链接当前产品源码的合成探针确认:76点完整/缺失/完整使变形通道85835/0/85835;纯框抖动输出/输入振幅比1;先请求40ms空帧、再补0ms有效脸后,缓存40ms仍空,与顺序请求不同;默认外观蒙版在几何保持时可清零。这些均为合成诊断,不是用户素材或目标运行统计。 用户报告目标稳定而本插件闪烁。新目标2.4.0的静态REA复核发现瘦脸单主要人脸改走 pin-style 筛选与保持,条件可达连续对象框跟踪。现有旧版自动跟随报告不能作为该新版主路径完全对齐的依据。直接链接当前产品源码的合成探针确认:76点完整/缺失/完整使变形通道85835/0/85835;纯框抖动输出/输入振幅比1;先请求40ms空帧、再补0ms有效脸后,缓存40ms仍空,与顺序请求不同;默认外观蒙版在几何保持时可清零。这些均为合成诊断,不是用户素材或目标运行统计。
见 analysis/跟踪闪烁对齐分析.md 和同目录 tracking-flicker-20261022;诊断入口 `zsh scripts/diagnose-tracking.sh`。产品源码与正式1.3.2保持相同,未构建APP、未安装、未重发PKG或文章。用户随后确认当前FCP草帽人物素材,已定位源文件,连续帧核对进行中;原1901项回归不代表连续跟踪稳定性已通过。 见 analysis/跟踪闪烁对齐分析.md 和同目录 tracking-flicker-20261022;诊断入口 `zsh scripts/diagnose-tracking.sh`。产品源码与正式1.3.2保持相同,未构建APP、未安装、未重发PKG或文章。已定位当前FCP草帽素材并以项目25fps独立扫描469帧,全部单脸/完整76点、无held/错误,未复现缺点归零;源5.72秒轮廓步幅raw6.33%、稳定后5.24%,仍含真实头动。原生请求与大眼叠加贡献未分离;原1901项回归不代表连续跟踪稳定性已通过。
+109
查看文件
@@ -0,0 +1,109 @@
// Offline diagnostics: actual detector/tracker, scalar statistics only.
// No image, full landmark array, host edit, or reference execution is produced.
#import <AVFoundation/AVFoundation.h>
#import "../FCP-BeautyGirl/FCP-BeautyGirl/Plugin/PGFaceProcessor.m"
static double ShapeRMS(NSDictionary *a, NSDictionary *b, NSUInteger first, NSUInteger last) {
NSArray *x=a[@"points76"], *y=b[@"points76"];
if(x.count!=76 || y.count!=76) return NAN;
CGRect old=PGArrayRect(a[@"box"]), current=PGArrayRect(b[@"box"]);
if(!PGValidRect(old)||!PGValidRect(current)) return NAN;
double sum=0;
for(NSUInteger i=first;i<=last;i++) {
CGPoint p=PGRemapPoint(x[i],old,current);
double dx=(p.x-[y[i][0] doubleValue])/current.size.width;
double dy=(p.y-[y[i][1] doubleValue])/current.size.height;
sum+=dx*dx+dy*dy;
}
return sqrt(sum/(last-first+1));
}
static id NumberOrNull(double x) {return isfinite(x)?@(x):NSNull.null;}
static double EyeRMS(NSDictionary *a, NSDictionary *b) {
CGRect old=PGArrayRect(a[@"box"]), current=PGArrayRect(b[@"box"]);
if(!PGValidRect(old)||!PGValidRect(current))return NAN;
double sum=0;NSUInteger n=0;
for(NSString *key in @[@"leftEye",@"rightEye"]) {
NSArray *x=a[key],*y=b[key];if(!x.count||x.count!=y.count)return NAN;
for(NSUInteger i=0;i<x.count;i++) {
CGPoint p=PGRemapPoint(x[i],old,current);
double dx=(p.x-[y[i][0] doubleValue])/current.size.width;
double dy=(p.y-[y[i][1] doubleValue])/current.size.height;
sum+=dx*dx+dy*dy;n++;
}
}
return n?sqrt(sum/n):NAN;
}
int main(int argc,const char *argv[]) {@autoreleasepool {
if(argc!=6) {fprintf(stderr,"usage: inspect-tracking-sequence <video> <output.json> <fps> <decode-longest> <timeline-offset-seconds>\n");return 2;}
NSString *path=@(argv[1]), *output=@(argv[2]);
int fps=atoi(argv[3]), longest=atoi(argv[4]);double offset=atof(argv[5]);
if(fps<1||fps>120||longest<128||longest>4096||!isfinite(offset))return 2;
AVURLAsset *asset=[AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:path] options:nil];
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
double duration=CMTimeGetSeconds(asset.duration);
AVAssetTrack *video=[[asset tracksWithMediaType:AVMediaTypeVideo] firstObject];
if(!video||!isfinite(duration)||duration<=0)return 2;
double nominal=video.nominalFrameRate;
AVAssetImageGenerator *generator=[[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.appliesPreferredTrackTransform=YES;generator.maximumSize=CGSizeMake(longest,longest);
generator.requestedTimeToleranceBefore=kCMTimeZero;generator.requestedTimeToleranceAfter=kCMTimeZero;
PGFaceProcessor *detector=[PGFaceProcessor new];PGRealtimeFaceTracker *tracker=[PGRealtimeFaceTracker new];
PGBeautySettings settings=PGBeautyDefaults();settings.singleFace=0;settings.trackingEnabled=0;
settings.fastMultiFace=0;settings.faceThin=1;settings.faceBigEye=.9035486629353234;
NSMutableArray *rows=[NSMutableArray new];NSDictionary *priorRaw=nil,*priorOutput=nil;
NSUInteger empty=0,partial=0,held=0,low=0,errors=0,multiple=0,invalidOutput=0,duplicateSourceFrames=0;
CMTime previousActual=kCMTimeInvalid;NSUInteger width=0,height=0;
for(int frame=0;frame<(int)ceil(duration*fps);frame++) {@autoreleasepool {
double requested=(double)frame/fps;if(requested>=duration)break;
NSError *error=nil;CMTime actual=kCMTimeInvalid;
CGImageRef cg=[generator copyCGImageAtTime:CMTimeMakeWithSeconds(requested,60000) actualTime:&actual error:&error];
if(!cg){errors++;fprintf(stderr,"decode failed at %.3f: %s\n",requested,error.localizedDescription.UTF8String);continue;}
if(CMTIME_IS_VALID(previousActual)&&CMTimeCompare(previousActual,actual)==0)duplicateSourceFrames++;
previousActual=actual;width=CGImageGetWidth(cg);height=CGImageGetHeight(cg);
CIImage *image=[CIImage imageWithCGImage:cg];
NSArray<VNFaceObservation *> *observations=[detector observationsInImage:image settings:settings error:&error];
if(!observations)errors++;
NSMutableArray *raw=[NSMutableArray new],*faces=[NSMutableArray new];
for(VNFaceObservation *face in observations)if(PGValidRect(face.boundingBox)&&raw.count<16){[raw addObject:PGGeometry(face)];[faces addObject:face];}
CMTime time=CMTimeAdd(CMTimeMake(frame,fps),CMTimeMakeWithSeconds(offset,60000));
NSDictionary *r=[tracker resultForGeometry:raw settings:settings time:time extent:image.extent];
NSInteger index=[r[@"index"] integerValue];NSDictionary *current=(index>=0&&(NSUInteger)index<raw.count)?raw[index]:nil;
VNFaceObservation *face=(index>=0&&(NSUInteger)index<faces.count)?faces[index]:nil;
NSDictionary *stable=[r[@"output"] firstObject];
double confidence=face.landmarks?face.landmarks.confidence:NAN;
if(!raw.count)empty++;if(raw.count>1)multiple++;
if(current&&[current[@"points76"] count]!=76)partial++;
if(stable&&[stable[@"points76"] count]!=76)invalidOutput++;
if([r[@"held"] boolValue])held++;
if(isfinite(confidence)&&confidence<.55)low++;
CGRect old=PGArrayRect(priorRaw[@"box"]),box=PGArrayRect(current[@"box"]);
double centerStep=NAN,sizeStep=NAN;
if(PGValidRect(old)&&PGValidRect(box)){
centerStep=hypot(CGRectGetMidX(old)-CGRectGetMidX(box),CGRectGetMidY(old)-CGRectGetMidY(box));
sizeStep=MAX(fabs(box.size.width/old.size.width-1),fabs(box.size.height/old.size.height-1));
}
NSMutableDictionary *row=[@{@"frame":@(frame),@"requestedSeconds":@(requested),@"actualSeconds":@(CMTimeGetSeconds(actual)),
@"faceCount":@(raw.count),@"points76Count":@([current[@"points76"] count]),@"held":r[@"held"],
@"landmarkConfidence":NumberOrNull(confidence),@"faceConfidence":NumberOrNull(face?face.confidence:NAN),
@"rawContourShapeStep":NumberOrNull(ShapeRMS(priorRaw,current,59,75)),
@"outputContourShapeStep":NumberOrNull(ShapeRMS(priorOutput,stable,59,75)),
@"rawAllShapeStep":NumberOrNull(ShapeRMS(priorRaw,current,0,75)),
@"outputAllShapeStep":NumberOrNull(ShapeRMS(priorOutput,stable,0,75)),
@"rawEyeShapeStep":NumberOrNull(EyeRMS(priorRaw,current)),
@"bboxCenterStep":NumberOrNull(centerStep),@"bboxRelativeSizeStep":NumberOrNull(sizeStep)} mutableCopy];
[rows addObject:row];priorRaw=current;priorOutput=stable;CGImageRelease(cg);
if(frame%50==0)fprintf(stderr,"inspected %d/%d frames\n",frame,(int)ceil(duration*fps));
}}
#pragma clang diagnostic pop
NSArray *keys=@[@"rawContourShapeStep",@"outputContourShapeStep",@"rawAllShapeStep",@"outputAllShapeStep",@"rawEyeShapeStep",@"bboxCenterStep",@"bboxRelativeSizeStep",@"landmarkConfidence"];
NSMutableDictionary *stats=[NSMutableDictionary new];
for(NSString *key in keys){NSMutableArray *values=[NSMutableArray new];for(NSDictionary *row in rows)if([row[key] isKindOfClass:NSNumber.class])[values addObject:row[key]];[values sortUsingSelector:@selector(compare:)];if(values.count){stats[key]=@{@"n":@(values.count),@"min":values.firstObject,@"median":values[values.count/2],@"p95":values[(NSUInteger)floor((values.count-1)*.95)],@"max":values.lastObject};}}
NSArray *ranked=[rows sortedArrayUsingComparator:^NSComparisonResult(NSDictionary *a,NSDictionary *b){double x=[a[@"rawContourShapeStep"] isKindOfClass:NSNumber.class]?[a[@"rawContourShapeStep"] doubleValue]:-1;double y=[b[@"rawContourShapeStep"] isKindOfClass:NSNumber.class]?[b[@"rawContourShapeStep"] doubleValue]:-1;return x>y?NSOrderedAscending:(x<y?NSOrderedDescending:NSOrderedSame);}];
NSDictionary *summary=@{@"sourceBasename":path.lastPathComponent,@"durationSeconds":@(duration),@"nominalSourceFPS":@(nominal),@"samplingFPS":@(fps),@"decodedSize":@[@(width),@(height)],@"timelineOffsetSeconds":@(offset),@"frames":@(rows.count),@"emptyDetectionFrames":@(empty),@"partial76Frames":@(partial),@"heldFrames":@(held),@"outputWithout76Frames":@(invalidOutput),@"landmarkConfidenceBelow055Frames":@(low),@"multipleFaceFrames":@(multiple),@"decodeOrVisionErrors":@(errors),@"duplicateSourceFramePairs":@(duplicateSourceFrames),@"statistics":stats,@"largestContourChanges":[ranked subarrayWithRange:NSMakeRange(0,MIN(12,ranked.count))],@"scope":@"Independent offline decoding and the current production detector/tracker; not FCP render logs or target execution. Shape steps remove previous bbox translation/scale, but still include actual pose/expression changes."};
NSDictionary *report=@{@"summary":summary,@"scalarFrames":rows};NSData *data=[NSJSONSerialization dataWithJSONObject:report options:NSJSONWritingPrettyPrinted|NSJSONWritingSortedKeys error:nil];
if(!data||![data writeToFile:output atomically:YES])return 1;
NSData *print=[NSJSONSerialization dataWithJSONObject:summary options:NSJSONWritingPrettyPrinted|NSJSONWritingSortedKeys error:nil];fwrite(print.bytes,1,print.length,stdout);fputc('\n',stdout);
return 0;
}}