Files
Ubuntu 32b43f85bd a
2026-07-03 16:58:28 +08:00

152 lines
5.5 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* test_real_images.js — 使用真实试纸图片验证 PaperRecognizer
*
* 用法: node test_real_images.js [image_path]
* 不带参数则处理 /home/ubuntu/nanocode/web-opencv/cpp/images/ 下所有图片
* 带参数则只处理指定图片
*
* 依赖: npm install canvas
*/
const { createCanvas, loadImage } = require('canvas');
const fs = require('fs');
const path = require('path');
const { PaperRecognizer, PST_NAMES } = require('./paper-recognizer.js');
const IMAGE_DIR = '/home/ubuntu/nanocode/web-opencv/cpp/images/';
const OUTPUT_DIR = '/home/ubuntu/nanocode/web-opencv/miniappB/samples/';
// Ensure output dir
if (!fs.existsSync(OUTPUT_DIR)) fs.mkdirSync(OUTPUT_DIR, { recursive: true });
const LOCATOR_COLORS = ['Unknown', 'Red', 'Green', 'Blue'];
const BLUR_NAMES = ['None', 'Slight', 'Severe'];
async function processImage(imagePath) {
const fname = path.basename(imagePath);
console.log(`\n▶ ${fname}`);
const t0 = performance.now();
// Load image
const img = await loadImage(imagePath);
console.log(` 尺寸: ${img.width}×${img.height}`);
// Draw to canvas to get RGBA pixels
const canvas = createCanvas(img.width, img.height);
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, img.width, img.height);
const pixels = new Uint8Array(imageData.data.buffer);
// Recognize
const recognizer = new PaperRecognizer();
const result = recognizer.recognize(pixels, img.width, img.height);
const elapsed = (performance.now() - t0).toFixed(0);
const paperType = PST_NAMES[result.paperType] || 'UNKNOWN';
const color = LOCATOR_COLORS[result.locatorColor] || '?';
const blur = BLUR_NAMES[result.blurLevel] || '?';
if (result.success) {
console.log(` ✅ 成功 | 类型: ${paperType} | 色块: ${result.itemCount} | 定位块颜色: ${color} | 小在左: ${result.smallLocatorOnLeft} | 模糊: ${blur}(${(result.blurScore||0).toFixed(0)}) | 耗时: ${elapsed}ms`);
// Save annotated image
if (recognizer.annotatedPixels) {
const outCanvas = createCanvas(img.width, img.height);
const outCtx = outCanvas.getContext('2d');
const outData = outCtx.createImageData(img.width, img.height);
// annotatedPixels is BGRA, need to convert to RGBA for canvas
const ap = recognizer.annotatedPixels;
for (let i = 0; i < ap.length; i += 4) {
outData.data[i] = ap[i + 2]; // R
outData.data[i + 1] = ap[i + 1]; // G
outData.data[i + 2] = ap[i]; // B
outData.data[i + 3] = ap[i + 3]; // A
}
outCtx.putImageData(outData, 0, 0);
const outName = fname.replace(/\.(jpg|jpeg|png|JPG|JPEG|PNG)$/, '_annotated.png');
const outPath = path.join(OUTPUT_DIR, outName);
const buf = outCanvas.toBuffer('image/png');
fs.writeFileSync(outPath, buf);
console.log(` 标注图: ${outPath}`);
}
// Print first 3 colors
if (result.colors && result.colors.length > 0) {
const preview = result.colors.slice(0, 3).map(c =>
`RGB(${c.r.toFixed(0)},${c.g.toFixed(0)},${c.b_val.toFixed(0)})`
).join(', ');
console.log(` 前3色块: ${preview}${result.colors.length > 3 ? ' ...' : ''}`);
}
} else {
const errCode = result.errorCode;
const errMsg = result.errorMessage || '';
console.log(` ❌ 失败 | 错误码: ${errCode} | ${errMsg} | 耗时: ${elapsed}ms`);
}
recognizer.free();
return { fname, result, elapsed };
}
async function main() {
const args = process.argv.slice(2);
let files;
if (args.length > 0) {
files = args.filter(f => {
const ext = path.extname(f).toLowerCase();
return ['.jpg', '.jpeg', '.png'].includes(ext);
});
} else {
files = fs.readdirSync(IMAGE_DIR)
.filter(f => /\.(jpg|jpeg|png|JPG)$/i.test(f))
.map(f => path.join(IMAGE_DIR, f));
}
if (files.length === 0) {
console.log('未找到图片文件');
process.exit(1);
}
console.log(`═══════════════════════════════════════════`);
console.log(`PaperRecognizer 真实图片测试`);
console.log(`共 ${files.length} 张图片`);
console.log(`═══════════════════════════════════════════`);
const results = [];
for (const f of files) {
try {
const r = await processImage(f);
results.push(r);
} catch (e) {
console.log(`\n▶ ${path.basename(f)}`);
console.log(` 💥 异常: ${e.message}`);
results.push({ fname: path.basename(f), result: null, error: e.message });
}
}
// Summary
const success = results.filter(r => r.result && r.result.success).length;
const failed = results.filter(r => r.result && !r.result.success).length;
const errors = results.filter(r => !r.result).length;
const total = results.length;
console.log(`\n═══════════════════════════════════════════`);
console.log(`汇总: ${total} 张 | ✅ ${success} | ❌ ${failed} | 💥 ${errors}`);
console.log(`成功率: ${(success / total * 100).toFixed(1)}%`);
// Print failures detail
const failures = results.filter(r => r.result && !r.result.success);
if (failures.length > 0) {
console.log(`\n失败详情:`);
for (const f of failures) {
console.log(` ${f.fname}: [${f.result.errorCode}] ${f.result.errorMessage}`);
}
}
process.exit(0);
}
main();