摘要:微信跳一跳是时下热门的微信小游戏,基本原理是根据按压屏幕的时间控制棋子跳过的距离,使其跳到下一个方块上;现利用Android adb工具,PC端获取实时截图,使用OpenCV库分析图片计算距离,从而计算按压时间传回手机。

环境:Ubuntu18.04、OpenCV3.4.0

步骤:

1、获取Android截图,并传到PC端

adb shell /system/bin/screencap -p /sdcard/screenshot.png

adb pull /sdcard/screenshot.png .

2、程序读入图片并获取ROI

cvLoadImage("screenshot.png", 1);

cvSetImageROI(src, cvRect(0, 600, 1080, 900));

2、对ROI进行模板匹配,找到chess坐标

cvMatchTemplate(src, mode, result, CV_TM_CCOEFF);

3、对ROI灰度处理并边缘检测

cvCvtColor(src,srcGray, CV_BGR2GRAY);

cvCanny( srcGray, dst, 50, 100, 3);

4、对边缘检测结果进行遍历像素点,获取最上与最右(左)的像素 点坐标,从而得出下一方块中心点。

5、计算两个点坐标距离乘相应系数得到时间。

adb shell input swipe  400 400 400 400  time

效果图:

具体代码如下:

 #include "cv.h"
#include "highgui.h"
#include <iostream>
#include <unistd.h>
#include <stdio.h>
using namespace std;
using namespace cv;
CvPoint find_chess_point(IplImage* src, IplImage* mode)
{
//模式匹配
IplImage* result;
CvPoint MinLocation, MaxLocation;
double MinValue, MaxValue;
int iwidth = src->width - mode->width + ;
int iheight = src->height - mode->height + ;
result = cvCreateImage(cvSize(iwidth, iheight), , );
cvMatchTemplate(src, mode, result, CV_TM_CCOEFF);
cvMinMaxLoc(result, &MinValue, &MaxValue, &MinLocation, &MaxLocation, NULL);
return cvPoint(MaxLocation.x + (int)mode->width/, MaxLocation.y + mode->height);
}
CvPoint find_next_point(IplImage* src, CvPoint chess_point, int mode = )
{
IplImage* tmp = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, );
cvCvtColor(src, tmp, CV_BGR2GRAY);
cvEqualizeHist(tmp, tmp);
IplImage* dst = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, );
cvCanny(src, dst, , , );
//cvNamedWindow("doCany");
//cvShowImage("doCany", dst);
CvPoint next_point;
if(chess_point.x < )//分左右,如果棋子在左侧,目标方块则在右侧
{
/*遍历轮廓上顶点*/
unsigned char *pixel = (unsigned char *)dst->imageData;//指向首地址
for(int row = ; row < ; ++row)//行扫描
{
for(int col = ; col < ; ++col)//列扫描
{
if(pixel[row*dst->width + col] == )//灰度图Canny边缘处理后轮廓为白色255
{
next_point.x = col;
if(mode == )
{
/*这是根据chess与target的连线与水平夹角总是30度,只知道横坐标和角度即可算出纵坐标*/
next_point.y = (int) (chess_point.y - (chess_point.x - next_point.x)/1.732); //根号3
return next_point;
}
/*找到上顶点后,开始遍历右顶点*/
for(int col_=; col_ > ; --col_)//最右列向左遍历
{
for(int row_=; row_ < ; ++row_)//从上向下遍历
{
if(pixel[row_*dst->width + col_] == )
{
/*找到右顶点*/
next_point.y = row_;
cvLine(dst, chess_point, next_point, Scalar(, , ));
cvShowImage("line", dst);
cvWaitKey();
return next_point;
}
}
}
}
}
}
}
else
{
/*遍历轮廓上顶点*/
unsigned char *pixel = (unsigned char* )dst->imageData;//指向首地址
for(int row = ; row < ; ++row)//行扫描
{
for(int col = ; col < ; ++col)//列扫描
{
if(pixel[row*dst->width + col] == )
{
next_point.x = col;
if(mode == )
{
/*这是根据chess与target的连线与水平夹角总是30度,只知道横坐标和角度即可算出纵坐标, 这个方法效果好*/
next_point.y = (int) (chess_point.y - (chess_point.x - next_point.x)/1.732); //根号3
return next_point;
}
/*找到上顶点后,开始遍历右顶点*/
for(int col_=; col_ > ; --col_)//最正中间列向左遍历
{
for(int row_=; row_ < ; ++row_)//从上向下遍历
{
if(pixel[row_*dst->width + col_] == )
{
/*找到右顶点*/
next_point.y = row_;
cvLine(dst, chess_point, next_point, Scalar(, , ));
cvShowImage("line", dst);
cvWaitKey();
return next_point;
}
}
}
}
}
}
}
return next_point;
} IplImage* cut_src_img(IplImage* src)
{
//SetImageROI
cvSetImageROI(src, cvRect(, , , ));//取决于手机分辨率,可以在上一行resize后,其他地方不需要修改
cvSaveImage("roi.jpg",src);
return cvLoadImage("roi.jpg", );
} float calculate_distance(CvPoint chess_point, CvPoint next_point)
{
float distance;
distance = sqrt(pow(abs(chess_point.x - next_point.x), ) + pow(abs(chess_point.y - next_point.y), ));
return distance;
}
void jump_one_jump(float distance, float parameter)
{
char jump[];
RNG rng;
sprintf(jump, "adb shell input swipe %d %d %d %d %d", rng.uniform(, ), rng.uniform(, ), rng.uniform(, ), rng.uniform(, ), (int)(distance * parameter));
system(jump);
}
int main(int argc, char** argv)
{
IplImage* roi_image = NULL;
IplImage* chess_mode = cvLoadImage("jump.png", );
float distance;
CvPoint chess_point, next_point;
cvNamedWindow("line",);
for(;;)
{
system("rm -rf screenshot.png && rm -rf roi.jpg");
system("adb shell /system/bin/screencap -p /sdcard/screenshot.png");
sleep(0.2);
system("adb pull /sdcard/screenshot.png . >/dev/null");//把adb pull命令的shell提示重定向
sleep(0.2);
IplImage* src = cvLoadImage("screenshot.png", );
roi_image = cut_src_img(src);//取截图中间部分
chess_point = find_chess_point(roi_image, chess_mode);//match找到chess坐标
next_point = find_next_point(roi_image, chess_point, );//像素点遍历找到target坐标,mode=1效果好
//cvLine(roi_image, chess_point, next_point, Scalar(0, 255, 255));
//cvShowImage("line",roi_image);
//cvWaitKey(100);
distance = calculate_distance(chess_point, next_point);//计算距离
jump_one_jump(distance, 1.4);
sleep();
}
return ;
}

