autojs-opencv工具箱

牙叔教程 简单易懂

功能

autojs-opencv工具箱

rgb通道分离

autojs-opencv工具箱

hsv通道分离

autojs-opencv工具箱

灰度化

autojs-opencv工具箱

边缘检测

autojs-opencv工具箱

二值化

autojs-opencv工具箱


霍夫直线

autojs-opencv工具箱

简介

本项目集合了一些opencv的常用操作,

脚本框架已经搭好, 有能力的话可以添加更多的操作,

比如霍夫圆, 膨胀腐蚀等形态学操作


项目目录

autojs-opencv工具箱


主界面

点击按钮跳转至对应的功能界面


按钮点击事件

遍历按钮添加点击事件, 因为所有按钮行为都是类似的

buttons.map((button) => {
  button.on("click", function (view) {
    ...
  });
});

启动对应脚本, 带上工具名字, 图片路径, 以及当前工作路径

engines.execScriptFile(toolPath, {
  arguments: { toolName: toolName, imgPath: currentImgPath, fromPath: files.path(".") },
});

为什么要带上当前工作路径?

因为常用的工具函数都在根目录放着, 要在新脚本中导入根目录的工具函数, 需要require工具函数的绝对路径

var args = engines.myEngine().execArgv;
let fromPath = args.fromPath;
let yashuImgTool = require(files.join(fromPath, "./yashuImgTool"));

怎样给新脚本传递图片信息

一开始想直接把 URI 传给新脚本, 但是报错了, 说用户不匹配之类的,

然后就换了个办法, 把图片保存到手机上, 传递文件路径


保存bitmap

currentImg = com.stardust.autojs.core.image.ImageWrapper.ofBitmap(bitmap);
let imgPath = files.join(dirPath, "img.png");
files.createWithDirs(imgPath);
images.save(currentImg, imgPath);

URI 转 图片

function getBitmapFromUri(uri) {
  return android.provider.MediaStore.Images.Media.getBitmap(context.getContentResolver(), uri);
}

工具脚本结构, 以边缘检测为例

边缘检测

  1. 接收主脚本传递过来的数据
var args = engines.myEngine().execArgv;
// 接收的数据
args = {
  fromPath: "/data/data/org.autojs.autojspro/cache/remote_project/3a26c38d0089d40061afbd09dacd38b5",
  imgPath: "/storage/emulated/0/脚本/opencvToolbox/img.png",
  toolName: "边缘检测",
};
  1. 导入工具模块
let yashuImgTool = require(files.join(fromPath, "./yashuImgTool"));

模块里面是一些常用的函数

autojs-opencv工具箱

  1. 处理图片
// 读取灰度图
var imgGray = Imgcodecs.imread(imgPath, 0);
// 降噪
Imgproc.GaussianBlur(imgGray, imgBlur, Size(3, 3), 0);
// 边缘检测
Imgproc.Canny(imgBlur, imgCanny, cannyParam.threshold1, cannyParam.threshold2, cannyParam.apertureSize, false);
  1. 显示界面
autojs-opencv工具箱

  1. 显示刚才处理过的图片
let bitmap = yashuImgTool.mat2bitmap(imgCanny);
ui.img.setImageBitmap(bitmap);
  1. 设置滑块监听

由于滑块功能类似, 因此可以设计一个通用的函数, 批量设置监听

seekbarBindingTextAndCannyParam(ui.threshold1ControlView, ui.threshold1ValueShowView, "threshold1");
seekbarBindingTextAndCannyParam(ui.threshold2ControlView, ui.threshold2ValueShowView, "threshold2");
seekbarBindingTextAndCannyParam(ui.apertureSizeControlView, ui.apertureSizeValueShowView, "apertureSize");
  1. 只响应用户的操作
function seekbarBindingTextAndCannyParam(seekbarView, textView, cannyParamName) {
  seekbarView.setOnSeekBarChangeListener(
    new android.widget.SeekBar.OnSeekBarChangeListener({
      onProgressChanged: function (seekbar, progress, fromUser) {
        if (fromUser) {
          ...
        }
      },
    })
  );
}
  1. 特殊参数, 特殊处理

测试的时候, apertureSize太大就会报错, 偶数也报错, 因此需要特殊处理;

注意同时修改滑块显示的数值

