autojs-opencv工具箱

简介: 牙叔教程 简单易懂

牙叔教程 简单易懂

功能


rgb通道分离

hsv通道分离

灰度化

边缘检测

二值化


霍夫直线

简介

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

  • rgb通道分离
  • hsv通道分离
  • 灰度化
  • 边缘检测
  • .二值化
  • .霍夫直线

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

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

项目目录


主界面

  • 上方选择图片
  • 下方列出功能按钮

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


按钮点击事件

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

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"));


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


  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. 显示界面


  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("执行失败!请到控制台查看错误信息");
}


打印出来的内容



明明有这个config.js文件的


我知道哪里的问题了

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


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


可气

注释后运行就正常了

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

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

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

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


测试环境

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


名人名言

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

声明

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



相关文章
|
4月前
|
计算机视觉
【轻松入门】OpenCV4.8 + QT5.x开发环境搭建
【轻松入门】OpenCV4.8 + QT5.x开发环境搭建
72 0
【轻松入门】OpenCV4.8 + QT5.x开发环境搭建
|
4月前
|
机器学习/深度学习 算法 数据可视化
基于OpenCV的人脸检测软件(含Python源码+UI界面+图文详解)
基于OpenCV的人脸检测软件(含Python源码+UI界面+图文详解)
|
文字识别 算法 计算机视觉
[笔记]OpenCV+FFmpeg+Qt实现视频编辑器之OpenCV图像处理
[笔记]OpenCV+FFmpeg+Qt实现视频编辑器之OpenCV图像处理
156 1
|
编译器 计算机视觉
[笔记]OpenCV+FFmpeg+Qt实现视频编辑器之OpenCV vs2015编译
[笔记]OpenCV+FFmpeg+Qt实现视频编辑器之OpenCV vs2015编译
|
计算机视觉
基于opencv的Qt开发项目
基于opencv的Qt开发项目
|
计算机视觉
实现素描效果---OpenCV-Python开发指南(49)
实现素描效果---OpenCV-Python开发指南(49)
251 0
实现素描效果---OpenCV-Python开发指南(49)
|
Android开发
autojs牙叔工具箱
牙叔教程 简单易懂
766 0
|
Java 程序员 开发工具
autojs-opencv常用命令
autojs-opencv常用命令
1078 0