coarse-search.cjs 2.0 KB

12345678910111213141516171819202122232425262728293031323334
  1. const fs = require('fs');
  2. const Jimp = require('jimp');
  3. const [referencePath, sourcePath, outputPath, scalesText] = process.argv.slice(2);
  4. const scales = scalesText.split(',').map(Number);
  5. const tw0 = 40, th0 = 35;
  6. const keep = [];
  7. function addHit(hit) {
  8. 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;
  9. keep.push(hit); keep.sort((a,b)=>b.score-a.score); if (keep.length > 30) keep.pop();
  10. }
  11. 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; }
  12. 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; }
  13. (async()=>{
  14. const ref=await Jimp.read(fs.readFileSync(referencePath));
  15. const src=await Jimp.read(sourcePath);
  16. const r=ref.clone().resize(tw0,th0); const rg=grad(gray(r),tw0,th0);
  17. 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);
  18. for(const scale of scales){
  19. const sim=src.clone().resize(Math.round(src.bitmap.width*scale),Math.round(src.bitmap.height*scale));
  20. const sw=sim.bitmap.width,sh=sim.bitmap.height; if(sw<tw0||sh<th0)continue;
  21. const sg=grad(gray(sim),sw,sh); const step=2; let best={score:-2};
  22. for(let y=1;y<=sh-th0-1;y+=step){
  23. for(let x=1;x<=sw-tw0-1;x+=step){
  24. let sum=0,sq=0,dot=0;
  25. 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);}
  26. const n=tw0*th0; const den=Math.sqrt(rt*(sq-sum*sum/n)); const score=den>0?dot/den:-1;
  27. if(score>best.score)best={score,x,y,scale,sourceX:x/scale,sourceY:y/scale};
  28. }
  29. }
  30. console.log(JSON.stringify(best)); addHit(best);
  31. }
  32. console.log('BEST '+JSON.stringify(keep));
  33. if(outputPath)fs.writeFileSync(outputPath,JSON.stringify(keep,null,2));
  34. })().catch(e=>{console.error(e);process.exitCode=1});