Зразки 1-3 описана Конstrained Fuzziness як абстрактний візерунок. Ця стаття застосовує ці візуальні візерунки до процесу аналізу зображення, який демонструє принципи в діїM SK1
NOTA: Знову підлаштовувати системуM SK1 Але там' тепер є десктопова версія, так само як і CLI . Вона працює PRETTY добре, але деякі краї змушують smooth out
Цей artykuł служить багатьма цілями. Навігайте, що вас цікавить

ImageSummarizer - це конвеєр RAG для поглинання зображення, який виділяє структуровані метадані, текстM SK1 субтитры, і візуальні сигнали за допомогою архітектура на основі хвиль. Система збільшується від швидкого локального аналізу ( ФлоренціяM SK2 ONNX) до Vision LLMs лише тоді, коли це потрібно
Головні принципи:
ImageSummarizer показує, що мультиmodaльні LLM можна використовувати без подолання детермінізму. ймовірність запропонує, детермінізм залишається.
Правила дизайну
- Моделі ніколи не споживають інших моделей' проза
- Природний мова ніколи не є державою
- Ескаляція - це детерміністичні шкали
- Кожен виход має довіру + проходження
Трубопровод виділяє структуровані метадані з зображень для систем RAG. Ураховуючи будь-яке зображення або анімований GIF
Ключе слово: структурований. Кожен результат має показники довіри , приналежність до джерела МSK2 і вказівники на докази M SK3 Жодна модель не є єдиним джерелом правдивості
Глибокий дайвинг: Трубопровод OCR досить складний, щоб гарантувати свій власний ArtikelM SK1 Погляньте Зразок 4.1: Трійна труба OCR для повного технічного розкладу, включаючи EAST, CRAFTM SK1 Real-ESRGAN , CLIPMSC4 та оптимізацію траєкторії зйомки фільмів
Система використовує тривимірну шкалу ескалації для видобутку текстів
| Зона МSK1 Metodа МSK2 Швидкість | Koszt мSK4 Найкраще для M | |||||||
|---|---|---|---|---|---|---|---|---|
| 1 | Тесеракт МSK0 ~50ms МSK2 Вільно | Чиста MSК4 висока МСК5 контрастний текст СМСК6 | ||||||
| 2 | Флоренція-2 ONNX | МSK1ms МSK2 Бесплатно | Стилизовані шрифтиM SK4 безкоштовні API | |||||
| 3 | Візор LLM МSK0 ~1-5s МSK2 | $0.001-0.01 | Створюва | МSK5 | забарвлений текст |
Розпізнавання тексту на NX (Схід, CRAFT, МSK1msM SK2 визначає оптимальний шляхMSC3
Результат: МSK1 ГБ локальних моделей ONNX, які обробляють МSK2 зображення без витрат API .

$ imagesummarizer demo-images/cat_wag.gif --pipeline caption --output text
Caption: A cat is sitting on a white couch.
Scene: indoor
Motion: MODERATE object_motion motion (partial coverage)
Моніторні фрази emitуються тільки тоді, коли їх підтримують оптичні вимірювання потоку і кадрні делти; інакше система повертається до нейтральних дескрипторов M SK1тонкий рух", " рух камериМSK4 " зміни об 'єктів МSK6

$ imagesummarizer demo-images/anchorman-not-even-mad.gif --pipeline caption --output text
"I'm not even mad."
"That's amazing."
Caption: A person wearing grey turtleneck sweater with neutral expression
Scene: meme
Motion: SUBTLE general motion (localized coverage)
-свідоме відокремлення кадру визначає зміни тексту в нижній частині кадру МSK1 кадрів МSK2 заважає яскравим пікселім
Для анімованих GIF з субтитрами, інструмент створює горизонтальні смуги кадрів для аналізу Vision LLM
Teks-Только смужка ( NEW МSK1 МSK2 30× Reducing token
Найефективніший режим виділяє лише коробки для текстурного обертання.

$ imagesummarizer export-strip demo-images/anchorman-not-even-mad.gif --mode text-only
Detecting subtitle regions (bottom 30%)...
Found 2 unique text segments
Saved text-only strip to: anchorman-not-even-mad_textonly_strip.png
Dimensions: 253×105 (83% token reduction)
| Погляньмо на це. | |||
|---|---|---|---|
| Полні кадри МSK1 МSK2 3000×185 MSК4 MSК5 СМСК6 Високо МСК7 | |||
| ОCR стрічка МSK1 кадри МSK2 | |||
| Teks- тільки смужка | 253×105 | ~50 | Найнижчий |
Як це працює: OpenCV ідентифікує області субтитров ( нижній МSK2 пороги яскравих пікселів | ( білий | МSK4 | чорний текст |), | виділяє вузькі коробки з вигином \ , | і відокремлює на основі змін тексту \ МSK7 | LLM Vision сприймає тільки текстові ділянки , | зберігаючи весь зміст субтитра, в той час як виключає фонові піксельі \
ОCR Mode Strip (текст змінюється лише МSK1 МSK2 кадри зменшені до M2 кадрівМСК4

$ imagesummarizer export-strip demo-images/anchorman-not-even-mad.gif --mode ocr
Deduplicating 93 frames (OCR mode - text changes only)...
Reduced to 2 unique text frames
Saved ocr strip to: anchorman-not-even-mad_ocr_strip.png
Dimensions: 600x185 (2 frames)
Руховий режим (шифри для припущення рухуM SK1

$ imagesummarizer export-strip demo-images/cat_wag.gif --mode motion --max-frames 6
Extracting 6 keyframes from 9 frames (motion mode)...
Extracted 6 keyframes for motion inference
Saved motion strip to: cat_wag_motion_strip.png
Dimensions: 3000x280 (6 frames)
Це дозволяє Vision LLM читати весь текст субтитра в одному API залучення, значно покращує точность мемів та субтитрового контенту, одночасно знизуючи використання токенівM SK1
Це б 'є " просто субтитрує його з фронтальним моделлю " з тієї ж причини, що рентгеничні промені б' ють розповідь МSK3 модель ніколи не просять заповнювати прогалини M SK4 вона отримує закритий журнал - вимірювані кольори MSC6 відслідкований рух MST7 відхилені кадри субтитрові МST8 довіра до OCR M ST9 і лише показує те, що вже міститься на підґрунті М ST10 Коли GPT М st11 субтитры роблять зображення M st12 це М С ST13 робить підрахунки M S ST14 коли ImageSummarizer робить М S ST15 це\ М S S ST16\ підсумовує сигнали, які вже існують\ М С S ST17\
Система використовує труба з базою на хвилях де кожна хвиля є незалежним аналізатором, що виробляє надруковані сигнали. Води виконуються в порядку пріоритету (нижче число запускається першимиM SK1, і інші хвилі можуть читати сигнали з попередніх хвиль
Порядок виконання: Потік МSK1 запускається перед Потіком МSK2 запускується перед Походом 80. Нижчі номери пріоритету виконуються раніше в процесі
flowchart TB
subgraph Wave10["Wave 10: Foundational Signals"]
W1[IdentityWave - Format, dimensions]
W2[ColorWave - Palette, saturation]
end
subgraph Wave40["Wave 40: Text Detection"]
W9[TextLikelinessWave - OpenCV EAST/CRAFT]
end
subgraph Wave50["Wave 50: Traditional OCR"]
W3[OcrWave - Tesseract]
end
subgraph Wave51["Wave 51: ML OCR"]
W8[MlOcrWave - Florence-2 ONNX]
end
subgraph Wave55["Wave 55: ML Captioning"]
W10[Florence2Wave - Local captions]
end
subgraph Wave58["Wave 58: Quality Gate"]
W5[OcrQualityWave - Escalation decision]
end
subgraph Wave70["Wave 70: Embeddings"]
W7[ClipEmbeddingWave - Semantic vectors]
end
subgraph Wave80["Wave 80: Vision LLM"]
W6[VisionLlmWave - Cloud fallback]
end
Wave10 --> Wave40 --> Wave50 --> Wave51 --> Wave55 --> Wave58 --> Wave70 --> Wave80
style Wave10 stroke:#22c55e,stroke-width:2px
style Wave40 stroke:#06b6d4,stroke-width:2px
style Wave50 stroke:#f59e0b,stroke-width:2px
style Wave51 stroke:#8b5cf6,stroke-width:2px
style Wave55 stroke:#8b5cf6,stroke-width:2px
style Wave58 stroke:#ef4444,stroke-width:2px
style Wave70 stroke:#3b82f6,stroke-width:2px
style Wave80 stroke:#8b5cf6,stroke-width:2px
Порядок пріоритетів МSK0нижчий - перший МSK1 10 ♫ ♫ → ♫
Це Обмежений фузій МСМ застосовується для аналізу зображення: багато учасників публікують на спільному підґрунті (the AnalysisContext), і кінцевий вихід об 'єднує їхні сигналиM SK1
Примітка про замовлення хвиль: Три OCR шари (Tesseract/FlorenceM SK2Vision LLM) - це рівень концептуального ескалаціїMSC4 Індивідуальні хвилі, такі як Advanced OCR або Quality Gate - покращення в межах цих шарів МСК0 не окремі рівні ескалації МSK1 вони виконують часову стабилізацію та перевірку якості МКС2 odpowiednio МСС3
Кожна хвиля виробляє сигнали за допомогою стандартизованої контракту:
public record Signal
{
public required string Key { get; init; } // "color.dominant", "ocr.quality.is_garbled"
public object? Value { get; init; } // The measured value
public double Confidence { get; init; } = 1.0; // 0.0-1.0 reliability score
public required string Source { get; init; } // "ColorWave", "VisionLlmWave"
public DateTime Timestamp { get; init; } // When produced
public List<string>? Tags { get; init; } // "visual", "ocr", "quality"
public Dictionary<string, object>? Metadata { get; init; } // Additional context
}
Це частина. 2 Сигналовий контракт в дії . Води не розмовляють один з одним за допомогою природної мови МSK2 Вони публікують надруковані сигнали в об 'єднаному контексті
Зауважте, Confidence є за один сигнал, а не за хвилі, один сигнал може видавати багато сигналів з різною епіцентричною силою. МSK4. Колірна хвиля МSK5. Домінуючий список кольорів має довіру. МSK6 (. Комп 'ютерні показники - МSK8. Але окремі відсоток кольора використовують довіру як вага для зворотнього підсумування.
Упевненість тут означає надійність для використання в зворотньому напрямку, не математична впевненість . Детерміністичні сигнали повторювані МSK2 не хибні
Остереження щодо детермінізму: " Детерміністична МSK2 означає, що для given runtime and configuration не існує випадковості та стабільних результатів з вибірки зразків
Щоб уникнути збентеження , тут' це канонічна नेमмена сигналу OCR, яка використовується впродовж системи МSK2
| Сигнальний ключ | Źródło МSK2 Описание МSK3 |
|---|---|
ocr.text |
Tesseract МSK1Tier 1) МSK3 Raw singleM SK4frame OCR |
ocr.confidence |
Тесеракт МSK1 Довіра до Tesseract МSK2 |
ocr.ml.text МSK0 Флоренція-2 M SK2Tier МSK3 \ |
ML OCR одинарkowy -фразм |
ocr.ml.multiframe_text |
ФлоренціяM SK1 МSK2Tier 2) | Мульти--フレーм GIF OCR МSK6подібно для анімації |
ocr.ml.confidence МSK0 ФлоренціяМСК1 MСК2 ФлорентіяМ СК3 довіра балу МСК4 |
|
ocr.quality.spell_check_score |
OcrQualityWave |
ocr.quality.is_garbled |
OcrQualityWave |
ocr.vision.text |
VisionLlmWave |
caption.text |
VisionLlmWave |
Важлива різниця: ocr.vision.text є видобуток МSK0OCR), тоді, як caption.text є опис сцени (captioningM SK1 Обидві можуть походить з одного вызову Vision LLM, але вони служать різними цілямиMSC3
Належність вибору кінцевого тексту МSK0с найвищим до найнижчим):
ocr.vision.text (Vision LLM OCRocr.ml.multiframe_text (ФлоренціяМSK1 GIFM SK2ocr.ml.text (ФлоренціяМSK1модильнийM SK2фразм)ocr.text (TesseractM SK1Кожна хвиля створює простий інтерфейс:
public interface IAnalysisWave
{
string Name { get; }
int Priority { get; } // Lower number = runs earlier (10 before 50 before 80)
IReadOnlyList<string> Tags { get; }
Task<IEnumerable<Signal>> AnalyzeAsync(
string imagePath,
AnalysisContext context, // Shared substrate with earlier signals
CancellationToken ct);
}
І AnalysisContext - це فضای консенсусу з частини 2. Waves canM SK1
context.GetValue<bool>("ocr.quality.is_garbled")context.GetCached<Image<Rgba32>>("ocr.frames")ColorWave запускає перший (priority 10) і обчислює факти, які обмежують все інше
public class ColorWave : IAnalysisWave
{
public string Name => "ColorWave";
public int Priority => 10; // Runs first (lowest priority number)
public IReadOnlyList<string> Tags => new[] { "visual", "color" };
public async Task<IEnumerable<Signal>> AnalyzeAsync(
string imagePath,
AnalysisContext context,
CancellationToken ct)
{
var signals = new List<Signal>();
using var image = await LoadImageAsync(imagePath, ct);
// Extract dominant colors (computed, not guessed)
var dominantColors = _colorAnalyzer.ExtractDominantColors(image);
signals.Add(new Signal
{
Key = "color.dominant_colors",
Value = dominantColors,
Confidence = 1.0, // Reproducible measurement
Source = Name,
Tags = new List<string> { "color" }
});
// Individual colors for easy access
for (int i = 0; i < Math.Min(5, dominantColors.Count); i++)
{
var color = dominantColors[i];
signals.Add(new Signal
{
Key = $"color.dominant_{i + 1}",
Value = color.Hex,
Confidence = color.Percentage / 100.0,
Source = Name,
Metadata = new Dictionary<string, object>
{
["name"] = color.Name,
["percentage"] = color.Percentage
}
});
}
// Cache the image for other waves (no need to reload)
context.SetCached("image", image.CloneAs<Rgba32>());
return signals;
}
}
Пізніше Vision LLM отримує ці кольори, як обмеження. Він не повинен стверджувати, що зображення має "яскраві червоні кольори МSK2 якщо ColorWave обчислив, що домінуючий колір - блакитний
Ось де Стримана неясність світиться. OcrQualityWave - це констренер яка вирішує, чи перейти до дорогих Vision LLM:
public class OcrQualityWave : IAnalysisWave
{
public string Name => "OcrQualityWave";
public int Priority => 58; // Runs after OCR waves
public IReadOnlyList<string> Tags => new[] { "content", "ocr", "quality" };
public async Task<IEnumerable<Signal>> AnalyzeAsync(
string imagePath,
AnalysisContext context,
CancellationToken ct)
{
var signals = new List<Signal>();
// Get OCR text from earlier waves (canonical taxonomy)
string? ocrText =
context.GetValue<string>("ocr.ml.multiframe_text") ?? // Florence-2 GIF
context.GetValue<string>("ocr.ml.text") ?? // Florence-2 single
context.GetValue<string>("ocr.text"); // Tesseract
if (string.IsNullOrWhiteSpace(ocrText))
{
signals.Add(new Signal
{
Key = "ocr.quality.no_text",
Value = true,
Confidence = 1.0,
Source = Name
});
return signals;
}
// Tier 1: Spell check (deterministic, no LLM)
var spellResult = _spellChecker.CheckTextQuality(ocrText);
signals.Add(new Signal
{
Key = "ocr.quality.spell_check_score",
Value = spellResult.CorrectWordsRatio,
Confidence = 1.0,
Source = Name,
Metadata = new Dictionary<string, object>
{
["total_words"] = spellResult.TotalWords,
["correct_words"] = spellResult.CorrectWords
}
});
signals.Add(new Signal
{
Key = "ocr.quality.is_garbled",
Value = spellResult.IsGarbled, // < 50% correct words
Confidence = 1.0,
Source = Name
});
// This signal triggers Vision LLM escalation
if (spellResult.IsGarbled)
{
signals.Add(new Signal
{
Key = "ocr.quality.correction_needed",
Value = true,
Confidence = 1.0,
Source = Name,
Tags = new List<string> { "action_required" },
Metadata = new Dictionary<string, object>
{
["quality_score"] = spellResult.CorrectWordsRatio,
["correction_method"] = "llm_sentinel"
}
});
// Cache for Vision LLM to access
context.SetCached("ocr.garbled_text", ocrText);
}
return signals;
}
}
Вирок ескалації детерміністична: якщо бал під час перевірки заклинання МSK1 МSK2 випромінює сигнал, що активує зоровий люмінесцен LLM

$ imagesummarizer demo-images/arse_biscuits.gif --pipeline caption --output text
OCR: "ARSE BISCUITS"
Caption: An elderly man dressed as bishop with text reading "arse biscuits"
Scene: meme
ОCR отримав текст; Vision LLM надавав сценічний контекстM SK1 Кожна хвиля додає того, що це добре в ' МSK3
Візорна хвиля LLM працює лише тоді, коли попередні сигнали показують, що це потрібне.
public class VisionLlmWave : IAnalysisWave
{
public string Name => "VisionLlmWave";
public int Priority => 50; // Runs after quality assessment
public IReadOnlyList<string> Tags => new[] { "content", "vision", "llm" };
public async Task<IEnumerable<Signal>> AnalyzeAsync(
string imagePath,
AnalysisContext context,
CancellationToken ct)
{
var signals = new List<Signal>();
if (!Config.EnableVisionLlm)
{
signals.Add(new Signal
{
Key = "vision.llm.disabled",
Value = true,
Confidence = 1.0,
Source = Name
});
return signals;
}
// Check if OCR was unreliable (garbled text)
var ocrGarbled = context.GetValue<bool>("ocr.quality.is_garbled");
var textLikeliness = context.GetValue<double>("content.text_likeliness");
var ocrConfidence = context.GetValue<double>("ocr.ml.confidence",
context.GetValue<double>("ocr.confidence"));
// Only escalate when: OCR failed OR (text likely but low OCR confidence)
// Models never decide paths; deterministic signals do (no autonomy)
bool shouldEscalate = ocrGarbled ||
(textLikeliness > 0.7 && ocrConfidence < 0.5);
if (shouldEscalate)
{
var llmText = await ExtractTextAsync(imagePath, ct);
if (!string.IsNullOrEmpty(llmText))
{
// Emit OCR signal (Vision LLM tier)
signals.Add(new Signal
{
Key = "ocr.vision.text", // Vision LLM OCR extraction
Value = llmText,
Confidence = 0.95, // High but not 1.0 - still probabilistic
Source = Name,
Tags = new List<string> { "ocr", "vision", "llm" },
Metadata = new Dictionary<string, object>
{
["ocr_was_garbled"] = ocrGarbled,
["escalation_reason"] = ocrGarbled ? "quality_gate_failed" : "low_confidence_high_likeliness",
["text_likeliness"] = textLikeliness,
["prior_ocr_confidence"] = ocrConfidence
}
});
// Optionally emit caption (separate signal)
var llmCaption = await GenerateCaptionAsync(imagePath, ct);
if (!string.IsNullOrEmpty(llmCaption))
{
signals.Add(new Signal
{
Key = "caption.text", // Descriptive caption (not OCR)
Value = llmCaption,
Confidence = 0.90,
Source = Name,
Tags = new List<string> { "caption", "description" }
});
}
}
}
return signals;
}
}
Найголовніша думка: Базовий текст LLM має впевненість 0.95, не 1.0. ЦеM SK1 краще, ніж розбитий OCR , але це МSK3 все ще вірогідний МSK4 Аgregація нижчего потоку знає це. | | МSK6 Навіщо | 0.95? По замовчуванню переді мною МСК8 конфігурований на один модель М СК9 трубка М S К10 записана в конфігурації М ็ С К11 точная величина має менший значення, ніж мати значення, яке не є't M SK1
І ImageLedger накопичує сигнали в структуровані секції для споживання вниз. Це Перетягування контексту застосовується для аналізу зображення:
public class ImageLedger
{
public ImageIdentity Identity { get; set; } = new();
public ColorLedger Colors { get; set; } = new();
public TextLedger Text { get; set; } = new();
public MotionLedger? Motion { get; set; }
public QualityLedger Quality { get; set; } = new();
public VisionLedger Vision { get; set; } = new();
public static ImageLedger FromProfile(DynamicImageProfile profile)
{
var ledger = new ImageLedger();
// Text: Priority order - corrected > voting > temporal > raw
ledger.Text = new TextLedger
{
ExtractedText =
profile.GetValue<string>("ocr.final.corrected_text") ?? // Tier 2/3 corrections
profile.GetValue<string>("ocr.voting.consensus_text") ?? // Temporal voting
profile.GetValue<string>("ocr.full_text") ?? // Raw OCR
string.Empty,
Confidence = profile.GetValue<double>("ocr.voting.confidence"),
SpellCheckScore = profile.GetValue<double>("ocr.quality.spell_check_score"),
IsGarbled = profile.GetValue<bool>("ocr.quality.is_garbled")
};
// Colors: Computed facts, not guessed
ledger.Colors = new ColorLedger
{
DominantColors = profile.GetValue<List<DominantColor>>("color.dominant_colors") ?? new(),
IsGrayscale = profile.GetValue<bool>("color.is_grayscale"),
MeanSaturation = profile.GetValue<double>("color.mean_saturation")
};
return ledger;
}
public string ToLlmSummary()
{
var parts = new List<string>();
parts.Add($"Format: {Identity.Format}, {Identity.Width}x{Identity.Height}");
if (Colors.DominantColors.Count > 0)
{
var colorList = string.Join(", ",
Colors.DominantColors.Take(5).Select(c => $"{c.Name}({c.Percentage:F0}%)"));
parts.Add($"Colors: {colorList}");
}
if (!string.IsNullOrWhiteSpace(Text.ExtractedText))
{
var preview = Text.ExtractedText.Length > 100
? Text.ExtractedText[..100] + "..."
: Text.ExtractedText;
parts.Add($"Text (OCR, {Text.Confidence:F0}% confident): \"{preview}\"");
}
return string.Join("\n", parts);
}
}
Довідник є прикріплення в термінах CFCD. Це просуває те, що вижили від селекції , і синтез ЛЛМ має поважати ці факти МSK2
Ви бачили логіку ескалації в двох місцях. OcrQualityWave випускає сигнали про якість; EscalationService вживається політика через ці сигнали . Це навмисное відокремлення:
EscalationService збирати сигнали і застосовувати глобальні шкалиІ EscalationService це все об 'єднує. це реалізує модель частини МSK1 підґрунт → запропонувач МSK1 конструктор:
public class EscalationService
{
private bool ShouldAutoEscalate(ImageProfile profile)
{
// Escalate if type detection confidence is low
if (profile.TypeConfidence < _config.ConfidenceThreshold)
return true;
// Escalate if image is blurry
if (profile.LaplacianVariance < _config.BlurThreshold)
return true;
// Escalate if high text content
if (profile.TextLikeliness >= _config.TextLikelinessThreshold)
return true;
// Escalate for complex diagrams or charts
if (profile.DetectedType is ImageType.Diagram or ImageType.Chart)
return true;
return false;
}
}
Кожне рішення щодо ескалації детерміністична: ті самі вхідні дані , ті ж проміжки МSK2 те саме рішення M SK3 Ніяких LLM судження у логіці ескалації .
Коли Vision LLM працює, то отримує обчислені факти як обмеження:
private static string BuildVisionPrompt(ImageProfile profile)
{
var prompt = new StringBuilder();
prompt.AppendLine("CRITICAL CONSTRAINTS:");
prompt.AppendLine("- Only describe what is visually present in the image");
prompt.AppendLine("- Only reference metadata values provided below");
prompt.AppendLine("- Do NOT infer, assume, or guess information not visible");
prompt.AppendLine();
prompt.AppendLine("METADATA SIGNALS (computed from image analysis):");
if (profile.DominantColors?.Any() == true)
{
prompt.Append("Dominant Colors: ");
var colorDescriptions = profile.DominantColors
.Take(3)
.Select(c => $"{c.Name} ({c.Percentage:F0}%)");
prompt.AppendLine(string.Join(", ", colorDescriptions));
if (profile.IsMostlyGrayscale)
prompt.AppendLine(" → Image is mostly grayscale");
}
prompt.AppendLine($"Sharpness: {profile.LaplacianVariance:F0} (Laplacian variance)");
if (profile.LaplacianVariance < 100)
prompt.AppendLine(" → Image is blurry or soft-focused");
prompt.AppendLine($"Detected Type: {profile.DetectedType} (confidence: {profile.TypeConfidence:P0})");
prompt.AppendLine();
prompt.AppendLine("Use these metadata signals to guide your description.");
prompt.AppendLine("Your description should be grounded in observable facts only.");
return prompt.ToString();
}
У Vision LLM не треба стверджувати, що "яскраві кольори " якщо ми обчислили сірий діапазон МSK2 якщо він правий M SK3 протиріччя можна виявити . Він не повинен стведжувати, що детермінативний субстрат обмежує ймовірність.
Ці обмеження зменшують галюцинацію, але не можуть її вилікувати-покази - це підказкиМSK1 не гарантіїM SK2 Реальний введення відбувається вниз по течії через вага довіру та вибір сигналуMSC3 Показ є одним шаром; архітектура є іншимMNK5
Коли витягується остаточний текст, система використовує жорсткий порядок пріоритету
static string? GetExtractedText(DynamicImageProfile profile)
{
// Priority chain using canonical signal names (see OCR Signal Taxonomy above)
// 1. Vision LLM OCR (best for complex/garbled)
// 2. Florence-2 multi-frame GIF (temporal stability)
// 3. Florence-2 single-frame (stylized fonts)
// 4. Tesseract (baseline)
var visionText = profile.GetValue<string>("ocr.vision.text");
if (!string.IsNullOrEmpty(visionText))
ocally (confidence 0.85-0.90, no cost)
- **Tesseract voting**: Reliable for clean text (confidence varies, deterministic)
- **Raw Tesseract**: Baseline fallback (confidence < 0.7 for stylized fonts)
The priority order encodes this knowledge. Florence-2 sitting between Vision LLM and Tesseract provides a "sweet spot" for most images—better than traditional OCR, cheaper than cloud Vision LLMs.
Note: this function selects *one* source, but the ledger exposes *all* sources with their confidence scores. Downstream consumers can-and should-inspect provenance when the domain requires it. The priority order is a sensible default, not a straitjacket.
---
## Selection and Conflict Resolution
The priority chain above is the current implementation-a simple fallback. But the architecture supports adding rejection rules as config-driven policy. Here's the pattern for contradiction detection (not yet implemented, but the signals exist to support it):
```csharp
// Pattern: Contradiction detection as policy rules
public static class SelectionPolicy
{
public static string? SelectTextWithConstraints(DynamicImageProfile profile)
{
var visionText = profile.GetValue<string>("vision.llm.text");
if (!string.IsNullOrEmpty(visionText))
{
// Rule: Reject if Vision claims text but deterministic signals say no text
var textLikeliness = profile.GetValue<double>("content.text_likeliness");
if (textLikeliness < _config.TextLikelinessThreshold && visionText.Length > 50)
{
// Contradiction detected - log and fall through
profile.AddSignal(new Signal
{
Key = "selection.vision_rejected",
Value = "text_likeliness_contradiction",
Confidence = 1.0,
Source = "SelectionPolicy",
Metadata = new Dictionary<string, object>
{
["text_likeliness"] = textLikeliness,
["vision_text_length"] = visionText.Length,
["threshold"] = _config.TextLikelinessThreshold
}
});
// Fall through to OCR sources
}
else
{
return visionText;
}
}
// Continue with priority chain...
return profile.GetValue<string>("ocr.voting.consensus_text")
?? profile.GetValue<string>("ocr.full_text");
}
}
Те ж саме стосується і інших типів сигналу:
color.is_grayscale це правдаquality.sharpness < - межаcontent.type Це діаграма з великою впевненістюКлючові властивості шару вибору:
Це те місце, де "детермінізм настає " стає механічно правдою МSK2 LLM запропонуєМSK3 детерміністичні правила вирішують, чи приймати
Трубопроводи можна повністю конфігурувати за допомогою JSON,, що робить структуру хвиль яскравою і перевіряноюM SK1
{
"name": "advancedocr",
"displayName": "Advanced OCR (Default)",
"description": "Multi-frame temporal OCR with stabilization and voting",
"estimatedDurationSeconds": 2.5,
"accuracyImprovement": 25,
"phases": [
{
"id": "color",
"name": "Color Analysis",
"priority": 100,
"waveType": "ColorWave",
"enabled": true
},
{
"id": "simple-ocr",
"name": "Simple OCR",
"priority": 60,
"waveType": "OcrWave",
"earlyExitThreshold": 0.98
},
{
"id": "advanced-ocr",
"name": "Advanced Multi-Frame OCR",
"priority": 59,
"waveType": "AdvancedOcrWave",
"dependsOn": ["simple-ocr"],
"parameters": {
"maxFrames": 30,
"ssimThreshold": 0.95,
"enableVoting": true
}
},
{
"id": "quality",
"name": "OCR Quality Assessment",
"priority": 58,
"waveType": "OcrQualityWave",
"dependsOn": ["advanced-ocr"]
}
]
}
На ранніх вихідних рівнях дешеві хвилі перестають рухатись, коли дешеві вже досягли високої надійності.
І auto трубопровод implements smart routing based on image characteristics, selecting the optimal processing pathM SK1
Image Analysis (OpenCV ~5-20ms)
│
├── Is animated (>1 frame)?
│ └── ANIMATED route
│ ├── Has subtitle regions? → Text-only strip extraction
│ ├── Minimal text? → FAST (Florence-2 only)
│ └── Motion significant? → Motion analysis
│
├── Has text regions (OpenCV detection)?
│ ├── High contrast, clean text → FAST route (Florence-2, ~100ms)
│ ├── Moderate confidence → BALANCED route (Florence-2 + Tesseract, ~300ms)
│ └── Low confidence → QUALITY route (Multi-frame + Vision LLM, ~1-5s)
│
├── Is chart/diagram (type detection)?
│ └── QUALITY route → Vision LLM caption
│
└── Default → FAST route (Florence-2 caption)
| Маршрут МSK1 Триггери, коли МSK2 Обробка | Час | |
|---|---|---|
| Швидший МSK1 Простій текстM SK2 високий контраст, стандартні шрифти | ФлоренціяMSC5 тільки МSK6 мск7 мз एमСК8 нижчий мСК9 локальний МСК10 | МСк11 |
| МSK0 Збалансований | Нормальний текст МSK2 середній рівень довіри | |
| Квалительність МSK1 Карти МSK2 діаграми , стильизовані шрифти \ , низька самовпевненість | ||
| ANIMATED МSK1 GIF-файли з субтитрами |
$ imagesummarizer anchorman-not-even-mad.gif --pipeline auto --output visual
[Route selection...]
Image: 300×185, 93 frames
Text detection: 15 regions found (bottom 30%)
Subtitle pattern: DETECTED
→ Selected ANIMATED route (text-only filmstrip)
[Processing...]
MlOcrWave: Extracted 10 frames → 2 unique text segments
Text-only strip: 253×105 (83% token reduction)
VisionLlmWave: Processing filmstrip...
[Results - 2.3s total]
Text: "I'm not even mad." + "That's amazing."
Caption: A person wearing grey turtleneck sweater with neutral expression
Scene: meme
Motion: SUBTLE general motion
Вибір маршруту є детерміністичним і записується в сигналах для аудиту:
{
"routing": {
"selected_route": "ANIMATED",
"reason": "subtitle_pattern_detected",
"text_regions": 15,
"frames": 93,
"decision_time_ms": 18
}
}
# Use auto pipeline (smart routing - recommended)
imagesummarizer meme.gif --pipeline auto
# Fast local caption with Florence-2 ONNX (~200ms)
imagesummarizer photo.jpg --pipeline florence2
# Best quality: Florence-2 + Vision LLM
imagesummarizer complex-diagram.png --pipeline florence2+llm
# Extract text only (three-tier OCR)
imagesummarizer screenshot.png --pipeline advancedocr
# Motion analysis for GIFs
imagesummarizer animation.gif --pipeline motion
# Process a directory with visual output
imagesummarizer ./photos/ --output visual
Запросити лише сигнали, які вам потрібні за допомогою попереднього-визначених колекційM SK1
# Minimal metadata (fast)
imagesummarizer image.png --signals "@minimal"
# Alt text for accessibility
imagesummarizer image.png --signals "@alttext"
# Motion analysis
imagesummarizer animation.gif --signals "@motion"
# Full analysis
imagesummarizer image.png --signals "@full"
# Custom wildcard patterns
imagesummarizer image.png --signals "color.dominant*, ocr.text, motion.*"
| Коллекция МSK1 Сигнали МSK2 Застосунок | ||
|---|---|---|
@minimal |
особистістьM SK1*, якістьM SK1 чіткість | Тільки швидкий профиль МSK3 |
@alttext |
субтиза МSK1текст МSK2 оcr .текст* | Доступність МSK1 |
@motion |
рух*, ідентичністьM SK1фразмемМSK2рахунок МSK3Анімація | |
@full |
Всі сигнали | Полна аналіз МSK2 |
@tool |
Оптимізований підбір МSK1 MCPM SK2автоматyzacja МSK3 |
$ imagesummarizer princess-bride.gif --output json
{
"image": "princess-bride.gif",
"duration_ms": 1838,
"waves_executed": ["ColorWave", "OcrWave", "AdvancedOcrWave", "VisionLlmWave"],
"text": {
"value": "You keep using that word.\nI do not think it means what you think it means.",
"source": "ocr.voting.consensus_text",
"confidence": 0.95
},
"escalation": {
"triggered": true,
"reason": "text_likeliness_above_threshold",
"threshold": 0.4,
"observed": 0.67
},
"signals": {
"color.dominant_1": { "value": "#1a1a2e", "confidence": 1.0 },
"ocr.quality.spell_check_score": { "value": 0.82, "confidence": 1.0 },
"ocr.quality.is_garbled": { "value": false, "confidence": 1.0 },
"motion.type": { "value": "static", "confidence": 0.95 }
}
}
Кожне поле має проходження. escalation блок-шоу чому Vision LLM називалася ".".

$ imagesummarizer demo-images/alanshrug_opt.gif --pipeline motion
Motion: SUBTLE general motion (localized coverage)
Direction: up-down
Magnitude: 0.23
$ imagesummarizer
ImageSummarizer Interactive Mode
Pipeline: advancedocr | Output: auto | LLM: auto
Commands: /help, /pipeline, /output, /llm, /model, /ollama, /models, /quit
Enter image path (or drag & drop): F:\Gifs\meme.gif
Processing...
I'm not even mad. That's amazing.
Enter image path: /llm true
Vision LLM: enabled
Enter image path: /model minicpm-v:8b
Vision model: minicpm-v:8b
Для візуального дослідження
У графічному інтерфейсі робочого столу архітектура відображається візуально— ви можете точно побачити, які хвилі бігають , які сигнали вони виділяють M SK2 і як приймаються рішення щодо маршрутізації . Чудово для розуміння системи або розладів спеціального трубопроводу
CLI відображає всю складність як прості варіанти. Ви можете переключати трубні ланцюгиМSK1 моделіM SK2 і вихідні формати, не розуміючи хвильної архітектури.
| Частина МSK1 Pattern МSK2 Implementation ImageSummarizer | ||
|---|---|---|
| 1 | Стримана неясність | ColorWave обчислює фактиM SK1 VisionLlmWave поважає їх |
| 2 | Обмежений фузій МСМ | Багато хвиль опублікують в контексті аналізу |
| 3 | Перетягування контексту | ImageLedger накопичує найвизначніші характеристикиM SK1 Результатиキャッシュування бази даних сигналів |
Схожі шаблони. Різні домениM SK1 Схоже правилоМSK2 ймовірність запропонує, детермінізм залишається.
Це не швидкий шлях. ЦеM SK1 надійний шлях . Досить, якщо вам потрібно оцінити зображення в масштабі
| tryb непрацездатності МSK1 що трапляється МSK2 як це відбувається ' як його лікують | ||
|---|---|---|
| Шумливий GIF | Стріпування кадруM SK1 артефакти стиснення МSK2 Temporal stabilisation + SSIM deduplication МSK4 голосуючий консенсус | |
| ОCR повертає сміття | Tesseract не працює на шрифтах зі стилізованими шрифтами | Spell-Check gate detects МSK3 МSK4 correct မ်СК5 escalates to Florence |
| Ціні API | Надто багато викликів Cloud Vision LLM | ФлоренціяM SK2 ONNX обробляє МSK3 локально МSK4ms), текст M SK6 тільки стрічки зменшують टोकони |
| Базові галюцинації | LLM заявляє, що не існує ' там не є МSK2 Сигнали дозволяють розпізнавати протиріччяvision.llm.text проти content.text_likeliness |
|
| Зміни трубопроводу з часом | Додали нові хвилі МSK1 врегулювали пороги МSK2 зміст - хеш-качування | |
| Модель нічого не повертає | Увізорний LLM вимкнення часу або пуста реакція | Спорядження зворотнього зв 'язку МSK2 Ввізорні LLM МSK3 Флоренція MSК4 МСК5 Голосування Tesseract СМСК6 Raw OCR СМСК7 Priory order ensures graceful degradation |
Кожен режим невдачі має детермінативний реагування. Без тильної деградаціїM SK1
Важливий контекст: ImageSummarizer - це канал поглинання зображення для екосистеми LucidRAG.
Ця стаття фокусується на виділенні структурованих сигналів з зображень. Але реальна сила виникає, коли її поєднують з іншими сумізерамиM SK1
Коли пов 'язані з LucidRAG МСК0, скоро , !),, ці три труби Мульти-МСК0 - модальний граф РАG:
Document → DocSummarizer → Structured signals
↓
Images → ImageSummarizer → Structured signals
↓
Data → DataSummarizer → Structured signals
↓
↓ (all signals)
↓
LucidRAG Graph Builder → Multi-modal knowledge graph
↓
Query → Multi-modal retrieval + constrained generation
Чому це важливо?: Традиційний RAG сприймає зображення як непрозорі краплі, що отримують субтитра . Мультифікатор МSK2 модальний граф RAG розглядає зображення, як джерело сигналу klasy first- з надрукованими зв 'язками з текстом, даніМSK1 та інші зображенняM SK2 Те ж саме принципи детермінізму, різна шкала .
Шкала шаблону: якщо ви можете відокремити структуровані сигнали з зображеннях M SK1 цей artykuł ), документи МSK3DocSummarizer), і дані МSK1DataSummarizer), ви можете побудувати граф знань, де кожен вузол має провини і кожен край має показники довіри
І скоро: Полна інтеграція LucidRAG, яка показує, як ці труби з 'єднуються в мультиплінарні - модальні графи RAG queries
Архітектура має структуру: кожна хвиля невід 'ємна , кожен сигнал зашифрований МSK2 кожна ескалація - детерміністична MSC3 Флоренція M SK4 дає швидкий локальний аналіз , Vision LLM справляється з складними ситуаціями MST6 але жодна з них не працює без обмежень МST7 детерминістичні сигнали завжди прив' язують вихідні сигнали МСТ8
З моменту публікації першої статті, система значно розвинулась.
Лише труба OCR— з трьома етапами ескалаціїМSK1 МSK2 мультимонітивніM SK3 кадрове голосування , оптимізація траєкторії фільмів, і текстуMSC6 лише видобуток стрічківMSL7 стала достатньо складною, щоб гарантувати власний деталізований artykułMKL8 Розгляньмо Інтеграція OCR для візуалізації вказівник на повний технический розрив.
Якщо ви можете зробити це для зображення— найскладніший тип вхідних данихMSC1 з шумом OCRM SK2 стильизовані шрифти, анімовані кадри , і галюцинаціїМSK5 схильні субтитры МSK6 ви можете робити це для будь-якого можливих компонентівMST7
Те, що "'" - обмежена незрозумілість в практиці МSK1 не абстрактна модель
| частина МSK1 візерунок МSK2 вісь | ||
|---|---|---|
| 1 | Стримана неясність | Едина компонента МSK1 |
| 2 | Обмежений фузій МСМ | Багато компонентів МSK1 |
| 3 | Перетягування контексту МSK0 Час / пам 'ять | |
| 4 | Інтелект з зображенням (та статтяM SK1 | Архітектура хвиль |
| 4.1 | Трійна труба МСК0Tier | OCRM SK1 Моделі ONNX, плівкові смуги |
Далі: Частина МSK1 покаже, як ImageSummarizer DocSummarizer, і DataSummarizer з 'єднати до мультиплікового графу RAG з LucidRAG.
Усі частини йдуть за однаковим інваріантом: ймовірнісні компоненти запропонують; детерміністичні системи тривають.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.