当前位置: 首页 > news >正文

【教程】Autojs使用OpenCV进行SIFT/BRISK等算法进行图像匹配

转载请注明出处:小锋学长生活大爆炸[xfxuezhang.cn]

        此代码可以替代内置的images.findImage函数使用,但可能会误匹配,如果是对匹配结果要求比较高的,还是得谨慎使用。


runtime.images.initOpenCvIfNeeded();
importClass(java.util.ArrayList);
importClass(java.util.List);
importClass(java.util.LinkedList);
importClass(org.opencv.imgproc.Imgproc);
importClass(org.opencv.imgcodecs.Imgcodecs);
importClass(org.opencv.core.Core);
importClass(org.opencv.core.Mat);
importClass(org.opencv.core.MatOfDMatch);
importClass(org.opencv.core.MatOfKeyPoint);
importClass(org.opencv.core.MatOfRect);
importClass(org.opencv.core.Size);
importClass(org.opencv.features2d.DescriptorMatcher);
importClass(org.opencv.features2d.Features2d);
importClass(org.opencv.features2d.SIFT);
importClass(org.opencv.features2d.ORB);
importClass(org.opencv.features2d.BRISK);
importClass(org.opencv.features2d.AKAZE);
importClass(org.opencv.features2d.BFMatcher);
importClass(org.opencv.core.MatOfPoint2f);
importClass(org.opencv.calib3d.Calib3d);
importClass(org.opencv.core.CvType);
importClass(org.opencv.core.Point);
importClass(org.opencv.core.Scalar);
importClass(org.opencv.core.MatOfByte);/** 用法示例:* var image1 = captureScreen();* var image2 = images.read('xxxx');* match(image1, image2);*/function match(img1, img2, method) {console.time("匹配耗时");// 指定特征点算法SIFTvar match_alg = null;if(method == 'sift') {match_alg = SIFT.create();}else if(method == 'orb') {match_alg = ORB.create();}else if(method == 'brisk') {match_alg = BRISK.create();}else {match_alg = AKAZE.create();}var bigTrainImage = Imgcodecs.imdecode(new MatOfByte(images.toBytes(img1)), Imgcodecs.IMREAD_UNCHANGED);var smallTrainImage = Imgcodecs.imdecode(new MatOfByte(images.toBytes(img2)), Imgcodecs.IMREAD_UNCHANGED);// 转灰度图// console.log("转灰度图");var big_trainImage_gray = new Mat(bigTrainImage.rows(), bigTrainImage.cols(), CvType.CV_8UC1);var small_trainImage_gray = new Mat(smallTrainImage.rows(), smallTrainImage.cols(), CvType.CV_8UC1);Imgproc.cvtColor(bigTrainImage, big_trainImage_gray, Imgproc.COLOR_BGR2GRAY);Imgproc.cvtColor(smallTrainImage, small_trainImage_gray, Imgproc.COLOR_BGR2GRAY);// 获取图片的特征点// console.log("detect");var big_keyPoints = new MatOfKeyPoint();var small_keyPoints = new MatOfKeyPoint();match_alg.detect(bigTrainImage, big_keyPoints);match_alg.detect(smallTrainImage, small_keyPoints);// 提取图片的特征点// console.log("compute");var big_trainDescription = new Mat(big_keyPoints.rows(), 128, CvType.CV_32FC1);var small_trainDescription = new Mat(small_keyPoints.rows(), 128, CvType.CV_32FC1);match_alg.compute(big_trainImage_gray, big_keyPoints, big_trainDescription);match_alg.compute(small_trainImage_gray, small_keyPoints, small_trainDescription);// console.log("matcher.train");var matcher = new BFMatcher();matcher.clear();var train_desc_collection = new ArrayList();train_desc_collection.add(big_trainDescription);// vector<Mat>train_desc_collection(1, trainDescription);matcher.add(train_desc_collection);matcher.train();// console.log("knnMatch");var matches = new ArrayList();matcher.knnMatch(small_trainDescription, matches, 2);//对匹配结果进行筛选,依据distance进行筛选// console.log("对匹配结果进行筛选");var goodMatches = new ArrayList();var nndrRatio = 0.8;var len = matches.size();for (var i = 0; i < len; i++) {var matchObj = matches.get(i);var dmatcharray = matchObj.toArray();var m1 = dmatcharray[0];var m2 = dmatcharray[1];if (m1.distance <= m2.distance * nndrRatio) {goodMatches.add(m1);}}var matchesPointCount = goodMatches.size();//当匹配后的特征点大于等于 4 个,则认为模板图在原图中,该值可以自行调整if (matchesPointCount >= 4) {log("模板图在原图匹配成功!");var templateKeyPoints = small_keyPoints;var originalKeyPoints = big_keyPoints;var templateKeyPointList = templateKeyPoints.toList();var originalKeyPointList = originalKeyPoints.toList();var objectPoints = new LinkedList();var scenePoints = new LinkedList();var goodMatchesList = goodMatches;var len = goodMatches.size();for (var i = 0; i < len; i++) {var goodMatch = goodMatches.get(i);objectPoints.addLast(templateKeyPointList.get(goodMatch.queryIdx).pt);scenePoints.addLast(originalKeyPointList.get(goodMatch.trainIdx).pt);}var objMatOfPoint2f = new MatOfPoint2f();objMatOfPoint2f.fromList(objectPoints);var scnMatOfPoint2f = new MatOfPoint2f();scnMatOfPoint2f.fromList(scenePoints);//使用 findHomography 寻找匹配上的关键点的变换var homography = Calib3d.findHomography(objMatOfPoint2f, scnMatOfPoint2f, Calib3d.RANSAC, 3);/*** 透视变换(Perspective Transformation)是将图片投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)。*/var templateCorners = new Mat(4, 1, CvType.CV_32FC2);var templateTransformResult = new Mat(4, 1, CvType.CV_32FC2);var templateImage = smallTrainImage;var doubleArr = util.java.array("double", 2);doubleArr[0] = 0;doubleArr[1] = 0;templateCorners.put(0, 0, doubleArr);doubleArr[0] = templateImage.cols();doubleArr[1] = 0;templateCorners.put(1, 0, doubleArr);doubleArr[0] = templateImage.cols();doubleArr[1] = templateImage.rows();templateCorners.put(2, 0, doubleArr);doubleArr[0] = 0;doubleArr[1] = templateImage.rows();templateCorners.put(3, 0, doubleArr);//使用 perspectiveTransform 将模板图进行透视变以矫正图象得到标准图片Core.perspectiveTransform(templateCorners, templateTransformResult, homography);//矩形四个顶点var pointA = templateTransformResult.get(0, 0);var pointB = templateTransformResult.get(1, 0);var pointC = templateTransformResult.get(2, 0);var pointD = templateTransformResult.get(3, 0);var y0 = Math.round(pointA[1])>0?Math.round(pointA[1]):0;var y1 = Math.round(pointC[1])>0?Math.round(pointC[1]):0;var x0 = Math.round(pointD[0])>0?Math.round(pointD[0]):0;var x1 = Math.round(pointB[0])>0?Math.round(pointB[0]):0;console.timeEnd("匹配耗时");return {x: x0, y: y0};} else {console.timeEnd("匹配耗时");log("模板图不在原图中!");return null;}
}

