差值平方和匹配_纯前端实现图片的模板匹配

基础介绍

模板匹配是指在当前图像A里寻找与图像B最相似的部分,本文中将图像A称为模板图像,将图像B称为搜索匹配图像。

引言:一般在Opencv里实现此种功能非常方便:直接调用

result = cv2.matchTemplate(templ, search, method)
  • templ 为原始图像
  • search 为搜索匹配图像,它的尺寸必须小于或等于原始图像
  • method 表示匹配方式

method一般取值:

type CompareWay =| "CV_TM_SQDIFF"| "CV_TM_SQDIFF_NORMED"| "CV_TM_CCORR"| "CV_TM_CCORR_NORMED"| "CV_TM_CCOEFF"| "CV_TM_CCOEFF_NORMED";

当然这里我们不是主要讲Opencv的api的,只是单独提出来,说明在前端实现对应的算法,就能进行模板匹配。

比如以CV_TM_SQDIFF算法为例:

  1. 遍历的起始坐标从原图A的左数第1个像素值开始
  2. 以搜索匹配B图的大小(w * h)匹配比较原图上对应空间上(w * h)的像素值
  3. 依次进行A图右移一像素去匹配B图,直到A图右侧(w)小于B图的w,然后换行再匹配
  4. 重复进行到A图距离底部不支持h大于B图的高度
  5. 最后找出最小误差值

我们的目标是实现这两张图的匹配:

5716d2c36017e333967ab618594681c5.png

b1c22a03f169d6ea2189519c863bddc5.png

这里实现对应的js算法

/*** 差值平方和匹配 CV_TM_SQDIFF* @param template 匹配的图片灰度值[x,x,x,...] w * h 长度的灰度图片数据* @param search 搜索的图片灰度值[x,x,x,...] w * h 长度的灰度图片数据* @param tWidth 匹配图片的width* @param tHeight 匹配图片的height* @param sWidth 搜索图片的width* @param sHeight 搜索图片的height*/
const cvTmSqDiff = (template, search, tWidth, tHeight, sWidth, sHeight) => {let minValue = Infinity;let x = -1;let y = -1;for (let th = 0; th < tHeight; th += 1) {for (let tW = 0; tW < tWidth; tW += 1) {if (tW + sWidth > tWidth || th + sHeight > tHeight) {continue;}let sum = 0;for (let sH = 0; sH < sHeight; sH += 1) {for (let sW = 0; sW < sWidth; sW += 1) {const tValue = template[(th + sH) * tWidth + tW + sW];const sValue = search[sH * sWidth + sW];sum += (tValue - sValue) * (tValue - sValue);}}if (minValue > sum) {minValue = sum;x = tW;y = th;}if (sum === 0) {return { x, y };}}}return { x, y };
};

因此根据上述算法的可行性,我们可以先将A图和B图进行RGB值转Gary值: 借鉴OpenCV中的转换方式

Gray = 0.299*r + 0.587*g + 0.114*b

再将转换好A图和B图的灰度值进行匹配比较:

const {x, y} = cvTmSqDiff(template, search, tWidth, tHeight, sWidth, sHeight);

得到的xy则是在原图A上的对应匹配成功的坐标,加上对应B图的大小,我们则可以在原图的基础上画出一个矩形框表示匹配的区域:

c1ceff22be1da67d56d425439fc01b5b.png

前端分步实现

上面大概讲了匹配的大致实现思路,下面开始正式的js代码实现:

  • 1、加载原图A和原图B
Promise.all([imgLoader("./lena.png"), imgLoader("./search.png")]).then((values: any) => {...}
);
  • 2、得到图片数据的rgb值,并转化为灰度值
Promise.all([getImageData(values[0]), getImageData(values[1])]).then((dataValues: any) => {const model = rgbToGary(dataValues[0]);const search = rgbToGary(dataValues[1]);...}
);
  • 3、获取对应的匹配坐标
const posi = getTemplatePos(model,search,dataValues[0].width,dataValues[0].height,dataValues[1].width,dataValues[1].height,"CV_TM_CCOEFF_NORMED"
);
  • 4、绘制原图和匹配到矩形框
const canvas = document.createElement("canvas");
canvas.width = dataValues[0].width;
canvas.height = dataValues[0].height;
const ctx = canvas.getContext("2d");ctx.drawImage(values[0], 0, 0);
ctx.strokeStyle = "red";
ctx.strokeRect(posi.x,posi.y,dataValues[1].width,dataValues[1].height
);
document.body.appendChild(canvas);

