【教程】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等算法进行图像匹配
转载请注明出处:小锋学长生活大爆炸[xfxuezhang.cn] 此代码可以替代内置的images.findImage函数使用,但可能会误匹配,如果是对匹配结果要求比较高的,还是得谨慎使用。 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 云计算(cloud computing&…...
计算机网络-计算机网络体系结构-概述,模型
目录 一、计算机网络概述 二、性能指标 速率 带宽 吞吐量 时延 往返时延RTT 利用率 三、计算机网络体系结构 分层结构 IOS模型 应用层-> 表示层-> 会话层-> 传输层-> 网络层-> 数据链路层-> 物理层-> TCP/IP模型 一、计算机网络概述 计…...
对示例程序spinner_asyncio.py进行修改使其能运行
学习《流畅的python》第18章 使用asyncio包处理并发,运行示例18-2 spinner_asyncio.py的时候,程序报错如下: 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行内容;默认head查看前10行 2.head用法 head [参数] 文件 head常用参数 参数说明-n从头显示N行,默认显示10行,可以不写-q隐藏文件名,在查看两个及以上文件名的情况…...
使用Visual Studio调试排查Windows系统程序audiodg.exe频繁弹出报错
VC常用功能开发汇总(专栏文章列表,欢迎订阅,持续更新...)https://blog.csdn.net/chenlycly/article/details/124272585C软件异常排查从入门到精通系列教程(专栏文章列表,欢迎订阅,持续更新...&a…...
WebSocket实战之六心跳重连机制
一、前言 WebSocket应用部署到生产环境,我们除了会碰到因为经过代理服务器无法连接的问题(注:该问题可以通过搭建WSS来解决,具体配置请看 WebSocket实战之四WSS配置 ),另外一个问题就是外网环境不稳定经常…...
Webpack 基础入门以及接入 CSS、Typescript、Babel
一、什么是 Webpack Webpack 是一款 JS 模块化开发的技术框架,其运作原理是将多个 JS 文件关联起来构成可运行的应用程序。 Webpack 拥有丰富的 plugins / loaders 插件生态圈,可以让 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平台自动化测试的一种手段,通过Monkey程序模拟用户触摸屏幕、滑动Trackball、按键等操作来对设备上的程序进行压 力测试,检测程序多久的时间会发生…...
力扣 -- 279. 完全平方数(完全背包问题)
解题步骤: 参考代码: 未优化代码: class Solution { public:int numSquares(int n) {const int INF0x3f3f3f3f;int msqrt(n);//多开一行,多开一列vector<vector<int>> dp(m1,vector<int>(n1));//初始化第一行…...
在将对象 => JSON格式时,无法序列化部分属性
问题现象: 在ssm项目中,一个controller返回Msg对象(自定义对象,包含三个属性,int code;String msg;HashMap map;同时这三个属性都有对应的get和set方法),我的map属性里面…...
用python表格初级尝试
Excel,我的野心 当我输入3,2 就表示在第3行第2列。的单元格输入数据input输入表头 (input内除了/,空格 回车 标点符号等 全部作为单元格分隔符)由我设置input输入的是行or列 给选项 1. 行 2. 列默认回车或没输入值是列由我设置起…...
【单片机】16-LCD1602和12864显示器
1.LCD显示器相关背景 1.LCD简介 (1)显示器,常见显示器:电视,电脑 (2)LCD(Liquid Crystal Display),液晶显示器,原理介绍 (3ÿ…...
AUTOSAR从入门到精通-基于 CAN 总线的汽车发电机智能调节器(下)
目录 4.4.3 CAN 通信软件实现 汽车发电机智能调节器试验与结果分析 5.1 试验方案设计...
Windows下Tensorflow docker python开发环境搭建
前置条件 windows10 更新到较新的版本,硬件支持Hyper-V。 参考:https://learn.microsoft.com/zh-cn/windows/wsl/install 启用WSL 在Powershell中输入如下指令: dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsys…...
idea常用快捷键 idea搜索快捷键
常用快捷键 IntelliJ IDEA 是一款流行的 Java 集成开发环境(IDE),有许多常用的快捷键可以帮助开发者提高效率。以下是一些常用的 IntelliJ IDEA 快捷键: CtrlSpace:基本代码补全,用于输入任何东西&#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处于可读状态时,会调用Channel的回调函数,回调函数中根据不同激活…...
[路径保护]解决中文路径乱码:从名称错乱到Unicode支持的实践指南
[路径保护]解决中文路径乱码:从名称错乱到Unicode支持的实践指南 【免费下载链接】calibre-do-not-translate-my-path Switch my calibre library from ascii path to plain Unicode path. 将我的书库从拼音目录切换至非纯英文(中文)命名 项…...
HunyuanVideo-Foley保姆级教程:从零部署到音效生成的5个关键步骤
HunyuanVideo-Foley保姆级教程:从零部署到音效生成的5个关键步骤 1. 环境准备与镜像部署 1.1 硬件要求检查 在开始部署前,请确保您的设备满足以下最低配置要求: 显卡:NVIDIA RTX 4090/4090D(24GB显存)内…...
Gradio项目快速公网演示:除了share=True,你还有这几种轻量级内网穿透方案
Gradio项目快速公网演示:5种轻量级内网穿透方案横向评测 当你开发了一个酷炫的机器学习模型演示,或是精心设计的数据可视化界面,最迫切的需求往往是如何快速分享给同事或客户。Gradio的shareTrue参数可能是大多数开发者首先想到的方案&#x…...
告别PS!用WPS宏批量改图片尺寸的隐藏技巧(附JSA API避坑指南)
告别PS!用WPS宏批量改图片尺寸的隐藏技巧(附JSA API避坑指南) 在电商运营、教育培训等日常工作中,批量处理图片是刚需。传统做法要么依赖Photoshop等专业软件(学习成本高),要么手动逐个调整&…...
modelsim crack过程中显示dll文件找不到解决方法
把这几个文件放到modelsim/win64目录下,按照教程点击patch64生成license时会报错,如下找不到文件 - mgls.dll找不到文件 - mgls64.dll这个时候关闭杀毒软件进入你的 D:\modeltech64_10.5\win64 文件夹。在文件夹上方的地址栏(显示路径的地方&…...
从FCN到U-Net:盘点深度学习图像分割中,那些‘放大’特征图的秘密武器与选型指南
从FCN到U-Net:解码图像分割中的特征图放大技术选型 在构建图像分割模型时,特征图的上采样操作往往是决定最终分割精度的关键环节之一。不同于分类任务只需输出一个类别标签,分割网络需要对每个像素进行分类,这就要求网络能够将低分…...
快速体验Qwen3-0.6B-FP8:无需下载模型,开箱即用的AI文本生成服务
快速体验Qwen3-0.6B-FP8:无需下载模型,开箱即用的AI文本生成服务 1. 为什么选择Qwen3-0.6B-FP8? Qwen3-0.6B-FP8是Qwen系列最新推出的轻量级语言模型,采用FP8量化技术大幅降低了显存需求。相比传统模型,它具有以下突…...
别再手动拆任务了!用CrewAI+DeepSeek打造你的第一个AI小团队(附PDF解析实战)
用CrewAI构建自动化AI团队:从PDF解析到智能协作实战 在传统AI开发中,开发者往往需要手动编写复杂的任务流程,像指挥一个士兵完成所有战斗。而CrewAI带来的革命性变化在于——它让你能够组建一支训练有素的AI特种部队,每个成员各司…...
从Debezium到Flink RowData:手把手解析Flink CDC 2.3如何优雅处理MySQL的UPDATE事件
从Debezium到Flink RowData:深入解析Flink CDC 2.3处理MySQL UPDATE事件的机制 在实时数据处理的领域中,变更数据捕获(CDC)技术已经成为构建数据管道的核心组件。当MySQL数据库中的一条记录被更新时,如何准确捕获这一变更并将其高效地传递到下…...
什么是分段锁
面试 线程只锁自己要用的那一段代码,不同段可以同时操作。这样可以减少锁竞争、提高并发。...