相关文章:

【教程】Autojs使用OpenCV进行SIFT/BRISK等算法进行图像匹配

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 此代码可以替代内置的images.findImage函数使用&#xff0c;但可能会误匹配&#xff0c;如果是对匹配结果要求比较高的&#xff0c;还是得谨慎使用。 runtime.images.initOpenCvIfNeeded(); importClass(java.uti…...

[庆国庆 迎国庆 发文]云计算的概念

庆国庆 迎国庆 国庆发文100%可得专属勋章 一年仅有一次哦 不要错过啦 去发布 https://activity.csdn.net/creatActivity?id10567&spm1011.2480.3001.6900 https://mp.csdn.net/edit?activity_id10567&spm1057.2600.3001.9674 云计算&#xff08;cloud computing&…...

计算机网络-计算机网络体系结构-概述,模型

目录 一、计算机网络概述 二、性能指标 速率 带宽 吞吐量 时延 往返时延RTT 利用率 三、计算机网络体系结构 分层结构 IOS模型 应用层-> 表示层-> 会话层-> 传输层-> 网络层-> 数据链路层-> 物理层-> TCP/IP模型 一、计算机网络概述 计…...

对示例程序spinner_asyncio.py进行修改使其能运行

学习《流畅的python》第18章 使用asyncio包处理并发&#xff0c;运行示例18-2 spinner_asyncio.py的时候&#xff0c;程序报错如下&#xff1a; D:\fluentPy\chapter17>python spinner_asyncio.py File "D:\fluentPy\chapter17\spinner_asyncio.py", line 30 …...

Linux命令(93)之head

linux命令之head 1.head介绍 linux命令head用来查看文件的前N行内容&#xff1b;默认head查看前10行 2.head用法 head [参数] 文件 head常用参数 参数说明-n从头显示N行&#xff0c;默认显示10行&#xff0c;可以不写-q隐藏文件名&#xff0c;在查看两个及以上文件名的情况…...

使用Visual Studio调试排查Windows系统程序audiodg.exe频繁弹出报错

VC常用功能开发汇总&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&#xff09;https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程&#xff08;专栏文章列表&#xff0c;欢迎订阅&#xff0c;持续更新...&a…...

WebSocket实战之六心跳重连机制

一、前言 WebSocket应用部署到生产环境&#xff0c;我们除了会碰到因为经过代理服务器无法连接的问题&#xff08;注&#xff1a;该问题可以通过搭建WSS来解决&#xff0c;具体配置请看 WebSocket实战之四WSS配置 &#xff09;&#xff0c;另外一个问题就是外网环境不稳定经常…...

