android无障碍服务可以操作元素,手势模拟,实现基本的控制。opencv可以进行图像识别。两者结合在一起即可实现支付宝能量自动收集。opencv用于识别能量,无障碍服务用于模拟手势,即点击能量。
当然这两者结合不单单只能实现这些,还能做很多自动化的程序,如芭芭农场自动施肥、蚂蚁庄园等等的自动化,甚至游戏的自动化也没问题。
下面简单介绍下核心的实现逻辑
核心步骤
- 准确识别多个能量球位置
- 准确点击能量球位置
opencv识别能量球
opencv是一个可用于开发实时的图像处理、计算机视觉以及模式识别可商用的开源库-opencv介绍
思路
使用opencv怎么识别能量球呢?
使用opencv的模板匹配。即,将能量球单独裁剪出来作为模板,再将其与屏幕图像进行匹配,筛选匹配分值最高的结果即获取能量球在屏幕中的位置。
实现
1. 项目集成opencv-android版
dependencies { implementation 'org.opencv:opencv:4.9.0' }
最新版本可查看官方集成教程
2. 截取能量球图像作为模板
3. 截取屏幕图像
4. 使用opencv模板匹配获取所有能量球位置
opencv模板匹配api
imgproc.matchtemplate(image, templ, result, method, mask)
参数解释:image
屏幕图像,即步骤3中截取的屏幕图像templ
模板图像,即步骤2中截图的能量球图像result
匹配结果容器,用于存储匹配的结果mask
掩膜,用于指定模板中哪些位置需要匹配,哪些不需要匹配
其中参数mask
掩膜是匹配准确度的关键点
掩膜图像是根据模板生成的一张黑白图像,其中黑色为不需要匹配的区域
模板图像与生成的掩膜图像对比
模板图像 | 掩模图像 |
---|---|
![]() | ![]() |
其中文字也是我们不需要匹配的,因为里面的文字会变化,所以中间加了一块黑色矩形用于指定匹配忽略区域
对于掩膜的创建方法这里不介绍了,所有代码都已经开放在我的自动化开源库assists里,想直接看代码这里:https://github.com/ven-coder/assists
参数准备好就可以进行匹配了,下面是完整代码(kotlin代码)
/** * 模板匹配能量球 */ fun match() { try { val path = system.getproperty("user.dir") + "\\lib\\x64\\opencv_java490.dll" system.load(path) val temp = system.getproperty("user.dir") + "\\images\\temp.jpg" val image = system.getproperty("user.dir") + "\\images\\image.png" //模板图像 val img = imgcodecs.imread(image) //屏幕图像 val templ = imgcodecs.imread(temp) //掩膜图像 val mask = createmask(templ) // 创建结果矩阵 val resultcols: int = img.cols() - templ.cols() + 1 val resultrows: int = img.rows() - templ.rows() + 1 val result = mat(resultrows, resultcols, cvtype.cv_32fc1) // 进行模板匹配 imgproc.matchtemplate(img, templ, result, imgproc.tm_ccorr_normed, mask) // 遍历结果矩阵,找到所有匹配超过阈值的位置 val threshold = 0.98 // 阈值,根据实际情况调整 var count = 0 var countvalue = 0 for (y in 0 until result.rows()) { for (x in 0 until result.cols()) { countvalue++ val matchvalue = result[y, x] if (matchvalue[0] >= threshold) { count++ // 找到一个匹配位置 val matchloc = point(x.todouble(), y.todouble()) // 绘制矩形框 imgproc.rectangle(img, matchloc, point(matchloc.x + templ.cols(), matchloc.y + templ.rows()), scalar( 85.0, 85.0,205.0,), 2, imgproc.line_aa, 0) } } } // 显示结果 imgproc.resize(img, img, size(img.cols() / 2.0, img.rows() / 2.0)) // 可选:调整显示大小 highgui.imshow("matched result: $count", img) highgui.waitkey(0) } catch (e: throwable) { e.printstacktrace() } } /** * 创建掩膜 */ fun createmask(source: mat): mat { // 转换为 hsv 颜色空间 val hsvimage = mat() imgproc.cvtcolor(source, hsvimage, imgproc.color_bgr2hsv) // 定义绿色的颜色范围 val lowergreen = scalar(35.0, 100.0, 100.0) val uppergreen = scalar(85.0, 255.0, 255.0) // 创建掩膜 val mask = mat() core.inrange(hsvimage, lowergreen, uppergreen, mask) // 忽略“27g”文字 // 你可以使用形态学操作去掉文字部分,或者手动确定文字的位置并将其设置为黑色(0)。 // 假设文字位于圆形中心,可以手动遮盖这个区域 // rect(中心位置x, 中心位置y, 宽度, 高度) val width = 80 val height = 60 val textrect = rect(source.width() / 2 - width / 2, source.height() / 2 - height / 2, width, height) // 假设的“27g”文字位置和大小 imgproc.rectangle(mask, textrect, scalar(0.0), -1) imgproc.rectangle(mask, rect((source.width() / 2 - width / 2) + 10, (source.height() / 2 - height / 2) + height, 40, 25), scalar(255.0), -1) return mask }
匹配结果
点击能量球
准确得到能量球位置之后就好办了,使用我的开源库assists开启无障碍服务后调用gestureclick(x: float, y: float)
点击能量球位置即可
//it.x + temp3.width() / 2,坐标加上模板大小的一半即点击中间位置 assists.gestureclick((it.x + temp3.width() / 2).tofloat(), (it.y + temp3.height() / 2).tofloat())
最终效果
以上所有代码都在我的开源库assists示例里了,需要的自取即可。
觉得有帮助顺便可以start一下,满足以下一下老夫虚荣心憋
到此这篇关于android无障碍自动化结合opencv实现支付宝能量自动收集的文章就介绍到这了,更多相关android能量自动收集内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论