| 12345678910111213141516171819202122232425262728293031323334 |
- 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<a.length;i++,j+=4)a[i]=.299*d[j]+.587*d[j+1]+.114*d[j+2]; return a; }
- function grad(a,w,h) { const g=new Float32Array(w*h); for(let y=1;y<h-1;y++)for(let x=1;x<w-1;x++){const dx=a[y*w+x+1]-a[y*w+x-1],dy=a[(y+1)*w+x]-a[(y-1)*w+x];g[y*w+x]=Math.sqrt(dx*dx+dy*dy);}return g; }
- (async()=>{
- 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(sw<tw0||sh<th0)continue;
- const sg=grad(gray(sim),sw,sh); const step=2; let best={score:-2};
- for(let y=1;y<=sh-th0-1;y+=step){
- for(let x=1;x<=sw-tw0-1;x+=step){
- let sum=0,sq=0,dot=0;
- for(let j=0;j<th0;j++)for(let i=0;i<tw0;i++){const v=sg[(y+j)*sw+x+i];sum+=v;sq+=v*v;dot+=v*(rg[j*tw0+i]-rm);}
- const n=tw0*th0; const den=Math.sqrt(rt*(sq-sum*sum/n)); const score=den>0?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});
|