我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第4篇文章,点击查看活动详情
牙叔教程 简单易懂
观察图片, 图像分上下两层, 上层亮一点, 下层暗一点;
因此, 我们用亮度这个维度来入手;
再次观察图片, 方块的背景色是米黄色, 颜色还是比较纯的, 也可以从这个维度试试;
我们先试试背景色吧
提取背景色数据
颜色一致, 要测试的话, 用ps的魔棒工具测试, 效率最高;
可以看到, 魔棒工具选出了所有的米黄色背景图, 非常棒;
我们用autojs提供的方法来试试
images.inRange(img, lowerBound, upperBound)
[v4.1.0新增]
img {Image} 图片
lowerBound {string} | {number} 颜色下界
upperBound {string} | {number} 颜色下界
返回 {Image}
颜色的范围, 我们同样用ps的魔棒工具, 多取几个点, 然后找到rgb的最大值和最小值
红色: 最小242, 最大248
绿色: 最小253, 最大255
蓝色: 最小203, 最大207
然后转换成十六进制颜色, 这个用电脑自带的计算机算算
lowerBound F2FDCB
upperBound F8FFCF
lowerBound F2FDCB
upperBound F8FFCF
提取某种颜色区间的图片代码
let lowerBound = "#F2FDCB";
let upperBound = "#F8FFCF";
let rangeImg = images.inRange(img, lowerBound, upperBound);
let rangeImgPath = "/sdcard/脚本/sheep1InRange.png";
rangeImg.saveTo(rangeImgPath);
media.scanFile(rangeImgPath);
yashuImgTool.viewImgFile(rangeImgPath);
提取的图片效果
大概的背景都提取出来了, 我们修改一下颜色值, 把应该提取出来, 而没有提取的颜色区间修正一下;
有些地方没提取到, 可以用 ps 或者 mt管理器 继续提取图片中的颜色, 或者写个脚本采集背景区域的颜色;
最终选择的颜色阈值如下
let lowerBound = "#d0c0b0";
let upperBound = "#FfFFDb";
该阈值提取的图片如下
提取区域信息
图片已经整理成黑白色了, 我们提取一下这些方块的轮廓数据
Imgproc.findContours(binary, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE, Point());
Imgproc.drawContours(img.mat, contours, -1, Scalar(255, 0, 0, 255), 3, 8);
let rgbMat = img.mat.clone();
Imgproc.cvtColor(img.mat, rgbMat, Imgproc.COLOR_BGR2RGBA);
let tempFilePath = files.join(files.getSdcardPath(), "脚本", "mat.png");
Imgcodecs.imwrite(tempFilePath, rgbMat);
提取出来的轮廓区域, 都用红色方块画出来了
去除噪点
仔细看上面的图片, 有几个红色的点, 这个属于噪点;
要去除噪点, 可以设置一个阈值, 如果面积小于多少, 就去掉该轮廓
先打印看看轮廓的数据, 轮廓的面积用轮廓的最小外接矩形来算
for (let i = 0; i < contours.size(); ++i) {
let item = contours.get(i);
let rotateRect = Imgproc.boundingRect(item);
let contourData = {
width: rotateRect.width,
height: rotateRect.height,
area: rotateRect.area(),
};
contourDataArr.push(contourData);
}
轮廓的数据
[ { width: 55, height: 55, area: 3025 },
{ width: 55, height: 55, area: 3025 },
{ width: 1, height: 1, area: 1 },
{ width: 55, height: 56, area: 3080 },
{ width: 56, height: 55, area: 3080 },
{ width: 56, height: 55, area: 3080 },
{ width: 55, height: 56, area: 3080 },
{ width: 1, height: 1, area: 1 },
{ width: 55, height: 56, area: 3080 },
{ width: 1, height: 1, area: 1 },
{ width: 1, height: 1, area: 1 },
{ width: 56, height: 55, area: 3080 } ]
可以看到, 轮廓面积基本都在3000以上, 我们的阈值就设置3000;
过滤不符合规则的轮廓
let filteredContourDataArr = contourDataArr.filter((contourData) => {
return contourData.area > 3000;
});
绘制轮廓
filteredContourDataArr.map((contourData) => {
Imgproc.drawContours(img.mat, contours, contourData.index, new Scalar(0, 0, 255), 3, 8);
});
去掉噪点后的轮廓
活干完了, 不要忘记回收资源;
图片用recycle, mat用release
img.recycle();
rangeImg.recycle();
hierarchy.release();
rgbMat.release();
总结
既然通过颜色区间, 已经实现了目的, 那么就不用其他方法试了,;
识别还是比较简单的, 只识别了上层比较亮的部分,
下层暗的地方, 没有识别, 如果要识别的话, 也没有好办法, 除非机器学习;
网上有很多通关教程, 修改http之类的,
这个教程主要是介绍opencv的图片处理, 目的不在于过关;
非要试试过关的话, 用脚本模拟点击, 我估计过不了, 除非运气好;
因为脚本截图, 只能分析到上层较亮的部分, 下层分析不到, 属于数据不全;
数据不全, 就过不了
环境
设备: 小米11pro
Android版本: 12
Autojs版本: 9.2.13
名人名言
思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问 --- 牙叔教程
声明
部分内容来自网络 本教程仅用于学习, 禁止用于其他用途