差值平方和匹配_纯前端实现图片的模板匹配
生活随笔
收集整理的這篇文章主要介紹了
差值平方和匹配_纯前端实现图片的模板匹配
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
基礎介紹
模板匹配是指在當前圖像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算法為例:
我們的目標是實現這兩張圖的匹配:
這里實現對應的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);得到的x、y則是在原圖A上的對應匹配成功的坐標,加上對應B圖的大小,我們則可以在原圖的基礎上畫出一個矩形框表示匹配的區域:
前端分步實現
上面大概講了匹配的大致實現思路,下面開始正式的js代碼實現:
- 1、加載原圖A和原圖B
- 2、得到圖片數據的rgb值,并轉化為灰度值
- 3、獲取對應的匹配坐標
- 4、繪制原圖和匹配到矩形框
上述所用的的函數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
總結
以上是生活随笔為你收集整理的差值平方和匹配_纯前端实现图片的模板匹配的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到自己抢劫是什么意思
- 下一篇: 梦到吃韭菜盒子怎么回事