autojs之识别象棋位置

简介: 声明本文仅供学习

声明


本文仅供学习


使用情景


识别象棋位置


效果展示

微信图片_20220624130601.jpg

微信图片_20220624130601.jpg


原理


  1. openev霍夫找圆
  2. canvas画圆
  3. 悬浮窗显示图片


知识点


  1. 隐藏虚拟按钮
  2. 全屏显示图片
  3. HoughCircles的各个参数的意思
  4. 图片的回收


代码讲解


  1. ui 显示象棋图片
ui.layout(
  <vertical w="{{device.width}}px" h="{{device.height}}px">
    <img src="file://./中国象棋.jpg"></img>
  </vertical>
);


  1. 请求截图
if (!requestScreenCapture()) {
  toast("请求截图失败");
  exit();
}


  1. 截图并保存
let screen = images.read(imgFilepath);
images.save(screen, imgFilepath);


  1. 霍夫找圆
let data = 霍夫找圆(screen);


  1. canvas画圆
let newImgFilepath = showData(data, imgFilepath);


  1. 悬浮窗全屏显示图片
悬浮窗全屏显示图片(newImgFilepath);


完整源码


  1. main.js
"ui";
importClass(android.view.WindowManager);
importClass(android.view.View);
let showData = require("./showData");
hideBottomUI();
ui.layout(
  <vertical w="{{device.width}}px" h="{{device.height}}px">
    <img src="file://./中国象棋.jpg"></img>
  </vertical>
);
threads.start(function () {
  //请求截图
  if (!requestScreenCapture()) {
    toast("请求截图失败");
    exit();
  }
  let imgFilepath = files.path("./中国象棋.jpg");
  log(imgFilepath);
  log(files.exists(imgFilepath));
  let screen = images.read(imgFilepath);
  images.save(screen, imgFilepath);
  let data = 霍夫找圆(screen);
  let newImgFilepath = showData(data, imgFilepath);
  悬浮窗全屏显示图片(newImgFilepath);
});
setInterval(function () {}, 1000);
// ==================自定义函数===================================
function 霍夫找圆(screen) {
  // 对图像进行中值滤波,返回处理后的图像。
  let grayImgInfo = images.grayscale(images.medianBlur(screen, 3));
  // void HoughCircles( InputArray image, OutputArray circles,
  //          int method, double dp, double minDist,
  //          double param1=100, double param2=100,
  //          int minRadius=0, int maxRadius=0 );
  //dp,用来检测圆心的累加器图像的分辨率与输入图像之比的倒数,例如如果dp= 1时,累加器和输入图像具有相同的分辨率。如果dp=2,累加器便只有输入图像一半的分辨率
  //minDist 检测到的圆的圆心之间的最小距离,即让我们的算法能明显区分的两个不同圆之间的最小距离。如果这个参数设置过大,某些圆就不能被检测出来。
  // param1:此参数是对应Canny边缘检测的最大阈值,最小阈值是此参数的一半 也就是说像素的值大于param1是会检测为边缘
  // param2:它表示在检测阶段圆心的累加器阈值。它越小的话,就可以检测到更多根本不存在的圆,而它越大的话,能通过检测的圆就更加接近完美的圆形了
  // minRadius:表示能够检测的最小圆的半径 这里我们设置为0是因为他也要检测圆心 而圆心可以看作是半径为0的圆
  // maxRadius:表示能够检测的最大圆的半径,这里我设置为100,那么表示圆半径大于100的圆不会被检测出来(这个是依据你要检测的图片而考虑)
  let findBalls = images.findCircles(grayImgInfo, {
    dp: 1,
    minDst: 80,
    param1: 100,
    param2: 45,
    minRadius: 50,
    maxRadius: 80,
  });
  // log("找到的圆:" + JSON.stringify(findBalls));
  let haveBalls = findBalls && findBalls.length > 0;
  grayImgInfo.recycle();
  screen.recycle();
  if (haveBalls) {
    log("有圆" + findBalls.length + "个");
    return findBalls;
  } else {
    return false;
  }
}
function 悬浮窗全屏显示图片(imgFilepath) {
  log("全屏显示图片");
  let screen = images.read(imgFilepath);
  var w = floaty.rawWindow(
    <frame gravity="center" bg="#44ffcc00">
      <img id="img"></img>
    </frame>
  );
  ui.run(function () {
    w.img.attr("src", "file://" + imgFilepath);
  });
  w.setSize(-1, -1);
  w.setTouchable(false);
  setTimeout(function () {
    screen.recycle();
  }, 1000);
}
function hideBottomUI() {
  // 隐藏虚拟键
  let uiFlags =
    View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
    View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
    View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
    View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
    View.SYSTEM_UI_FLAG_FULLSCREEN;
  uiFlags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
  activity.getWindow().getDecorView().setSystemUiVisibility(uiFlags);
  //解决虚拟按键弹出,无法再次隐藏的问题
  activity
    .getWindow()
    .getDecorView()
    .setOnSystemUiVisibilityChangeListener(function (i) {
      hideBottomUI();
    });
}


  1. showData.js