代码链接:https://files.cnblogs.com/files/luoyijie/jump2.0.tar.gz

基于OpenCV的微信跳一跳外挂的更多相关文章

  1. C#又能出来装个B了。一步一步微信跳一跳自动外挂

    PS:语言只是载体.思维逻辑才是王道 前天看见了个python的脚本.于是装python.配置环境变量.装pip.折腾了一上午,最终装逼失败. 于是进入博客园,顶部有篇文章吸引了我 .NET开发一个微 ...

  2. 跳一跳外挂的python实现--OpenCV步步精深

    去我的个人网站看看吧 http://opencvblog.com/跳一跳外挂-python实现/ 都在这里啦

  3. Android远程桌面助手扩展之微信跳一跳辅助

    微信跳一跳的外挂辅助已是五花八门,万能的TB上也有了各种明码标价的代练.微信小程序游戏的火爆甚至带火了手游外挂产业.另一方面,跳一跳游戏也在不断更新,防止使用外挂刷高分.Android远程桌面助手支持 ...

  4. 教你用.Net来玩微信跳一跳

    目前开发的所有代码都已经上传到了GitHub.欢迎大家来Star https://github.com/GiantLiu/AutoJump 目前程序分为“全自动版本”和“半自动版本” 全自动版本 We ...

  5. Python操作微信跳一跳

    “跳一跳”这个东西还是今天刚接触到的,看到了python群中有人再问“微信跳一跳的外挂有人写了没”,“早就有了”,“github”,“等着出个更详细的教程教程没看懂,主要没有用过adb”. 不过没关系 ...

  6. 微信跳一跳Python

    微信最新的小程序里面出了个叫“跳一跳”的小游戏,大神们也通过Python实现了自动玩游戏具体代码 如下: Github地址: https://github.com/wangshub/wechat_ju ...

  7. 微信跳一跳辅助自动跳Python

    一.说明 此代码借鉴github一位大神所写,已经做了简化合并处理,如果能成功连上手机并运行,可以实现程序自动玩游戏,刷个1000+的分数轻轻松松 github源码地址 https://github. ...

  8. 微信跳一跳辅助Demo

    [原创] 前几天没事干看别人一直在玩微信上线的那一个跳一跳小游戏,玩着玩着老是掉下去,闲着没事呗 就想了想做一个辅助程序的呗.不过先做的手动版的.自动版的有点麻烦.就不发了.用的Java写的,也就一个 ...

  9. python 微信跳一跳辅助 复现

    本来用的是苹果ios得手机,但是步骤较为复杂,没有吃透,最后妥协用了android的机器搞得. 首先找到大牛的github https://github.com/wangshub/wechat_jum ...