上述所用的的函数imgLoader getImageData rgbToGary getTemplatePos 都可以在这里找到xy-imageloader

也可以npm安装:npm i xy-imageloader

完整代码

import imgLoader, { getImageData, rgbToGary } from "xy-imageloader";
import { getTemplatePos } from "xy-imageloader/lib/utils";
Promise.all([imgLoader("./lena.png"), imgLoader("./search.png")]).then((values: any) => {Promise.all([getImageData(values[0]), getImageData(values[1])]).then((dataValues: any) => {const model = rgbToGary(dataValues[0]);const search = rgbToGary(dataValues[1]);const posi = getTemplatePos(model,search,dataValues[0].width,dataValues[0].height,dataValues[1].width,dataValues[1].height,"CV_TM_CCOEFF_NORMED");const canvas = document.createElement("canvas");canvas.width = dataValues[0].width;canvas.height = dataValues[0].height;const ctx = canvas.getContext("2d");ctx.drawImage(values[0], 0, 0);ctx.strokeStyle = "red";ctx.strokeRect(posi.x,posi.y,dataValues[1].width,dataValues[1].height);document.body.appendChild(canvas);});}
);

附算法思想:

* CV_TM_SQDIFF

9d67763fb7da6a597289f66b10159c5a.png
  • CV_TM_SQDIFF_NORMED

738b33955fe4d6d8400ec3bfb47df945.png
  • CV_TM_CCORR

e0ede50c0f63c44290abf3af1fae329d.png
  • CV_TM_CCORR_NORMED

4fe0c681e7b27eb6b724e9f4bfe898f6.png
  • CV_TM_CCOEFF

0769b98b9696663f84eab7ae7e6f28db.png
  • CV_TM_CCOEFF_NORMED

5bfc05de6fb7837beb49dcb8ad1fad8c.png
算法具体实现可参考 xy-imageloader

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/388981.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝牙耳机音量大解决办法_长时间使用蓝牙耳机的危害这么大?我们到底该选什么蓝牙耳机呢?...

蓝牙耳机避免了耳机线缠结&#xff0c;使人活动更自由&#xff0c;给人们带来了更加方便、舒适的听觉体验。但近日&#xff0c;英国《每日邮报》刊文表示&#xff0c;蓝牙耳机可能会危害人体健康。美国加州大学伯克利分校公共健康教授乔尔莫斯科维茨博士表示&#xff0c;已有研…

spotify 数据分析_我的Spotify流历史分析

spotify 数据分析Spotisis /spo-ti-sis/ noun The analysis of one’s Spotify streaming history using Python.Spotisis / spo-ti-sis / 名词使用Python分析一个人的Spotify流历史。 I was reading through a lot of data science related guides and project ideas when I …

intellig idea中jsp或html数据没有自动保存和更换字体

主题一:保存数据jsp intellig idea是自动保存数据的,看到没有保存 解决方案&#xff1a; 成功解决 主题二:更换字体: 或者快捷键CtelAlts 成功解决 转载于:https://www.cnblogs.com/weibanggang/p/9398498.html

java 环境变量

1.确保安装jrd jdk 2.环境变量配置 (1)新建->变量名"JAVA_HOME"&#xff0c;变量值"C:\Java\jdk1.8.0_05"&#xff08;JDK的安装路径&#xff09; (2)编辑->变量名"Path"&#xff0c;在原变量值的最后面加上“;%JAVA_HOME%\bin;%JAVA_HOME…

陆涛喜欢夏琳吗_夏琳·香布利斯(Charlene Chambliss):从心理学到自然语言处理和应用研究

陆涛喜欢夏琳吗技术系列中的女性 (WOMEN IN TECHNOLOGY SERIES) Interest in data science has been exponentially increasing over the past decade, and more and more people are working towards making a career switch into the field. In 2020, articles and YouTube v…

【angularJS】简介

简介 AngularJS 是一个 JavaScript 框架。它可通过 <script> 标签添加到 HTML 页面。 AngularJS 通过 指令 扩展了 HTML&#xff0c;且通过 表达式 绑定数据到 HTML。 AngularJS 是一个 JavaScript 框架。它是一个以 JavaScript 编写的库。 AngularJS 是以一个 JavaScrip…

纹个鸡儿天才小熊猫_给熊猫用户的5个提示

纹个鸡儿天才小熊猫A popular Python library used by those working with data is pandas, an easy and flexible data manipulation and analysis library. There are a myriad of awesome methods and functions in pandas, some of which are probably less well-known tha…

用户与用户组管理