function showData(dataList, imgPath) {
  ocrType = "牙叔圆形识别测试";
  log("显示数据 imgPath = " + imgPath);
  var img = images.read(imgPath);
  var canvas = new Canvas(img);
  let circlePaint = new Paint();
  circlePaint.setStrokeWidth(3);
  circlePaint.setColor(colors.parseColor("#00ff00"));
  circlePaint.setStyle(Paint.Style.STROKE); //空心矩形框
  let textPaint = new Paint();
  textPaint.setTextAlign(Paint.Align.CENTER);
  textPaint.setTextSize(30);
  textPaint.setStyle(Paint.Style.FILL);
  textPaint.setColor(colors.parseColor("#f000ff"));
  var len = dataList.length;
  for (var i = 0; i < len; i++) {
    let data = dataList[i];
    // { x: 464.5, y: 566.5, radius: 15.399999618530273 },
    canvas.drawCircle(data.x, data.y, data.radius, circlePaint);
    canvas.drawText(i + "", data.x, data.y, textPaint);
  }
  var image = canvas.toImage();
  let newFilename = files.getNameWithoutExtension(imgPath) + "_" + ocrType + ".png";
  let newFilepath = "/sdcard/脚本/" + ocrType + "/" + newFilename;
  files.createWithDirs(newFilepath);
  images.save(image, newFilepath);
  log("识别后的图片保存路径: " + newFilepath);
  img.recycle();
  image.recycle();
  return newFilepath;
}
events.on("exit", function () {
  log("结束运行 模块脚本");
});
module.exports = showData;


3.素材 中国象棋.jpg








相关文章
|
4月前
|
存储 安全 Java
"Java编码魔法:揭秘图片与文件的Base64神秘转换术,让数据在指尖跳跃!"
【8月更文挑战第16天】Base64编码在Java开发中常用于将二进制数据如图片转换为ASCII字符串以便传输。编码使用64个字符及等号填充,每3字节数据编码为4个字符。Java利用`java.util.Base64`类实现此功能:读取图片或文件为字节数组后进行编码。解码时将Base64字符串还原为字节数组并写入文件。需注意编码效率降低、不提供安全性及特殊字符兼容性等问题。掌握这些技巧有助于解决Web开发中的数据传输需求。
115 4
|
4月前
|
人工智能 算法
你试过一秒钟出现在世界各地的感觉吗?使用一键人像抠图换背景,让你拥有任意门
准备人像与背景图,访问ModelScope一键抠图换背景工具。上传人像至位置1,背景至位置2。点击按钮稍候,AI快速生成新图,将人像无缝融合至新背景中。体验高效便捷,算法智能精准,边缘处理细腻无痕,支持多样背景选择,输出质量高,适合多种应用场景。
|
6月前
|
移动开发 前端开发 安全
技术心得记录:怎么更快地合成大西瓜?搞懂游戏的源码,闭着眼睛都能成功!
技术心得记录:怎么更快地合成大西瓜?搞懂游戏的源码,闭着眼睛都能成功!
93 0
|
7月前
|
索引
在微信小游戏制作工具中实现文字逐个出现的打字机效果
在微信小游戏制作工具中实现文字逐个出现的打字机效果
81 0
|
人工智能 API 数据安全/隐私保护
Python3,5行代码,Chatxxx能对PDF文件进行旋转、提取、合并等一系列操作,看了这篇,80岁老奶奶走路都不扶墙了。
Python3,5行代码,Chatxxx能对PDF文件进行旋转、提取、合并等一系列操作,看了这篇,80岁老奶奶走路都不扶墙了。
108 0
|
iOS开发
iOS开发 自拍及照片镜面翻转问题解决办法
iOS开发 自拍及照片镜面翻转问题解决办法
292 0
|
Python
python植物大战僵尸二十四之调整植物放置位置
python植物大战僵尸二十四之调整植物放置位置
103 0
|
算法 索引
【切图仔的算法修炼之旅】LeetCode1991:找到数组中的中间位置
【切图仔的算法修炼之旅】LeetCode1991:找到数组中的中间位置
117 0
|
测试技术 Android开发
autojs象棋识别棋子
牙叔教程 简单易懂
185 0