@pilio/gemini-watermark-remover 1.0.31 → 1.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/video-app.js +1 -1
- package/package.json +1 -1
- package/src/core/adaptiveDetector.js +57 -13
- package/src/core/candidateSelector.js +64 -6
- package/src/core/geminiSizeCatalog.js +0 -1
- package/src/core/imageWatermarkPipeline.js +98 -3
- package/src/core/pipelineAcceptedExecutor.js +9 -5
- package/src/core/pipelineAlphaStageSpecs.js +81 -0
- package/src/core/pipelineAlphaTraceContract.js +3 -1
- package/src/core/pipelineAlphaTrial.js +98 -15
- package/src/core/pipelineCandidateQuality.js +49 -9
- package/src/core/pipelineFinalization.js +17 -9
- package/src/core/pipelineInitialSelection.js +596 -14
- package/src/core/pipelineMeta.js +37 -11
- package/src/core/pipelineRepairStageSpecs.js +4 -0
- package/src/core/pipelineRuntime.js +23 -2
- package/src/core/previewAlphaCalibration.js +6 -3
- package/src/core/restorationMetrics.js +214 -23
- package/src/core/watermarkProcessor.js +1412 -103
- package/src/shared/pageImageReplacement.js +2 -8
package/dist/video-app.js
CHANGED
package/package.json
CHANGED
|
@@ -196,6 +196,52 @@ export function computeSizeAdjustedConfidence(confidence, size, referenceSize =
|
|
|
196
196
|
return confidence * sizeWeight;
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
+
function compareAdaptiveCandidatePriority(left, right) {
|
|
200
|
+
const leftScore = Number.isFinite(left?.adjustedScore)
|
|
201
|
+
? left.adjustedScore
|
|
202
|
+
: computeSizeAdjustedConfidence(left?.confidence, left?.size);
|
|
203
|
+
const rightScore = Number.isFinite(right?.adjustedScore)
|
|
204
|
+
? right.adjustedScore
|
|
205
|
+
: computeSizeAdjustedConfidence(right?.confidence, right?.size);
|
|
206
|
+
if (Math.abs(leftScore - rightScore) > 1e-12) {
|
|
207
|
+
return leftScore - rightScore;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const leftSize = Number.isFinite(left?.size) ? left.size : 0;
|
|
211
|
+
const rightSize = Number.isFinite(right?.size) ? right.size : 0;
|
|
212
|
+
const leftDistance = Math.abs(leftSize - REFERENCE_WATERMARK_SIZE);
|
|
213
|
+
const rightDistance = Math.abs(rightSize - REFERENCE_WATERMARK_SIZE);
|
|
214
|
+
if (leftDistance !== rightDistance) {
|
|
215
|
+
return rightDistance - leftDistance;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const leftConfidence = Number.isFinite(left?.confidence) ? left.confidence : 0;
|
|
219
|
+
const rightConfidence = Number.isFinite(right?.confidence) ? right.confidence : 0;
|
|
220
|
+
if (leftConfidence !== rightConfidence) {
|
|
221
|
+
return leftConfidence - rightConfidence;
|
|
222
|
+
}
|
|
223
|
+
if (leftSize !== rightSize) {
|
|
224
|
+
return leftSize - rightSize;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const leftX = Number.isFinite(left?.x) ? left.x : Infinity;
|
|
228
|
+
const rightX = Number.isFinite(right?.x) ? right.x : Infinity;
|
|
229
|
+
if (leftX !== rightX) {
|
|
230
|
+
return rightX - leftX;
|
|
231
|
+
}
|
|
232
|
+
const leftY = Number.isFinite(left?.y) ? left.y : Infinity;
|
|
233
|
+
const rightY = Number.isFinite(right?.y) ? right.y : Infinity;
|
|
234
|
+
return rightY - leftY;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export function selectAdaptiveFineCandidate(currentBest, candidate) {
|
|
238
|
+
if (!currentBest) return candidate;
|
|
239
|
+
if (!candidate) return currentBest;
|
|
240
|
+
return compareAdaptiveCandidatePriority(candidate, currentBest) > 0
|
|
241
|
+
? candidate
|
|
242
|
+
: currentBest;
|
|
243
|
+
}
|
|
244
|
+
|
|
199
245
|
function buildSeedConfigs(width, height, defaultConfig) {
|
|
200
246
|
// Start adaptive search from both the coarse default anchor and any
|
|
201
247
|
// catalog-projected anchors for official or near-official Gemini sizes.
|
|
@@ -445,10 +491,10 @@ export function detectAdaptiveWatermarkRegion({
|
|
|
445
491
|
})
|
|
446
492
|
.filter(Boolean);
|
|
447
493
|
|
|
448
|
-
const bestSeed = seedCandidates.reduce(
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
494
|
+
const bestSeed = seedCandidates.reduce(
|
|
495
|
+
(best, candidate) => selectAdaptiveFineCandidate(best, candidate),
|
|
496
|
+
null
|
|
497
|
+
);
|
|
452
498
|
if (bestSeed && bestSeed.confidence >= threshold + 0.08) {
|
|
453
499
|
return {
|
|
454
500
|
found: true,
|
|
@@ -483,7 +529,7 @@ export function detectAdaptiveWatermarkRegion({
|
|
|
483
529
|
const topK = [];
|
|
484
530
|
const pushTopK = (candidate) => {
|
|
485
531
|
topK.push(candidate);
|
|
486
|
-
topK.sort((
|
|
532
|
+
topK.sort((left, right) => -compareAdaptiveCandidatePriority(left, right));
|
|
487
533
|
if (topK.length > 5) topK.length = 5;
|
|
488
534
|
};
|
|
489
535
|
|
|
@@ -545,14 +591,12 @@ export function detectAdaptiveWatermarkRegion({
|
|
|
545
591
|
const score = scoreCandidate(context, tpl.alpha, tpl.grad, { x, y, size });
|
|
546
592
|
if (!score) continue;
|
|
547
593
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
};
|
|
555
|
-
}
|
|
594
|
+
best = selectAdaptiveFineCandidate(best, {
|
|
595
|
+
x,
|
|
596
|
+
y,
|
|
597
|
+
size,
|
|
598
|
+
...score
|
|
599
|
+
});
|
|
556
600
|
}
|
|
557
601
|
}
|
|
558
602
|
}
|
|
@@ -137,6 +137,8 @@ const BOTTOM_RIGHT_48_EVIDENCE_DOMINANCE_GRADIENT_ADVANTAGE = 0.12;
|
|
|
137
137
|
const BOTTOM_RIGHT_48_EVIDENCE_DOMINANCE_MAX_RESIDUAL_DELTA = 0.08;
|
|
138
138
|
const DARK_POLARITY_CATALOG_MIN_ORIGINAL_SPATIAL = 0.12;
|
|
139
139
|
const DARK_POLARITY_CATALOG_MIN_ORIGINAL_GRADIENT = 0.08;
|
|
140
|
+
const DARK_POLARITY_48_MIN_ORIGINAL_SPATIAL = 0.6;
|
|
141
|
+
const DARK_POLARITY_48_MIN_ORIGINAL_GRADIENT = 0.3;
|
|
140
142
|
const DARK_POLARITY_CATALOG_MAX_TEXTURE_FOR_WEAK_EVIDENCE = 0.25;
|
|
141
143
|
const DARK_POLARITY_MAX_NEAR_WHITE_RATIO_INCREASE_FOR_WEAK_EVIDENCE = 0.05;
|
|
142
144
|
const DARK_POLARITY_NEAR_WHITE_OVERRIDE_MIN_ORIGINAL_SPATIAL = 0.4;
|
|
@@ -183,6 +185,7 @@ const PREVIEW_ANCHOR_GAIN_SKIP_RESIDUAL_THRESHOLD = 0.24;
|
|
|
183
185
|
const PREVIEW_ANCHOR_GAIN_SKIP_GRADIENT_THRESHOLD = 0.24;
|
|
184
186
|
const CORE_ALPHA_PRIORITY_GAINS = Object.freeze([0.6, 1, 1.1, 1.15, 1.3, 0.45, 0.7, 0.85, 0.55]);
|
|
185
187
|
const CURRENT_LARGE_MARGIN_ULTRA_WEAK_ALPHA_GAINS = Object.freeze([0.25, 0.3, 0.35, 0.4]);
|
|
188
|
+
const DARK_POLARITY_48_ULTRA_WEAK_ALPHA_GAINS = Object.freeze([0.08, 0.1, 0.12, 0.15, 0.2]);
|
|
186
189
|
const STANDARD_ANCHOR_WEAK_ALPHA_RESCUE_GAINS = Object.freeze([0.55, 0.7, 0.85]);
|
|
187
190
|
const STANDARD_ANCHOR_WEAK_RESCUE_MAX_SPATIAL = 0.35;
|
|
188
191
|
const STANDARD_ANCHOR_WEAK_RESCUE_MAX_GRADIENT = 0.24;
|
|
@@ -393,13 +396,17 @@ function buildStandardCandidateSeeds({
|
|
|
393
396
|
}
|
|
394
397
|
|
|
395
398
|
if (shouldAddDarkPolaritySeed(candidateConfig)) {
|
|
399
|
+
const weakDarkPolarity48 = candidateConfig.logoSize === 48;
|
|
396
400
|
seeds.push({
|
|
397
401
|
...baseSeed,
|
|
398
402
|
alphaMap: createNegativeAlphaMap(alphaMap),
|
|
399
403
|
source: `${baseSeed.source}+dark-polarity`,
|
|
400
404
|
provenance: mergeCandidateProvenance(
|
|
401
405
|
baseSeed.provenance,
|
|
402
|
-
{
|
|
406
|
+
{
|
|
407
|
+
darkPolarity: true,
|
|
408
|
+
...(weakDarkPolarity48 ? { weakDarkPolarity48: true } : {})
|
|
409
|
+
}
|
|
403
410
|
)
|
|
404
411
|
});
|
|
405
412
|
}
|
|
@@ -409,9 +416,19 @@ function buildStandardCandidateSeeds({
|
|
|
409
416
|
}
|
|
410
417
|
|
|
411
418
|
function shouldAddDarkPolaritySeed(config) {
|
|
412
|
-
|
|
419
|
+
if (
|
|
420
|
+
config?.logoSize === 96 &&
|
|
413
421
|
config.marginRight === 192 &&
|
|
414
|
-
config.marginBottom === 192
|
|
422
|
+
config.marginBottom === 192
|
|
423
|
+
) {
|
|
424
|
+
return true;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
return config?.logoSize === 48 &&
|
|
428
|
+
config.marginRight >= 90 &&
|
|
429
|
+
config.marginRight <= 100 &&
|
|
430
|
+
config.marginBottom >= 90 &&
|
|
431
|
+
config.marginBottom <= 100;
|
|
415
432
|
}
|
|
416
433
|
|
|
417
434
|
const negativeAlphaMapCache = new WeakMap();
|
|
@@ -659,7 +676,15 @@ function isWeakAlphaPrioritySeed(seed) {
|
|
|
659
676
|
seed.config.marginBottom === 96;
|
|
660
677
|
}
|
|
661
678
|
|
|
679
|
+
function isWeakDarkPolarity48Seed(seed) {
|
|
680
|
+
return seed?.provenance?.weakDarkPolarity48 === true;
|
|
681
|
+
}
|
|
682
|
+
|
|
662
683
|
function resolveStandardSeedAlphaPriorityGains(seed, alphaPriorityGains) {
|
|
684
|
+
if (isWeakDarkPolarity48Seed(seed)) {
|
|
685
|
+
return DARK_POLARITY_48_ULTRA_WEAK_ALPHA_GAINS;
|
|
686
|
+
}
|
|
687
|
+
|
|
663
688
|
const extras = isWeakAlphaPrioritySeed(seed)
|
|
664
689
|
? [
|
|
665
690
|
...CURRENT_LARGE_MARGIN_ULTRA_WEAK_ALPHA_GAINS,
|
|
@@ -874,7 +899,7 @@ function evaluateStandardTrialForSeed({
|
|
|
874
899
|
}
|
|
875
900
|
}
|
|
876
901
|
|
|
877
|
-
|
|
902
|
+
const selected = isWeakAlphaPrioritySeed(seed)
|
|
878
903
|
? bestWeakAlphaPriorityTrial ?? bestWeakAlphaRescueTrial ?? bestAcceptedTrial ?? fallbackTrial
|
|
879
904
|
: bestWeakAlphaPriorityTrial ??
|
|
880
905
|
(
|
|
@@ -884,6 +909,10 @@ function evaluateStandardTrialForSeed({
|
|
|
884
909
|
) ??
|
|
885
910
|
bestWeakAlphaRescueTrial ??
|
|
886
911
|
fallbackTrial;
|
|
912
|
+
|
|
913
|
+
return isWeakDarkPolarity48Seed(seed) && selected?.accepted !== true
|
|
914
|
+
? null
|
|
915
|
+
: selected;
|
|
887
916
|
}
|
|
888
917
|
|
|
889
918
|
export function evaluateRestorationCandidate({
|
|
@@ -1011,11 +1040,40 @@ export function evaluateRestorationCandidate({
|
|
|
1011
1040
|
const strongDarkPolarityOriginalEvidence =
|
|
1012
1041
|
originalScores.spatialScore >= DARK_POLARITY_CATALOG_MIN_ORIGINAL_SPATIAL ||
|
|
1013
1042
|
originalScores.gradientScore >= DARK_POLARITY_CATALOG_MIN_ORIGINAL_GRADIENT;
|
|
1043
|
+
const isLargeMargin48DarkPolarity =
|
|
1044
|
+
provenance?.darkPolarity === true &&
|
|
1045
|
+
config?.logoSize === 48 &&
|
|
1046
|
+
config.marginRight >= 90 &&
|
|
1047
|
+
config.marginRight <= 100 &&
|
|
1048
|
+
config.marginBottom >= 90 &&
|
|
1049
|
+
config.marginBottom <= 100;
|
|
1050
|
+
const largeMargin48DarkPolarityEvidenceAllowed =
|
|
1051
|
+
!isLargeMargin48DarkPolarity ||
|
|
1052
|
+
(
|
|
1053
|
+
originalScores.spatialScore >= DARK_POLARITY_48_MIN_ORIGINAL_SPATIAL &&
|
|
1054
|
+
originalScores.gradientScore >= DARK_POLARITY_48_MIN_ORIGINAL_GRADIENT
|
|
1055
|
+
);
|
|
1056
|
+
const weakDarkPolarity48ScopeAllowed =
|
|
1057
|
+
provenance?.weakDarkPolarity48 !== true ||
|
|
1058
|
+
(
|
|
1059
|
+
config?.logoSize === 48 &&
|
|
1060
|
+
config.marginRight >= 90 &&
|
|
1061
|
+
config.marginRight <= 100 &&
|
|
1062
|
+
config.marginBottom >= 90 &&
|
|
1063
|
+
config.marginBottom <= 100 &&
|
|
1064
|
+
alphaGain <= 0.2
|
|
1065
|
+
);
|
|
1014
1066
|
const darkPolarityCatalogEvidenceAllowed =
|
|
1015
1067
|
provenance?.darkPolarity !== true ||
|
|
1016
1068
|
provenance?.catalogVariant !== true ||
|
|
1017
|
-
|
|
1018
|
-
|
|
1069
|
+
(
|
|
1070
|
+
weakDarkPolarity48ScopeAllowed &&
|
|
1071
|
+
largeMargin48DarkPolarityEvidenceAllowed &&
|
|
1072
|
+
(
|
|
1073
|
+
strongDarkPolarityOriginalEvidence ||
|
|
1074
|
+
texturePenalty <= DARK_POLARITY_CATALOG_MAX_TEXTURE_FOR_WEAK_EVIDENCE
|
|
1075
|
+
)
|
|
1076
|
+
);
|
|
1019
1077
|
const strongDarkPolarityNearWhiteOverrideEvidence =
|
|
1020
1078
|
originalScores.spatialScore >= DARK_POLARITY_NEAR_WHITE_OVERRIDE_MIN_ORIGINAL_SPATIAL ||
|
|
1021
1079
|
originalScores.gradientScore >= DARK_POLARITY_NEAR_WHITE_OVERRIDE_MIN_ORIGINAL_GRADIENT;
|
|
@@ -27,6 +27,14 @@ function createSelectedCandidate(best) {
|
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
function findDarkBackgroundSupportConvergence(meta = {}) {
|
|
31
|
+
const stages = Array.isArray(meta.alphaAdjustmentStages)
|
|
32
|
+
? meta.alphaAdjustmentStages
|
|
33
|
+
: [];
|
|
34
|
+
const convergence = stages.at(-1)?.darkBackgroundSupportConvergence;
|
|
35
|
+
return convergence?.accepted === true ? convergence : null;
|
|
36
|
+
}
|
|
37
|
+
|
|
30
38
|
function createRuntimeFailureResult({
|
|
31
39
|
createRejectedResult,
|
|
32
40
|
originalImageData,
|
|
@@ -42,6 +50,26 @@ function createRuntimeFailureResult({
|
|
|
42
50
|
});
|
|
43
51
|
}
|
|
44
52
|
|
|
53
|
+
function createNoWatermarkResult({
|
|
54
|
+
createRejectedResult,
|
|
55
|
+
originalImageData,
|
|
56
|
+
collection,
|
|
57
|
+
debugTimings
|
|
58
|
+
}) {
|
|
59
|
+
const selection = collection?.automaticSelection ?? collection?.fixedSelection ?? {};
|
|
60
|
+
return createRejectedResult({
|
|
61
|
+
imageData: originalImageData,
|
|
62
|
+
debugTimings,
|
|
63
|
+
reason: 'no-watermark-detected',
|
|
64
|
+
adaptiveConfidence: selection.adaptiveConfidence ?? null,
|
|
65
|
+
originalSpatialScore: selection.standardSpatialScore ?? null,
|
|
66
|
+
originalGradientScore: selection.standardGradientScore ?? null,
|
|
67
|
+
source: 'skipped',
|
|
68
|
+
decisionTier: selection.decisionTier ?? 'insufficient',
|
|
69
|
+
selectionDebug: null
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
45
73
|
function notifyCandidateCompleted({ options, candidate, debugTimings }) {
|
|
46
74
|
if (typeof options?.onCandidateCompleted !== 'function') return;
|
|
47
75
|
|
|
@@ -55,6 +83,41 @@ function notifyCandidateCompleted({ options, candidate, debugTimings }) {
|
|
|
55
83
|
}
|
|
56
84
|
}
|
|
57
85
|
|
|
86
|
+
function appendUniqueRiskFlag(flags, flag) {
|
|
87
|
+
const normalized = Array.isArray(flags) ? flags : [];
|
|
88
|
+
return normalized.includes(flag) ? normalized : [...normalized, flag];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function attachPresenceBestEffortMeta(meta, collection) {
|
|
92
|
+
if (collection?.bestEffortFallback !== true) return meta;
|
|
93
|
+
|
|
94
|
+
const riskFlag = 'unconfirmed-watermark-presence';
|
|
95
|
+
const decisionPath = meta?.decisionPath && typeof meta.decisionPath === 'object'
|
|
96
|
+
? {
|
|
97
|
+
...meta.decisionPath,
|
|
98
|
+
riskFlags: appendUniqueRiskFlag(meta.decisionPath.riskFlags, riskFlag),
|
|
99
|
+
evaluation: meta.decisionPath.evaluation &&
|
|
100
|
+
typeof meta.decisionPath.evaluation === 'object'
|
|
101
|
+
? {
|
|
102
|
+
...meta.decisionPath.evaluation,
|
|
103
|
+
riskFlags: appendUniqueRiskFlag(
|
|
104
|
+
meta.decisionPath.evaluation.riskFlags,
|
|
105
|
+
riskFlag
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
: meta.decisionPath.evaluation
|
|
109
|
+
}
|
|
110
|
+
: meta?.decisionPath;
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
...meta,
|
|
114
|
+
presenceConfirmed: false,
|
|
115
|
+
bestEffortReason:
|
|
116
|
+
collection.bestEffortReason ?? 'presence-witness-unconfirmed',
|
|
117
|
+
decisionPath
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
58
121
|
export function runImageWatermarkPipeline({
|
|
59
122
|
imageData,
|
|
60
123
|
options = {},
|
|
@@ -119,6 +182,26 @@ export function runImageWatermarkPipeline({
|
|
|
119
182
|
debugTimings.generatedCandidateCount = hypotheses.length;
|
|
120
183
|
debugTimings.earlyExitReason = null;
|
|
121
184
|
}
|
|
185
|
+
if (
|
|
186
|
+
collection?.presenceConfirmed === false &&
|
|
187
|
+
collection?.bestEffortFallback !== true
|
|
188
|
+
) {
|
|
189
|
+
if (debugTimingsEnabled) {
|
|
190
|
+
debugTimings.candidateExecutionMs = 0;
|
|
191
|
+
debugTimings.executedCandidateCount = 0;
|
|
192
|
+
debugTimings.completedCandidateCount = 0;
|
|
193
|
+
debugTimings.failedCandidateCount = 0;
|
|
194
|
+
debugTimings.candidateRankingMs = 0;
|
|
195
|
+
debugTimings.earlyExitReason = 'no-watermark-detected';
|
|
196
|
+
debugTimings.totalMs = nowMs() - totalStartedAt;
|
|
197
|
+
}
|
|
198
|
+
return createNoWatermarkResult({
|
|
199
|
+
createRejectedResult,
|
|
200
|
+
originalImageData,
|
|
201
|
+
collection,
|
|
202
|
+
debugTimings
|
|
203
|
+
});
|
|
204
|
+
}
|
|
122
205
|
|
|
123
206
|
const completed = [];
|
|
124
207
|
const failures = [];
|
|
@@ -135,7 +218,9 @@ export function runImageWatermarkPipeline({
|
|
|
135
218
|
debugTimingsEnabled,
|
|
136
219
|
visualPostProcessingEnabled,
|
|
137
220
|
cleanupConfig,
|
|
138
|
-
createAcceptedPipelineDependencies
|
|
221
|
+
createAcceptedPipelineDependencies: () => (
|
|
222
|
+
createAcceptedPipelineDependencies(hypothesis)
|
|
223
|
+
),
|
|
139
224
|
runAcceptedPipeline,
|
|
140
225
|
createAcceptedFinalResult
|
|
141
226
|
});
|
|
@@ -148,7 +233,16 @@ export function runImageWatermarkPipeline({
|
|
|
148
233
|
qualitySignals: measureCandidate({
|
|
149
234
|
originalImageData,
|
|
150
235
|
candidateImageData: completedCandidate.result.imageData,
|
|
151
|
-
hypothesis
|
|
236
|
+
hypothesis,
|
|
237
|
+
finalCandidate: {
|
|
238
|
+
position: completedCandidate.pipelineState?.position,
|
|
239
|
+
alphaMap: completedCandidate.pipelineState?.alphaMap,
|
|
240
|
+
alphaGain: completedCandidate.pipelineState?.alphaGain,
|
|
241
|
+
darkBackgroundSupportConvergence:
|
|
242
|
+
findDarkBackgroundSupportConvergence(
|
|
243
|
+
completedCandidate.result.meta
|
|
244
|
+
)
|
|
245
|
+
}
|
|
152
246
|
})
|
|
153
247
|
};
|
|
154
248
|
completed.push(candidate);
|
|
@@ -197,13 +291,14 @@ export function runImageWatermarkPipeline({
|
|
|
197
291
|
}
|
|
198
292
|
|
|
199
293
|
const candidateSummaries = createSummaries(ranked, failures);
|
|
200
|
-
const
|
|
294
|
+
const selectionMeta = attachSelectionMeta(best.result.meta, {
|
|
201
295
|
qualityStatus: best.qualitySignals?.qualityStatus,
|
|
202
296
|
selectionConfidence: best.selectionConfidence,
|
|
203
297
|
selectedCandidate: createSelectedCandidate(best),
|
|
204
298
|
qualitySignals: best.qualitySignals,
|
|
205
299
|
candidateSummaries
|
|
206
300
|
});
|
|
301
|
+
const meta = attachPresenceBestEffortMeta(selectionMeta, collection);
|
|
207
302
|
if (debugTimingsEnabled) {
|
|
208
303
|
debugTimings.candidateRankingMs = nowMs() - rankingStartedAt;
|
|
209
304
|
debugTimings.totalMs = nowMs() - totalStartedAt;
|
|
@@ -96,11 +96,15 @@ export function runAcceptedAlphaRepairPipeline({
|
|
|
96
96
|
originalGradientScore: current.originalGradientScore,
|
|
97
97
|
calculateNearBlackRatio: metrics.calculateNearBlackRatio,
|
|
98
98
|
acceptCurrentAlphaTrialResult,
|
|
99
|
-
debugTimings,
|
|
100
|
-
debugTimingsEnabled,
|
|
101
|
-
refiners: {
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
debugTimings,
|
|
100
|
+
debugTimingsEnabled,
|
|
101
|
+
refiners: {
|
|
102
|
+
refineLargeMargin48ProfileAlphaRescue:
|
|
103
|
+
refiners.refineLargeMargin48ProfileAlphaRescue,
|
|
104
|
+
fineTuneEvidenceGatedLocalAlpha:
|
|
105
|
+
refiners.fineTuneEvidenceGatedLocalAlpha,
|
|
106
|
+
recalibrateOverSubtractedAlpha: refiners.recalibrateOverSubtractedAlpha,
|
|
107
|
+
fineTuneDarkCatalogAlpha: refiners.fineTuneDarkCatalogAlpha,
|
|
104
108
|
fineTuneWeakPositiveResidualAlpha: refiners.fineTuneWeakPositiveResidualAlpha
|
|
105
109
|
}
|
|
106
110
|
});
|
|
@@ -27,12 +27,92 @@ export function createFineAlphaTrialSequenceSpecs({
|
|
|
27
27
|
refiners = {}
|
|
28
28
|
} = {}) {
|
|
29
29
|
const {
|
|
30
|
+
refineLargeMargin48ProfileAlphaRescue,
|
|
31
|
+
fineTuneEvidenceGatedLocalAlpha,
|
|
30
32
|
recalibrateOverSubtractedAlpha,
|
|
31
33
|
fineTuneDarkCatalogAlpha,
|
|
32
34
|
fineTuneWeakPositiveResidualAlpha
|
|
33
35
|
} = refiners;
|
|
34
36
|
|
|
37
|
+
const evidenceGatedStages = [];
|
|
38
|
+
if (typeof refineLargeMargin48ProfileAlphaRescue === 'function') {
|
|
39
|
+
evidenceGatedStages.push({
|
|
40
|
+
stage: 'large-margin-48-profile-alpha-rescue',
|
|
41
|
+
strategy: 'large-margin-48-profile-alpha',
|
|
42
|
+
createTrial: () => {
|
|
43
|
+
const state = readPipelineAlphaState(readState);
|
|
44
|
+
return typeof refineLargeMargin48ProfileAlphaRescue === 'function'
|
|
45
|
+
? refineLargeMargin48ProfileAlphaRescue({
|
|
46
|
+
originalImageData,
|
|
47
|
+
currentImageData: state.finalImageData,
|
|
48
|
+
currentAlphaMap: state.alphaMap,
|
|
49
|
+
currentPosition: state.position,
|
|
50
|
+
currentConfig: state.config,
|
|
51
|
+
currentSpatialScore: state.finalProcessedSpatialScore,
|
|
52
|
+
currentGradientScore: state.finalProcessedGradientScore,
|
|
53
|
+
currentAlphaGain: state.alphaGain,
|
|
54
|
+
originalSpatialScore,
|
|
55
|
+
originalGradientScore
|
|
56
|
+
})
|
|
57
|
+
: null;
|
|
58
|
+
},
|
|
59
|
+
acceptCurrentAlphaTrialResult,
|
|
60
|
+
source: () => {
|
|
61
|
+
const source = readPipelineAlphaState(readState).source;
|
|
62
|
+
return source.includes('+profile-alpha-rescue')
|
|
63
|
+
? source
|
|
64
|
+
: `${source}+profile-alpha-rescue`;
|
|
65
|
+
},
|
|
66
|
+
stageExtras: (result) => ({
|
|
67
|
+
profileExponent: result.profileExponent
|
|
68
|
+
})
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
if (typeof fineTuneEvidenceGatedLocalAlpha === 'function') {
|
|
72
|
+
evidenceGatedStages.push({
|
|
73
|
+
stage: 'evidence-gated-local-alpha-search',
|
|
74
|
+
strategy: 'evidence-gated-local-alpha',
|
|
75
|
+
createTrial: () => {
|
|
76
|
+
const state = readPipelineAlphaState(readState);
|
|
77
|
+
return typeof fineTuneEvidenceGatedLocalAlpha === 'function'
|
|
78
|
+
? fineTuneEvidenceGatedLocalAlpha({
|
|
79
|
+
originalImageData,
|
|
80
|
+
currentImageData: state.finalImageData,
|
|
81
|
+
alphaMap: state.alphaMap,
|
|
82
|
+
position: state.position,
|
|
83
|
+
currentSpatialScore: state.finalProcessedSpatialScore,
|
|
84
|
+
currentGradientScore: state.finalProcessedGradientScore,
|
|
85
|
+
currentAlphaGain: state.alphaGain,
|
|
86
|
+
originalSpatialScore,
|
|
87
|
+
originalGradientScore,
|
|
88
|
+
originalNearBlackRatio: resolveNearBlackRatio({
|
|
89
|
+
calculateNearBlackRatio,
|
|
90
|
+
imageData: originalImageData,
|
|
91
|
+
position: state.position
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
: null;
|
|
95
|
+
},
|
|
96
|
+
acceptCurrentAlphaTrialResult,
|
|
97
|
+
source: () => {
|
|
98
|
+
const source = readPipelineAlphaState(readState).source;
|
|
99
|
+
return source.includes('+fine-alpha')
|
|
100
|
+
? source
|
|
101
|
+
: `${source}+fine-alpha`;
|
|
102
|
+
},
|
|
103
|
+
stageExtras: (result) => ({
|
|
104
|
+
localSearchTrigger: result.localSearchTrigger,
|
|
105
|
+
darkBackgroundSupportConvergence:
|
|
106
|
+
result.darkBackgroundSupportConvergence ?? null
|
|
107
|
+
}),
|
|
108
|
+
debugTimings,
|
|
109
|
+
timingKey: debugTimingsEnabled ? 'localAlphaSearchMs' : null,
|
|
110
|
+
nowMs
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
35
114
|
return [
|
|
115
|
+
...evidenceGatedStages,
|
|
36
116
|
{
|
|
37
117
|
stage: 'over-subtraction-recalibration',
|
|
38
118
|
strategy: 'over-subtraction-fine-alpha',
|
|
@@ -105,6 +185,7 @@ export function createFineAlphaTrialSequenceSpecs({
|
|
|
105
185
|
return typeof fineTuneWeakPositiveResidualAlpha === 'function'
|
|
106
186
|
? fineTuneWeakPositiveResidualAlpha({
|
|
107
187
|
originalImageData,
|
|
188
|
+
currentImageData: state.finalImageData,
|
|
108
189
|
alphaMap: state.alphaMap,
|
|
109
190
|
position: state.position,
|
|
110
191
|
currentSpatialScore: state.finalProcessedSpatialScore,
|
|
@@ -21,13 +21,15 @@ export function normalizeAlphaAdjustmentStageForTrace(stagePayload = {}) {
|
|
|
21
21
|
profileExponent = null,
|
|
22
22
|
alphaStrategy = null,
|
|
23
23
|
repairStrategy = null,
|
|
24
|
-
allowSameAlphaGain = false
|
|
24
|
+
allowSameAlphaGain = false,
|
|
25
|
+
...stageExtras
|
|
25
26
|
} = stagePayload;
|
|
26
27
|
|
|
27
28
|
if (!stage || !Number.isFinite(fromAlphaGain) || !Number.isFinite(toAlphaGain)) return null;
|
|
28
29
|
if (!allowSameAlphaGain && Math.abs(fromAlphaGain - toAlphaGain) < 0.0001) return null;
|
|
29
30
|
|
|
30
31
|
return {
|
|
32
|
+
...stageExtras,
|
|
31
33
|
stage,
|
|
32
34
|
fromAlphaGain,
|
|
33
35
|
toAlphaGain,
|