1种获取图像相似度的方法

//欧几里得算法 求两个数a、b的最大公约数
function gcd(a,b){
  return b===0?a:gcd(b,a%b)
}
//获取一个位置的相似度
function getOneSame(x,y,rect1,rect2){
  let endn,n,i;
  const arrX=[]
  const arrXF=[]

  endn=(x+1)*rect2.width;
  n=x*rect2.width;
  i=parseInt(n/rect1.width);
  while(n<endn){
    arrX.push(i)
    i++;
    const pren=n;
    n=Math.min(i*rect1.width,endn)
    arrXF.push(n-pren)
  }
  const arrY=[]
  const arrYF=[]
  endn=(y+1)*rect2.height
  n=y*rect2.height;
  i=parseInt(n/rect1.height);
  while(n<endn){
    arrY.push(i)
    i++;
    const pren=n;
    n=Math.min(i*rect1.height,endn)
    arrYF.push(n-pren)
  }
  const k = y*rect1.width + x;
  let fz=0;
  let fm=rect2.width*rect2.height;
  arrY.forEach(function (y2,ny) {
    arrX.forEach(function (x2,nx) {
      const k2 = y2*rect2.width + x2;
      if(rect1.data[k]===rect2.data[k2]){
        fz=fz+arrYF[ny]*arrXF[nx];
      }
    })
  })
  return [fz,fm]
}

//获取相似度
function getSameByRect(rect1,rect2){
  let fArr;
  let fm=rect1.width*rect1.height;
  for(let y=0;y<rect1.height;y++){
    for(let x=0;x<rect1.width;x++){
      const arr=getOneSame(x,y,rect1,rect2)
      if(!fArr){
        fArr=arr;
      }else{
        fArr[0]=fArr[0]*arr[1]+fArr[1]*arr[0];
        fArr[1]=fArr[1]*arr[1];
        const g=gcd(fArr[0],fArr[1])
        fArr[0]=fArr[0]/g;
        fArr[1]=fArr[1]/g;
      }
    }
  }
  fArr[1]=fArr[1]*fm;
  return fArr[0]/fArr[1]
}

function getSquareRect(rect1) {
  if(rect1.width>rect1.height){
    const top=(rect1.width-rect1.height)>>1;
    const bottom=rect1.height+top;
    const nRect1={
      rect1.width,
      height:rect1.width,
      data:[]
    }
    console.log(top,bottom)
    for(let y=0;y<nRect1.height;y++){
      for(let x=0;x<nRect1.width;x++){
        if(y<top){
          nRect1.data.push(undefined);
        }else if(y<bottom){
          nRect1.data.push(rect1.data[(y-top)*rect1.width+x]);
        }else{
          nRect1.data.push(undefined);
        }
      }
    }
    return nRect1;
  }else if(rect1.width<rect1.height){
    const top=(rect1.height-rect1.width)>>1;
    const bottom=rect1.width+top;
    const nRect1={
      rect1.height,
      height:rect1.height,
      data:[]
    }
    console.log(top,bottom)
    for(let y=0;y<nRect1.height;y++){
      for(let x=0;x<nRect1.width;x++){
        if(x<top){
          nRect1.data.push(undefined);
        }else if(x<bottom){
          nRect1.data.push(rect1.data[y*rect1.width+(x-top)]);
        }else{
          nRect1.data.push(undefined);
        }
      }
    }
    return nRect1;
  }
  return rect1;
}

function getSimilarityByRect(rect1,rect2) {
  const nrect1=getSquareRect(rect1)
  const nrect2=getSquareRect(rect2)
  const same=getSameByRect(nrect1,nrect2)
  return 1-same;
}
const dis=getSimilarityByRect({
  2,
  height:1,
  data:[1,0]
},{
  3,
  height:1,
  data:[1,1,0]
})
console.log(dis)

  

原文地址:https://www.cnblogs.com/caoke/p/14764360.html