摘要:最近看了阮一峰老师的相似图片搜索的原理二,其中介绍了通过内容特征法来对比两个图片的相似性。不知道是不是哪步出错了,感觉用这个方法计算出来的结果并不理想
最近看了阮一峰老师的相似图片搜索的原理(二),其中介绍了通过内容特征法来对比两个图片的相似性。
大致步骤:
把图片都缩放到50x50大小
转成灰度图片
利用"大津法"(Otsu"s method)确定阈值
通过阈值再对图片进行二值化
对比两个图片对应位置像素,得出结果
接下来,看看用JS怎么实现上面的步骤,理论部分就不多介绍了,还是看相似图片搜索的原理(二)
首先,对图片数据进行操作当然要使用canvas,所以先创建一个画布和它的绘图上下文
const canvas = document.createElement("canvas") const context = canvas.getContext("2d")
把图片缩放渲染到画布,得到图片像素数据:
function toZoom() { canvas.width = 50 canvas.height = 50 const img = new Image img.onload = function () { context.drawImage(this, 0, 0, this.width, this.height, 0, 0, 50, 50) const imageData = context.getImageData(0, 0, 50, 50) } img.src = "test.jpg" }
图片灰度化,灰度就是图片每个像素的r、g、b设置相同的值,计算每个像素的值的方法有很多,这里使用加权算法:
function toGray() { const grayData = [] const data = imageData.data canvas.width = 50 canvas.height = 50 for (let i = 0; i < data.length; i += 4) { const gray = data[i] * .299 + data[i + 1] * .587 + data[i + 2] * .114 | 0 data[i] = data[i + 1] = data[i + 2] = gray grayData.push(gray) } context.putImageData(imageData, 0, 0) return grayData }
在对图片二值化,使之变成黑白图片之前,要先确定一个阈值,根据这个阈值对图片二值化,能使图片的轮廓最明显。
文章中提到了通过"大津法"(Otsu"s method)来求得这个阈值,并给了一个实例网站,提供了Java版算法,用JS改写:
function toOtsu() { let ptr = 0 let histData = Array(256).fill(0) // 记录0-256每个灰度值的数量,初始值为0 let total = grayData.length while (ptr < total) { let h = 0xFF & grayData[ptr++] histData[h]++ } let sum = 0 // 总数(灰度值x数量) for (let i = 0; i < 256; i++) { sum += i * histData[i] } let wB = 0 // 背景(小于阈值)的数量 let wF = 0 // 前景(大于阈值)的数量 let sumB = 0 // 背景图像(灰度x数量)总和 let varMax = 0 // 存储最大类间方差值 let threshold = 0 // 阈值 for (let t = 0; t < 256; t++) { wB += histData[t] // 背景(小于阈值)的数量累加 if (wB === 0) continue wF = total - wB // 前景(大于阈值)的数量累加 if (wF === 0) break sumB += t * histData[t] // 背景(灰度x数量)累加 let mB = sumB / wB // 背景(小于阈值)的平均灰度 let mF = (sum - sumB) / wF // 前景(大于阈值)的平均灰度 let varBetween = wB * wF * (mB - mF) ** 2 // 类间方差 if (varBetween > varMax) { varMax = varBetween threshold = t } } return threshold }
根据上面求得的阈值进行二值化,小于阈值的灰度值为0,大于阈值的灰度值为255:
function toBinary() { const threshold = toOtsu(grayData, index) const imageData = context.createImageData(50, 50) const data = imageData.data const temp = [] grayData.forEach((v, i) => { let gray = v > threshold ? 255 : 0 data[i * 4] = data[i * 4 + 1] = data[i * 4 + 2] = gray data[i * 4 + 3] = 255 temp.push(gray > 0 ? 0 : 1) }) canvas.width = 50 canvas.height = 50 context.putImageData(imageData, 0, 0) }
最后计算两个图像每个像素的值相同的占总数的百分比。
function toCompare() { let sameCount = 0 // img1_data // img2_data const total = img1_data.length for (let i = 0; i < total; i++) { sameCount += img1_data[i] === img2_data[i] } console.log((sameCount / total * 100).toLocaleString() + "%") }
不知道是不是哪步出错了,感觉用这个方法计算出来的结果并不理想
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/106306.html
摘要:文和,创意实验室创意技术专家在机器学习和计算机视觉领域,姿势预测或根据图像数据探测人体及其姿势的能力,堪称最令人兴奋而又最棘手的一个话题。使用,用户可以直接在浏览器中运行机器学习模型,无需服务器。 文 / Jane Friedhoff 和 Irene Alvarado,Google 创意实验室创意技术专家在机器学习和计算机视觉领域,姿势预测或根据图像数据探测人体及其姿势的能力,堪称最令人兴...
摘要:随着复杂和高效的神经网络架构的出现,卷积神经网络的性能已经优于传统的数字图像处理方法,如和。子网络由多个卷积层组成,而子网络由几个完全连接层组成。结论总而言之,模型用信号分析的角度为我们剖析了卷积神经网络。 随着复杂和高效的神经网络架构的出现,卷积神经网络(CNN)的性能已经优于传统的数字图像处理方法,如 SIFT 和 SURF。在计算机视觉领域,学者们开始将研究重点转移到 CNN,并相信 ...
摘要:特征匹配改变了生成器的损失函数,以最小化真实图像的特征与生成的图像之间的统计差异。我们建议读者检查上使用的损失函数和相应的性能,并通过实验验证来设置。相反,我们可能会将注意力转向寻找在生成器性能不佳时不具有接近零梯度的损失函数。 前 言GAN模型相比较于其他网络一直受困于三个问题的掣肘: 1. 不收敛;模型训练不稳定,收敛的慢,甚至不收敛; 2. mode collapse; 生成器产生的...
摘要:当前,很多学者和研究机构都尝试基于深度学习进行服装检索技术的探究与创新。下文将回顾三篇基于深度学习来解决跨域服装检索问题的文章。总的来说,以上深度学习方法的探索与创新都将为商品检索技术趋 摘要商品检索是一门综合了物体检测、 图像分类以及特征学习的技术。 近期, 很多研究者成功地将深度学习方法应用到这个领域。 本文对这些方法进行了总结, 然后概括地提出了商品特征学习框架以及垂类数据挖掘方式, ...
阅读 1503·2023-04-26 02:08
阅读 3089·2021-10-14 09:42
阅读 6956·2021-09-22 15:34
阅读 3205·2019-08-30 13:16
阅读 2682·2019-08-26 13:49
阅读 1318·2019-08-26 11:59
阅读 1214·2019-08-26 10:31
阅读 2117·2019-08-23 17:19