最近换季容易感冒,小伙伴们及各位大佬一定要注意身体,每年的这个时候都要渡一次劫。
进博会马上就要来临,最近公司在做一个关于进博会的活动。我是不负责这个项目的。但是看到我们给甲方的稿子甲方老是不满意,老是让修改,我就想参与一下,看看问题到底是出在哪里。
是这样的,我先来简单说下活动的流程,用户刚进入页面呢,会给你展现一个图形(底图),用户要在这个底图上画出相应的图形。然后对比相似度进行奖励。
画图阶段就不多说了,我们直奔重点,这个活动的关键点在于如何进行用户画出的图和底图进行相似度的比较,大家都清楚底图是死的,然而用户画的一坨坨可是大小形都不一样的。我在想,刚开始我直接的想法就是把底图转成一段线段,用用户画出的线段走过的点进行比较,存两个数组进行比较,给一个误差值,只要不超过误差值就算是相似的。但是转头一想,你丫的不对啊,如果说用户超出你的误差值,画的图比你的底图要大很多或者小很多,但是形状上又很相似,那你的程序就是错误判断。后来,我就在想有没有另一种实现方案,如果把他转成图片会怎么样,他该如何进行相似度的比较,接下来就是我们今天的要讲的如何进行图片相似度的比较,我也不解释了,做法我是参考网上的。目前我能想到的比较合适的就这一版解决方案。之所以发这篇帖子是因为我想得到这里大神推荐的更优方案。不说了,直接贴代码了。逻辑你们自己理解下吧。
function searchImage(image1, image2, tmplw, tmplh) { var canvas = document.createElement('canvas'), ctx = canvas.getContext('2d'), sw = image1.width, // 原图宽度 sh = image1.height, // 原图高度 tw = tmplw || 8, // 模板宽度 th = tmplh || 8; // 模板高度canvas.width = tw; canvas.height = th;ctx.drawImage(image1, 0, 0, sw, sh, 0, 0, tw, th);var pixels = ctx.getImageData(0, 0, tw, th);pixels = toGrayBinary(pixels, true, null, true);var canvas2 = document.createElement('canvas'); var ctx2 = canvas2.getContext('2d');canvas2.width = tw; canvas2.height = th;ctx2.drawImage(image2, 0, 0, image2.width, image2.height, 0, 0, tw, th);var pixels2 = ctx2.getImageData(0, 0, tw, th);pixels2 = toGrayBinary(pixels2, true, null, true);var similar = 0;for (var i = 0, len = tw * th; i < len; i++) { if (pixels[i] == pixels2[i]) similar++; }similar = (similar / (tw * th)) * 100;return similar;
}
// 像素数据,是否二值化(bool),二值化闵值(0-255),是否返回二值化后序列(bool)
function toGrayBinary(pixels, binary, value, sn) { var r, g, b, g, avg = 0, len = pixels.data.length, s = '';for (var i = 0; i < len; i += 4) { avg += (.299 * pixels.data[i] + .587 * pixels.data[i + 1] + .114 * pixels.data[i + 2]); }avg /= (len / 4);for (var i = 0; i < len; i += 4) { r = .299 * pixels.data[i], g = .587 * pixels.data[i + 1], b = .114 * pixels.data[i + 2]; if (binary) { if ((r + g + b) >= (value || avg)) { g = 255; if (sn) s += '1'; } else { g = 0; if (sn) s += '0'; } g = (r + g + b) > (value || avg) ? 255 : 0; } else { g = r + g + b; }pixels.data[i] = g, pixels.data[i + 1] = g, pixels.data[i + 2] = g; }if (sn) return s; else return pixels;
}复制代码
在此欢迎各位大佬指正及推荐更优方案。本人不才,只能借力发力。还望以后能多多交流。互加关注➕