基础介绍

模板匹配是指在当前图像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. 最后找出最小误差值

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

这里实现对应的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图的大小,我们则可以在原图的基础上画出一个矩形框表示匹配的区域:

前端分步实现

上面大概讲了匹配的大致实现思路,下面开始正式的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

  • CV_TM_SQDIFF_NORMED
  • CV_TM_CCORR
  • CV_TM_CCORR_NORMED
  • CV_TM_CCOEFF
  • CV_TM_CCOEFF_NORMED

算法具体实现可参考 xy-imageloader

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

  1. 差值平方和匹配_机器学习实战 | 简单目标识别与意图分析之模板匹配

    (点击上方快速关注并设置为星标,一起学Python) 一天,我正在学校楼下撸猫,同学发来消息,他的老师给了他一个研究课题,大致的方向是对图片或者视频里面的内容进行识别,然后判断意图,而且举了个例子,两 ...

  2. cropper.js 图像旋转问题_JavaScript开源良心插件,纯前端网页图片剪裁插件——cropperjs...

    介绍 cropperjs是一款基于JavaScript的网页端图片裁剪插件,可能相对于图片预览来说,图片的裁剪使用场景貌似并不是很多,但是图片预览插件又要比裁剪插件容易找到,而且从实现难度上来说也不及 ...

  3. 纯前端实现图片上传功能

    纯前端实现图片上传功能,告别后端formData上传 使用ElementUI中的upload组件+腾讯云实现简单的图片上传功能 了解了upload的基本属性之后我们要开始上硬菜了 使用ElementU ...

  4. js固定表格行列_纯前端表格控件SpreadJS V14.0发布:组件化编辑器+数据透视表

    SpreadJS 是一款基于 HTML5 的纯前端表格控件,兼容 450 种以上的 Excel 公式,具备"高性能.跨平台.与 Excel 高度兼容"的产品特性,可为用户提供高度类 ...

  5. autojs遍历当前页面所有控件_纯前端表格控件SpreadJS V14.0发布:组件化编辑器+数据透视表 - 葡萄城开发工具...

    SpreadJS 是一款基于 HTML5 的纯前端表格控件,兼容 450 种以上的 Excel 公式,具备"高性能.跨平台.与 Excel 高度兼容"的产品特性,可为用户提供高度类 ...

  6. java数据透视表插件_纯前端表格控件SpreadJS:新增数据透视表插件等,完美呈现强大的Excel数据分析能力...

    SpreadJS是一款基于 HTML5 的纯前端电子表格控件,兼容 450 种以上的 Excel 公式,凭借其 "高性能.跨平台.与 Excel 高度兼容"的产品特性,备受以华为. ...

  7. c# 差值 获取时间_详解C# TimeSpan 计算时间差(时间间隔)

    TimeSpan 结构  表示一个时间间隔. 命名空间:System 程序集:mscorlib(在 mscorlib.dll 中) 说明: 1.DateTime值类型代表了一个从公元0001年1月1日 ...

  8. 纯前端实现图片背景透明化

    前言 不论是做一些2d的小游戏,或者制作小图标,或者抠图都需要用到这个功能,对图片的背景进行透明化,是我们经常需要用到的一个功能. 通常情况下我们都会去下载PS或者美图秀秀这样的软件去制作. 但是我真 ...

  9. JS魔法堂之实战:纯前端的图片预览

    一.前言 图片上传是一个普通不过的功能,而图片预览就是就是上传功能中必不可少的子功能了.在这之前,我曾经通过订阅input[type=file]元素的 onchange事件,一旦更改路径则将图片上传至 ...

最新文章

  1. App Tracking Transparency被拒解决
  2. [Python正则表达式] 字符串中xml标签的匹配
  3. 燕山大学计算机专业研究生怎么样,求助大家!重庆邮电大学计算机专业的研究生值得一读吗?...
  4. 随机数发生器怎么用_用随机数发生器射击自己的脚
  5. TensorFlow Hub介绍:TensorFlow中可重用的机器学习模块库
  6. android 全局 窗口,学习笔记:WindowManager显示Android全局悬浮窗口
  7. strcmp() Anyone? UVA - 11732 左孩子右兄弟Trie/计数
  8. SQL Server 数据库之索引
  9. 联想拯救者P7000八代I7 8750H 可以安装WIN7系统吗
  10. DOS windows PE三者有什么区别
  11. FPGA-09FPGA-RGB TFT-LCD显示
  12. 有关于图片压缩大小--尺寸裁剪 和 压缩系数
  13. 与朋友分享的生活日记
  14. Ubuntu开机无桌面图标
  15. background属性用法总结
  16. HDU 4415 Assassin’s Creed
  17. ElementUI 树形结构默认展示某个节点
  18. 2021-07-18大学 复习网课 视频 (倍速详细篇)
  19. 《人月神话》8 胸有成竹(Chaptor 8.Calling the Shot -The Mythical Man-Month)
  20. 如何发布自己的npm包(超详细步骤,博主都在用)

热门文章

  1. Linux_linux常用工具(git,vim ,gcc ,gdb,权限)超详解
  2. ubuntu14.04 通过PPA 安装ffmpeg
  3. CodeForces - 1152B二进制+思维
  4. x86异常处理与中断机制(3)中断处理过程
  5. css知识笔记(二)——盒子模型
  6. JAVA List集合转Page(分页对象)
  7. 洛谷 P2919 [USACO08NOV]守护农场Guarding the Farm
  8. 跳过 centos部署 webpy的各种坑
  9. node搭建服务器,写接口,调接口,跨域
  10. jenkins svn tomcat ant自动部署