linux最优秀的地方之一&#xff0c;就在于他的多用用户、多任务环境。 用户及用户组的概念 1、文件所有者 由于linux是一个多用户、多任务的系统。因此可能常常会有很多人同时使用这台主机来进行工作的情况发生&#xff0c;为了考虑每个人的隐私权以及每个人的喜好的工作环境&a…

代码 抠图_3 行 Python 代码 5 秒抠图的 AI 神器,根本无需 PS,附教程

曾几何时&#xff0c;「抠图」是一个难度系数想当高的活儿&#xff0c;但今天要介绍的这款神工具&#xff0c;只要 3 行代码 5 秒钟就可以完成高精度抠图&#xff0c;甚至都不用会代码&#xff0c;点两下鼠标就完成了。感受下这款抠图工具抠地有多精细&#xff1a;是不是很赞&a…

python函数使用易错举例

关于嵌套&#xff1a; 嵌套使用中&#xff0c; retrun inner ---> 返回的是函数的地址 retrun inner() &#xff1a; ---> 运行inner()函数 ---> 运行inner()函数后的返回值a&#xff08;假设&#xff09;返回上级 --> retrun inner()得到返回值a 如…

图像离群值_什么是离群值?

图像离群值你是&#xff01; (You are!) Actually not. This is not a text about you.其实并不是。 这不是关于您的文字。 But, as Gladwell puts it in Outliers, if you find yourself being that type of outlier, you’re quite lucky. And rare.但是&#xff0c;正如Gla…

混合模型和EM---混合高斯

2019独角兽企业重金招聘Python工程师标准>>> 混合高斯 最大似然 用于高斯混合模型的EM 转载于:https://my.oschina.net/liyangke/blog/2986520

Python学习---django知识补充之CBV

Django知识补充之CBV Django: url --> def函数 FBV[function based view] 用函数和URL进行匹配 url --> 类 CBV[function based view] 用类和URL进行匹配 POSTMAN插件 http://blog.csdn.net/zzy1078689276/article/details/77528249 基于CBV的登…

蓝图解锁怎么用_[UE4蓝图][Materials]虚幻4中可互动的雪地材质完整实现(一)

不说废话&#xff0c;先上个演示图最终成果&#xff08;脚印&#xff0c;雪地可慢慢恢复&#xff0c;地形可控制&#xff09;主要原理&#xff08;白话文&#xff09;&#xff1a;假如你头上是块白色并且可以透视的平地&#xff0c;来了个非洲兄弟踩上面&#xff0c;你拿起单反…

数据预处理工具_数据预处理

数据预处理工具As the title states this is the last project from Udacity Nanodegree. The goal of this project is to analyze demographics data for customers of a mail-order sales company in Germany.如标题所示&#xff0c;这是Udacity Nanodegree的最后一个项目。…

自考数据结构和数据结构导论_我跳过大学自学数据科学

自考数据结构和数据结构导论A few months back, I decided I wanted to learn data science. In order to do this, I skipped an entire semester of my data science major.几个月前&#xff0c;我决定要学习数据科学。 为此&#xff0c; 我跳过了数据科学专业的整个学期。 …

十三、原生爬虫实战

一、简单实例 1、需求&#xff1a;爬取熊猫直播某类主播人气排行 2、了解网站结构 分类——英雄联盟——"观看人数" 3、找到有用的信息 二、整理爬虫常规思路 1、使用工具chrome——F12——element——箭头——定位目标元素 目标元素&#xff1a;主播名字&#xff0c…

归一化 均值归一化_归一化折现累积收益

归一化 均值归一化Do you remember the awkward moment when someone you had a good conversation with forgets your name? In this day and age we have a new standard, an expectation. And when the expectation is not met the feeling is not far off being asked “w…

sqlserver垮库查询_Oracle和SQLServer中实现跨库查询

一、在SQLServer中连接另一个SQLServer库数据在SQL中&#xff0c;要想在本地库中查询另一个数据库中的数据表时&#xff0c;可以创建一个链接服务器&#xff1a;EXEC master.dbo.sp_addlinkedserver server N别名, srvproductN库名,providerNSQLOLEDB, datasrcN服务器地址EXEC…

机器学习实践三---神经网络学习

Neural Networks 在这个练习中&#xff0c;将实现神经网络BP算法,练习的内容是手写数字识别。Visualizing the data 这次数据还是5000个样本&#xff0c;每个样本是一张20*20的灰度图片fig, ax_array plt.subplots(nrows10, ncols10, figsize(6, 4))for row in range(10):fo…