随机推荐

  1. 安装PHPphp-5.4.4

    一.下载PHPphp-5.4.4 [root@aliyun software]# pwd /software[root@aliyun software]# wget http://mirrors.so ...

  2. CC2530 LED灯控制

      有三个寄存器 分别是功能寄存器.方向寄存器.配置寄存器 功能寄存器 通用 I/O口 说的就是一般的I/O口,可以输出高低电平 为外设IO 例如摄像头或者打印机他们具体实现某些功能(拍照或打印文档) ...

  3. 沉淀再出发:jvm的本质

    沉淀再出发:jvm的本质 一.前言 关于jvm,使用的地方实在是太多了,从字面意思上我们都能明白这也是一个虚拟机,那么其他的虚拟机都会用来运行别的操作系统的,而jvm却是实现了可以在不用的操作系统之上 ...

  4. 在Windows10中破解一些软件

    在Windows10中破解一些软件 一.前言   以前的windows是很好破解的,这里说的windows包含了windows的一些产品,比如说office,visio等等,可是自从到了新版的wind ...

  5. MapReduce Design Patterns(chapter 2(part 1))(二)

    随着每天都有更多的数据加载进系统,数据量变得很庞大.这一章专注于对你的数据顶层的,概括性意见的设计模式,从而使你能扩展思路,但可能对局部数据是不适用的.概括性的分析都是关于对相似数据的分组和执行统计运 ...

  6. Android启动外部应用的方法

    1.根据package的名称获取应用的Launch Intent Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage ...

  7. php中的static

    静态成员是一种类变量,可以把它看成时属于整个类而不是属于类的某个实例.与一般的实例变量不同的是,静态成员只保留一个变量值,而这个变量值对所有的实例都是有效的,也就是说,所有的实例共享这个成员. $th ...

  8. 二、并行编程 - Task任务

    任务,基于线程池.其使我们对并行编程变得更简单,且不用关心底层是怎么实现的.System.Threading.Tasks.Task类是Task Programming Library(TPL)中最核心 ...

  9. Ubuntu下命令行安装jdk,android-studio,及genymotion虚拟机来进行android开发

    安装JDK 从oracle官网下最新版的linux64位的jdk包(现在最新为jdk-8u92-linux-x64.tar.gz) 命令如下 新建文件夹-解压 sudo mkdir /usr/lib/ ...

  10. 【[NOI2011]阿狸的打字机】

    首先发现这个插入的非常有特点,我们可以直接利用这个特殊的性质在\(Trie\)树上模拟指针的进退 之后得到了\(Trie\)树,先无脑建出\(AC\)机 之后考虑一下如何写暴力 最简单的暴力对于每一个 ...