Webpack 基础入门以及接入 CSS、Typescript、Babel

一、什么是 Webpack Webpack 是一款 JS 模块化开发的技术框架&#xff0c;其运作原理是将多个 JS 文件关联起来构成可运行的应用程序。 Webpack 拥有丰富的 plugins / loaders 插件生态圈&#xff0c;可以让 js 识别不同的语言如 .css, .scss, .sass, .json, .xml, .ts, .vue…...

postgresql-自增字段

postgresql-自增字段 标识列IdentitySerial类型Sequence序列 标识列Identity -- 测试表 create table t_user( -- 标识列自增字段user_id integer generated always as identity primary key,user_name varchar(50) not null unique );-- 自动生成序列 CREATE SEQUENCE public…...

SpringBoot中使用Servlet和Filter

为什么要把Servlet和Filter写在一起,因为使用方式很相似 两种方式 第一种,使用Servlet和Filter 使用Servlet 继承HttpServlet 注册Servlet 使用Filter 1.自定义过滤器 2.注册过滤器 这里注意一点 使用/**无效 至少我这2.4.5版本是这样 过滤所有请求用/* 那么其实还有…...

Monkey命令

shell, monkey, system, Android, 文件系统Monkey, 示例, 简介 一、Monkey测试简介 Monkey测试是Android平台自动化测试的一种手段&#xff0c;通过Monkey程序模拟用户触摸屏幕、滑动Trackball、按键等操作来对设备上的程序进行压 力测试&#xff0c;检测程序多久的时间会发生…...

力扣 -- 279. 完全平方数(完全背包问题)

解题步骤&#xff1a; 参考代码&#xff1a; 未优化代码&#xff1a; class Solution { public:int numSquares(int n) {const int INF0x3f3f3f3f;int msqrt(n);//多开一行&#xff0c;多开一列vector<vector<int>> dp(m1,vector<int>(n1));//初始化第一行…...

在将对象 => JSON格式时,无法序列化部分属性

问题现象: 在ssm项目中&#xff0c;一个controller返回Msg对象&#xff08;自定义对象&#xff0c;包含三个属性&#xff0c;int code&#xff1b;String msg&#xff1b;HashMap map&#xff1b;同时这三个属性都有对应的get和set方法&#xff09;&#xff0c;我的map属性里面…...

用python表格初级尝试

Excel&#xff0c;我的野心 当我输入3,2 就表示在第3行第2列。的单元格输入数据input输入表头 &#xff08;input内除了/&#xff0c;空格 回车 标点符号等 全部作为单元格分隔符&#xff09;由我设置input输入的是行or列 给选项 1. 行 2. 列默认回车或没输入值是列由我设置起…...

【单片机】16-LCD1602和12864显示器

1.LCD显示器相关背景 1.LCD简介 &#xff08;1&#xff09;显示器&#xff0c;常见显示器&#xff1a;电视&#xff0c;电脑 &#xff08;2&#xff09;LCD&#xff08;Liquid Crystal Display&#xff09;&#xff0c;液晶显示器&#xff0c;原理介绍 &#xff08;3&#xff…...

AUTOSAR从入门到精通-基于 CAN 总线的汽车发电机智能调节器(下)

目录 4.4.3 CAN 通信软件实现 汽车发电机智能调节器试验与结果分析 5.1 试验方案设计...

Windows下Tensorflow docker python开发环境搭建

前置条件 windows10 更新到较新的版本&#xff0c;硬件支持Hyper-V。 参考&#xff1a;https://learn.microsoft.com/zh-cn/windows/wsl/install 启用WSL 在Powershell中输入如下指令&#xff1a; dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsys…...

idea常用快捷键 idea搜索快捷键

常用快捷键 IntelliJ IDEA 是一款流行的 Java 集成开发环境&#xff08;IDE&#xff09;&#xff0c;有许多常用的快捷键可以帮助开发者提高效率。以下是一些常用的 IntelliJ IDEA 快捷键&#xff1a; CtrlSpace&#xff1a;基本代码补全&#xff0c;用于输入任何东西&#x…...

Redis Cluster Gossip Protocol: MEET

返回目录 CLUSTER MEET 过程说明 #mermaid-svg-dp95n6LRjBO1mCKE {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-dp95n6LRjBO1mCKE .error-icon{fill:#552222;}#mermaid-svg-dp95n6LRjBO1mCKE .error-text{fill:#…...

TcpConnection的读写操作【深度剖析】

文章目录 前言一、TcpConnection的读二、TcpConnection的写三、TcpConnection的关闭 前言 今天总结TcpConnection类的读写事件。 一、TcpConnection的读 当Poller检测到套接字的Channel处于可读状态时&#xff0c;会调用Channel的回调函数&#xff0c;回调函数中根据不同激活…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...