颜色分类,之后补充图片成矩形,找出左上角点,之后找出{ r: 212, c: 41, w: 78, h: 80 };r为行y,c为列x,w为宽度,h为高度;
const getPixels = require("get-pixels") function getPixelsSync(filename){ return new Promise(function (resolve,reject) { getPixels(filename, function(err, pixels) { if(err) { console.log("Bad image path") reject(err) return } resolve(pixels) }) }) } const {Matrix,Fraction,Point,Line} = require("./utils/math"); function getColor(x,y,pixels) { return [ pixels.data[x*4+y*4*pixels.shape[0]], pixels.data[x*4+1+y*4*pixels.shape[0]], pixels.data[x*4+2+y*4*pixels.shape[0]], pixels.data[x*4+3+y*4*pixels.shape[0]] ] } function isNearColor(color1,color2){ if((Math.abs(color1[0]-color2[0])+Math.abs(color1[1]-color2[1])+Math.abs(color1[2]-color2[2])+Math.abs(color1[3]-color2[3]))<75){ return 1; } return 0; } //将颜色分成多少种 maxTagNum是限制最大多少种 function sortMatColor(mat1,maxTagNum){ function sortColor(num) { let map={} let maxKey; mat1.rowEach(function (item,r,c) { if(typeof item==="number"){return;} const key=item.join(',') if(map[key]===undefined){ map[key]=0; } map[key]++; if(!maxKey){ maxKey=key; }else if(map[maxKey]<map[key]){ maxKey=key; } }) let bgColor=maxKey.split(',').map((item)=>parseInt(item)); let running=false; mat1.rowMap(function (item,r,c) { if(typeof item==="number"){return item;} if(maxTagNum-1<=num||isNearColor(item,bgColor)){ return num; }else{ running=true; return item; } }) if(running){ return sortColor(num+1); } return num+1; } return sortColor(0); } //补图为矩形 function addOne(mat1,r,c){ function addTop(mat1,r,c) { //左上角、右上角 if(mat1.getItem(r-1,c)!==1&&(mat1.getItem(r-1,c+1)===1||mat1.getItem(r-1,c-1)===1)){ mat1.setItem(r-1,c,1) addTop(mat1,r-1,c) } //左下角、右下角 if(mat1.getItem(r+1,c)!==1&&(mat1.getItem(r+1,c+1)===1||mat1.getItem(r+1,c-1)===1)){ mat1.setItem(r+1,c,1) addTop(mat1,r+1,c) } if(mat1.getItem(r,c-1)!==1&&(mat1.getItem(r-1,c-1)===1||mat1.getItem(r+1,c-1)===1)){ mat1.setItem(r,c-1,1) addTop(mat1,r,c-1) } if(mat1.getItem(r,c+1)!==1&&(mat1.getItem(r+1,c+1)===1||mat1.getItem(r-1,c+1)===1)){ mat1.setItem(r,c+1,1) addTop(mat1,r,c+1) } } addTop(mat1,r,c); } //根据左上角,找出矩形的宽高 function findConner(mat1,r,c){ let w=0,h=0; while (mat1.getItem(r,c+w+1)===1){ w=w+1; } while (mat1.getItem(r+h+1,c)===1){ h=h+1; } return { r,c,w,h } } async function init() { const pixels=await getPixelsSync('1.jpg'); console.log(pixels) const [w,h]=pixels.shape; //1定义矩阵 const mat1=new Matrix([],h,w); mat1.rowMap(function (item,r,c) { return getColor(c,r,pixels); }) sortMatColor(mat1,3); mat1.rowEach(function (item,r,c) { if(item===1){ addOne(mat1,r,c) } }) const arr1=[] mat1.rowEach(function (item,r,c) { //左上 if(item===1&&mat1.getItem(r-1,c)!==1&&mat1.getItem(r,c-1)!==1){ arr1.push({r,c}) } }) const arr2=arr1.map(function ({r,c}) { return findConner(mat1,r,c) }) console.log(arr2) return arr2; } init(); // [ { r: 212, c: 41, w: 78, h: 80 }, // { r: 213, c: 128, w: 80, h: 78 }, // { r: 213, c: 306, w: 77, h: 79 }, // { r: 213, c: 394, w: 79, h: 80 }, // { r: 214, c: 216, w: 80, h: 79 }, // { r: 316, c: 51, w: 69, h: 79 }, // { r: 316, c: 222, w: 69, h: 18 }, // { r: 317, c: 308, w: 75, h: 36 }, // { r: 318, c: 398, w: 71, h: 77 }, // { r: 319, c: 129, w: 78, h: 77 }, // { r: 330, c: 40, w: 9, h: 34 }, // { r: 338, c: 216, w: 77, h: 58 }, // { r: 357, c: 309, w: 72, h: 38 } ]