const fs = require('fs'); const Jimp = require('jimp'); const [referencePath, sourcePath, outputPath, scalesText] = process.argv.slice(2); const scales = scalesText.split(',').map(Number); const tw0 = 40, th0 = 35; const keep = []; function addHit(hit) { if (keep.some(v => Math.abs(v.x - hit.x) < tw0 && Math.abs(v.y - hit.y) < th0 && Math.abs(v.scale - hit.scale) < .08)) return; keep.push(hit); keep.sort((a,b)=>b.score-a.score); if (keep.length > 30) keep.pop(); } function gray(im) { const d=im.bitmap.data, a=new Float32Array(im.bitmap.width*im.bitmap.height); for(let i=0,j=0;i{ const ref=await Jimp.read(fs.readFileSync(referencePath)); const src=await Jimp.read(sourcePath); const r=ref.clone().resize(tw0,th0); const rg=grad(gray(r),tw0,th0); const vals=Array.from(rg); const rm=vals.reduce((a,b)=>a+b,0)/vals.length; let rt=0; for(const v of vals)rt+=(v-rm)*(v-rm); for(const scale of scales){ const sim=src.clone().resize(Math.round(src.bitmap.width*scale),Math.round(src.bitmap.height*scale)); const sw=sim.bitmap.width,sh=sim.bitmap.height; if(sw0?dot/den:-1; if(score>best.score)best={score,x,y,scale,sourceX:x/scale,sourceY:y/scale}; } } console.log(JSON.stringify(best)); addHit(best); } console.log('BEST '+JSON.stringify(keep)); if(outputPath)fs.writeFileSync(outputPath,JSON.stringify(keep,null,2)); })().catch(e=>{console.error(e);process.exitCode=1});