let value = parseInt(progress);
cannyParam[cannyParamName] = value;
if (cannyParamName === "apertureSize") {
  apertureSize = value + 3;
  if (apertureSize % 2 == 0) {
    apertureSize += 1;
    seekbarView.setProgress(progress + 1);
  }
  textView.setText("" + apertureSize);
} else {
  textView.setText("" + value);
}
  1. 节流

因为处理图片, 需要一定的时间, 因此使用防抖操作,

在一定时间内, 只处理用户最后一次的操作

function debounce(fn, delay) {
  let timer;
  delay = delay || 500;
  return function () {
    if (timer) {
      clearTimeout(timer);
    }
    const args = arguments;
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  };
}
let debounceRefreshMat = yashuTool.debounce(refreshMat);
  1. 刷新图片

设置新图片, 回收旧图片, 避免内存泄漏

function refreshMat() {
  ui.img.setImageBitmap(bitmap);
  ui.post(function () {
    oldBitmap.recycle();
  }, 200);
}
  1. 霍夫直线
let HoughLinesPParam = {
  threshold: 22, // 阈值,只有获得足够交点的极坐标点才被看成是直线
  minLineLength: 22, // 最小直线长度,有默认值0,表示最低线段的长度,比这个设定参数短的线段就不能被显现出来。
  maxLineGap: 22, // 最大间隔,有默认值0,允许将同一行点与点之间连接起来的最大的距离。
};
let lines = new Mat();
Imgproc.HoughLinesP(
  imgCanny,
  lines,
  1,
  Math.PI / 180,
  HoughLinesPParam.threshold,
  HoughLinesPParam.minLineLength,
  HoughLinesPParam.maxLineGap
);

以上就是 边缘检测 工具脚本的大概流程, 其他opencv工具脚本流程与它类似


备注

不同软件测出来的阈值不一样,

比如你用PS和autojs测出来的二值化阈值就不一样,


因此, 浏览初步效果可以在ps上看,

要测出合适的数值, 就要在手机上操作


鉴于有的人不会调试脚本, 我打算打包一个app.

打包脚本遇到的问题

打包后安装, 提示包解析错误


然后我就准备用autojs8.8.20打包,

先运行一次脚本, 脚本报错了

Java class "androidx.core.view.ViewCompat" has no public instance field or method named "getWindowInsetsController"

这个 getWindowInsetsController 方法是安卓11新增的全屏api,

autojs8.8.20出来的时候, 还没有支持安卓11,

因此我把这个全屏函数try catch


再次运行脚本, 还是报错

Error: Module "/data/data/org.autojs.autojspro/cache/remote_project/3a26c38d0089d40061afbd09dacd38b5/config.json" not found.

我在autojs9.0.14用的好好的, 在autojs8.8.20就报错了, 也是有点委屈;


报错说找不到模块文件, 那么我们去对应的目录下面看看都有什么文件


shell打印文件目录

cmd = "cd /data/user/0/org.autojs.autojspro/cache/remote_project/cb63fce5e400e29f9d8b3bacbab39fa5/  && pwd && ls -al ";
var result = shell(cmd);
log(result);
console.show();
if (result.code == 0) {
  toast("执行成功");
} else {
  toast("执行失败!请到控制台查看错误信息");
}

打印出来的内容

autojs-opencv工具箱

明明有这个config.js文件的


我知道哪里的问题了

调试的时候用了上一次的 args没注释

args = {
  fromPath: "/data/data/org.autojs.autojspro/cache/remote_project/3a26c38d0089d40061afbd09dacd38b5",
  imgPath: "/storage/emulated/0/脚本/opencvToolbox/img.png",
  toolName: "hsv通道分离",
};

可气


注释后运行就正常了


再打包试试, 还是提示解析错误

autojs-opencv工具箱

然后就开始猜测是哪里错了


打包的时候有一些东西要填写, 我把中文和破折号等都给删掉,

再次打包, 居然可以了, 看来是中文或者破折号的问题


测试环境


手机: Mi 11 Pro
Android版本: 12
Autojs版本: 9.1.14


名人名言

思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问 --- 牙叔教程

声明

部分内容来自网络 本教程仅用于学习, 禁止用于其他用途

展开阅读全文

页面更新:2024-03-03

标签:阈值   灰度   工具箱   直线   脚本   函数   按钮   边缘   操作   工具   图片

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top