Add diagnostic logging to panel detection pipeline

Added comprehensive logging throughout the panel detection system to aid in debugging and understanding detection flow:

- detector.js: Log caching status, detection start, and attempts for each method (OpenCV, ML, Grid)
- opencv.js: Log number of potential panels detected
- coco-ssd.js: Log number of predictions from ML model
- grid.js: Log final merged panel count

These logs help track which detection method is being used and how many panels are found at each step, making it easier to diagnose detection issues.
This commit is contained in:
2026-04-13 20:43:49 -04:00
parent fc9d0ecafb
commit e0d53837c6
4 changed files with 28 additions and 4 deletions
+1 -1
View File
@@ -8,11 +8,11 @@ export async function detectPanelsML(imageData, model) {
ctx.putImageData(imageData, 0, 0); ctx.putImageData(imageData, 0, 0);
const predictions = await model.detect(canvas); const predictions = await model.detect(canvas);
console.log("[COCO-SSD] Got", predictions.length, "predictions");
const panels = []; const panels = [];
const imgWidth = imageData.width; const imgWidth = imageData.width;
const imgHeight = imageData.height; const imgHeight = imageData.height;
for (let i = 0; i < predictions.length; i++) { for (let i = 0; i < predictions.length; i++) {
const pred = predictions[i]; const pred = predictions[i];
const [x, y, w, h] = pred.bbox; const [x, y, w, h] = pred.bbox;
+25 -2
View File
@@ -10,6 +10,7 @@ export class PanelDetector {
const cacheKey = `${doc.location?.pathname || ""}-${index}`; const cacheKey = `${doc.location?.pathname || ""}-${index}`;
if (!force && this.#cache.has(cacheKey)) { if (!force && this.#cache.has(cacheKey)) {
console.log("[Panel Detection] Using cached result");
return this.#cache.get(cacheKey); return this.#cache.get(cacheKey);
} }
@@ -17,7 +18,10 @@ export class PanelDetector {
if (!imageData) { if (!imageData) {
return { panels: [], method: "no-image", confidence: 0 }; return { panels: [], method: "no-image", confidence: 0 };
} }
console.log(
"[Panel Detection] Starting detection for image:",
`${imageData.width}x${imageData.height}px`,
);
// Load ML libraries on first use // Load ML libraries on first use
if (!this.#scriptsLoaded) { if (!this.#scriptsLoaded) {
const result = await loadMLLibraries(); const result = await loadMLLibraries();
@@ -66,7 +70,7 @@ export class PanelDetector {
const { detectPanelsOpenCV } = await import("./opencv.js"); const { detectPanelsOpenCV } = await import("./opencv.js");
const { detectPanelsML } = await import("./coco-ssd.js"); const { detectPanelsML } = await import("./coco-ssd.js");
const { detectPanelsGrid } = await import("./grid.js"); const { detectPanelsGrid } = await import("./grid.js");
console.log("[Panel Detection] Attempting OpenCV detection...");
// Try OpenCV (uses global cv) // Try OpenCV (uses global cv)
try { try {
const cv = globalThis.cv; const cv = globalThis.cv;
@@ -83,8 +87,12 @@ export class PanelDetector {
}); });
const panels = await detectPanelsOpenCV(imageData, cv); const panels = await detectPanelsOpenCV(imageData, cv);
console.log("[Panel Detection] OpenCV found", panels.length, "panels");
if (this.#validatePanels(panels, imageData)) { if (this.#validatePanels(panels, imageData)) {
console.log("[Panel Detection] ✓ Using OpenCV detection");
return { panels, method: "opencv", confidence: 0.85 }; return { panels, method: "opencv", confidence: 0.85 };
} else {
console.log("[Panel Detection] ✗ OpenCV panels failed validation");
} }
} }
} catch (e) { } catch (e) {
@@ -92,17 +100,26 @@ export class PanelDetector {
} }
// Try ML (uses global cocoSsd) // Try ML (uses global cocoSsd)
console.log("[Panel Detection] Attempting ML detection...");
try { try {
const cocoSsdModule = globalThis.cocoSsd; const cocoSsdModule = globalThis.cocoSsd;
if (cocoSsdModule && cocoSsdModule.load) { if (cocoSsdModule && cocoSsdModule.load) {
// Load model if not cached // Load model if not cached
if (!this.#model) { if (!this.#model) {
console.log("[Panel Detection] Loading COCO-SSD model...");
this.#model = await cocoSsdModule.load(); this.#model = await cocoSsdModule.load();
console.log("[Panel Detection] COCO-SSD model loaded");
} else {
console.log("[Panel Detection] Using cached COCO-SSD model");
} }
const panels = await detectPanelsML(imageData, this.#model); const panels = await detectPanelsML(imageData, this.#model);
console.log("[Panel Detection] ML found", panels.length, "panels");
if (this.#validatePanels(panels, imageData)) { if (this.#validatePanels(panels, imageData)) {
console.log("[Panel Detection] ✓ Using ML detection");
return { panels, method: "ml", confidence: 0.7 }; return { panels, method: "ml", confidence: 0.7 };
} else {
console.log("[Panel Detection] ✗ ML panels failed validation");
} }
} }
} catch (e) { } catch (e) {
@@ -110,7 +127,13 @@ export class PanelDetector {
} }
// Grid fallback (always works) // Grid fallback (always works)
console.log("[Panel Detection] Falling back to grid detection");
const panels = detectPanelsGrid(imageData); const panels = detectPanelsGrid(imageData);
console.log(
"[Panel Detection] ✓ Using grid detection, found",
panels.length,
"panels",
);
return { panels, method: "grid", confidence: 0.4 }; return { panels, method: "grid", confidence: 0.4 };
} }
+1 -1
View File
@@ -82,7 +82,7 @@ function mergeAdjacentPanels(panels) {
} }
} }
} }
console.log("[Grid] Merged to", merged.length, "panels");
merged.push(current); merged.push(current);
} }
+1
View File
@@ -41,6 +41,7 @@ export async function detectPanelsOpenCV(imageData, cv) {
reading_order: i, reading_order: i,
}); });
} }
console.log("[OpenCV] Detected", panels.length, "potential panels");
panels.sort((a, b) => { panels.sort((a, b) => {
const rowA = Math.floor(a.y / 20); const rowA = Math.floor(a.y / 20);