趁着期末这段时间,课程不多,在学习opencv,闲来无事,看到网上有大神用python实现了Wechat的跳一跳的辅助外挂,看了大概原理,似乎跟我最近学的opencv好像很沾边,但是鄙人实在不懂Python,于是想着用C++就把它给实现了。原文链接:https://github.com/wangshub/wechat_jump_game,感兴趣的同学们可以看一下大神版本。

步入正题

先说原理,我这里直接copy大神的:

将手机点击到《跳一跳》小程序界面,用 ADB 工具获取当前手机截图,并用 ADB 将截图传上来,靠棋子的颜色来识别棋子,靠底色和方块的色差来识别棋盘(重点),用 ADB 工具点击屏幕一跳。

开发环境:

所谓工欲善必先利其器,鄙人的平台是win7 64位+vs2015+opencv 3.4+adb工具+荣耀4X(分辨率:720x1280),只对此分辨率作适配过,其它的我试了一下,不可行,等考完试我再适配。环境配置网上很多,这里就不浪费时间了。adb工具直接放到工程文件夹下即可。

前提准备工作:把手机用数据线连到电脑,装好驱动,打开开发者模式,打开USB调试,下载adb工具,这里最好配个环境变量。不配也行,打开cmd命令窗口,转到adb目录,键入 adb devices 命令(坑爹的魅族手机,它就是连接不了,不得不借用同学的备用手机荣耀4x来测试),如下:

连接成功之后,开始写代码了

打开vs,新建工程键入头文件这些这些不多说了,同学们都会,

1.使用system命令,截图,并传上来,用imread读入到变量scree去

system("adb shell screencap -p /sdcard/autojump.jpg");//截图
system("adb pull /sdcard/autojump.jpg");              //上传到电脑
Mat scree = imread("autojump.jpg");            //读入

2.对图像进行处理,分两步,一是先找出棋子的位置,二是找到物体的中心位置

1).找棋子。找规律,发现的棋子的颜色在游戏中好像是独一无二的,利用这点,我们很容易找到棋子的位置,用ps拾取棋子底部的RGB三个通道颜色(注意了,opencv的储存通道的顺序是BGR)作为参考点,然后从图像下方(逐行逐个像素)往上扫描(为什么是从下往上?因为我们要的是棋子的下方,如果是上方,找的是棋子的脑袋),如果扫描到的点的各通道的数值与参考点的作对比,如果各点的误差的值的和少于20(数值根据需要适当的调),那么认为是找到了。代码如下:

Point ptc, ptm;                              //存储棋子底下与物体中心的坐标
void draw_color(Mat &img)
{   int average = 0;int channels = img.channels();int nRows = img.rows;int nCols = img.cols* channels;int i = (int)nRows * 1 / 3;                  //不用整个图像都扫描,高的1/3就行int b_color = 102;                       //定义棋子蓝色通道值int g_color = 54;                       //定义棋子绿色通道值int r_color = 53;                       //定义棋子红色通道值int man_x = 0;int man_y = 0;int fla = 0;for (man_y = i + 350; man_y>i + 100; man_y--){for (man_x = 99; man_x < nCols - 99; man_x += 3){if ((abs((int)img.at<uchar>(man_y, man_x) - b_color) +abs((int)img.at<uchar>(man_y, man_x + 1) - g_color) +abs((int)img.at<uchar>(man_y, man_x + 2) - r_color)) < 20) //判断{ptm.x = (int)man_x / 3.0;     //记录坐标,因为opencv存储图像点是以三通道存储的,所以除以3ptm.y = man_y - 5;         //下移,防止找到背景点的bugfla = 1;break;}}if (fla)break;}draw_garry(img, ptm.x);//调用另外一下函数,由另外的函数去找物体顶面上的中点
}

2).找到棋子的坐标坐标之后,我们要找物体的顶面上的中点。分两步,1是找物体的顶面的上界,2是找物体的顶面的下界。

首先从图像上方往下扫描,大概屏幕往下的1/4开始找,因为这部分区域基本上是背景,无其它的颜色,所以利用这点,我们以此处的第一行为参考,把一行中每一点的像素值加起来,与第一行作对比,如果比参考值大或者小于某个数值(适当的调整),则认为是有物体了(先把图像转换为灰度比较好处理)。然后再往右扫描,以第一个像素点作对比,然后比较他们的绝对差,大于某个值,就是找到了

代码如下

        Mat img;cvtColor(thr, img, COLOR_RGB2GRAY);int sum = 0;int average = 0;int channels = img.channels();int nRows = img.rows;int nCols = img.cols* channels;int k = 0;int f = 0;Rect r1;Rect r2;Point pt1, pt2;int stat_y = (int)(nRows*(2.0 / 6.0));pt2.x = nCols;pt1.x = 0;pt1.y = 0;pt2.y = 0;int i;int j;//找出物体的第一行//扫描每一行,如果下一行与第一行的像素总和相差正负30个,那么就不是纯色,有物体了for (i = stat_y; i < nRows; ++i){for (j = 0; j<nCols; j++){sum += img.at<uchar>(i, j);//把一行的像素值加起来}if (sum != 0)if (k == 0){f = sum;k = 1;}if (sum <f - 30|| sum>f + 30)//如果这行与参考行的像素值相差正负30,那么认为是有物体{average = 1;break;}if (average)break;sum = 0;}
 //找出有物体的第一行后
    //接着找出非背景的第一点
    int fl = i + 273;//物体最大不会高于273行
    int i_x = 0;
    int i_y = 0;
    int kk = 0;
    for (; i < fl; ++i)
    {
        for (j = 0; j<nCols-1; j++)
        {
            //如果前一点与后一点的像素值相差大于5,那么就是找到了
            kk = abs((int)img.at<uchar>(i, j) - (int)img.at<uchar>(i, j+1));
            //为了防止棋子的脑袋超过物体,所以先找出棋子的x轴方向的位置,
            //如果这时找出的第一点与棋子的坐标相接近,则继续找
            if (abs(j - man_xx) < 30)
                continue;
            if (kk>5)
            {
                i_x = j;
                i_y = i;
                pt1.x = i_x;
                pt1.y = i_y;
                break;
            }       }
        if (i_x != 0)
            break;
    }

同理,嗯嗯,我很喜欢这词,每当用这个词的时候可以省略好多字好多言语。我们取上界那个点的颜色作参考点,由下往上找,就能找到下界的点了

 int n;int n_x = 0;int n_y = 0;//找出物体的下界,以便求中点for (n = fl; n >= i; n--){//用上面找到物体的那一点的像素值来判断,相差不大于10就是找到了if (abs((int)img.at<uchar>(i+1, j) - (int)img.at<uchar>(n, j)) < 10){pt2.x = j;pt2.y = n;break;}}

上下界的点找到之后,物体的顶面的中点就很容易计算出来了

 ptc.x = j;ptc.y = (int)((n - i) /2) + i;//计算物体顶面中点

3.计算物体顶面中点到棋子底部的距离,不多说,两点距离公式,并乘上系数0.5再除以0.25,就是按压时间。

 //计算人到物体中心距离//两点距离公式,距离再乘以0.5再除以0.25就是按压时间int S = (int)sqrt((ptc.x - ptm.x)*(ptc.x - ptm.x) + (ptc.y - ptm.y)*(ptc.y - ptm.y))*0.5 / 0.25;

4.发送命令:adb shell input swipe 320 420 320 410,在坐标320,410到坐标320,410模拟滑到时间S毫秒,也就是按压S毫秒啦啦。

 char ch[50] = { " " };//把按压时间与命令放到一个字符串上sprintf(ch, "adb shell input swipe 320 410 310 410 %d", S);//用system命令输入system(ch);

所有代码:

main.cpp文件
#include "header.h"int main()
{cout << "微信跳一跳辅助程序,彬彬移植于网络大神的python的版本\n此版本是用C++与opencv定的还有很多bug\n";cout << "请确保打开了手机微信跳一跳 y or n?\n";getchar();while(1){system("adb shell screencap -p /sdcard/autojump.jpg");system("adb pull /sdcard/autojump.jpg");Mat scree = imread("autojump.jpg");draw_color(scree);Sleep(1500);//延时,不能太快}system("pause");return 0;
}
gray.cpp文件
#include "header.h"
Point ptc, ptm;                             //存储棋子底下与物体中心的坐标/************找出棋子的底下的坐标*****************///判断当前点与人物底下的颜色相似
//对应的通道像素值作差取绝对值
//即参考的红色通道值-扫描点的红色通道点等三个通道分别减取绝对值
//然后相加,如果少于20,那就认为这两点颜色相同
//记录坐标
************************************************/
void draw_color(Mat &img)
{   int average = 0;int channels = img.channels();int nRows = img.rows;int nCols = img.cols* channels;int i = (int)nRows * 1 / 3;              //不用整个图像都扫描,高的1/3就行int b_color = 102;                       //定义棋子蓝色通道值int g_color = 54;                       //定义棋子绿色通道值int r_color = 53;                       //定义棋子红色通道值int man_x = 0;int man_y = 0;int fla = 0;for (man_y = i + 350; man_y>i + 100; man_y--){for (man_x = 99; man_x < nCols - 99; man_x += 3){if ((abs((int)img.at<uchar>(man_y, man_x) - b_color) +abs((int)img.at<uchar>(man_y, man_x + 1) - g_color) +abs((int)img.at<uchar>(man_y, man_x + 2) - r_color)) < 20) //判断{ptm.x = (int)man_x / 3.0; //记录坐标,因为opencv存储图像点是以三通道存储的,所以除以3ptm.y = man_y - 5;         //下移,防止找到背景点的bugfla = 1;break;}}if (fla)break;}draw_garry(img, ptm.x);
}
void draw_garry(Mat &thr,int man_xx)
{Mat img;cvtColor(thr, img, COLOR_RGB2GRAY);int sum = 0;int average = 0;int channels = img.channels();int nRows = img.rows;int nCols = img.cols* channels;int k = 0;int f = 0;Rect r1;Rect r2;Point pt1, pt2;int stat_y = (int)(nRows*(2.0 / 6.0));pt2.x = nCols;pt1.x = 0;pt1.y = 0;pt2.y = 0;int i;int j;//找出物体的第一行//扫描每一行,如果下一行与第一行的像素总和相差正负30个,那么就不是纯色,有物体了for (i = stat_y; i < nRows; ++i){for (j = 0; j<nCols; j++){sum += img.at<uchar>(i, j);//把一行的像素值加起来}if (sum != 0)if (k == 0){f = sum;k = 1;}if (sum <f - 30|| sum>f + 30)//如果这行与参考行的像素值相差正负30,那么认为是有物体{average = 1;break;}if (average)break;sum = 0;}//找出有物体的第一行后//接着找出非背景的第一点int fl = i + 273;//物体最大不会高于273行int i_x = 0;int i_y = 0;int kk = 0;for (; i < fl; ++i){for (j = 0; j<nCols-1; j++){//如果前一点与后一点的像素值相差大于5,那么就是找到了kk = abs((int)img.at<uchar>(i, j) - (int)img.at<uchar>(i, j+1));//为了防止棋子的脑袋超过物体,所以先找出棋子的x轴方向的位置,//如果这时找出的第一点与棋子的坐标相接近,则继续找if (abs(j - man_xx) < 30)continue;if (kk>5){i_x = j;i_y = i;pt1.x = i_x;pt1.y = i_y;break;}}if (i_x != 0)break;}int n;int n_x = 0;int n_y = 0;//找出物体的下界,以便求中点for (n = fl; n >= i; n--){//用上面找到物体的那一点的像素值来判断,相差不大于10就是找到了if (abs((int)img.at<uchar>(i+1, j) - (int)img.at<uchar>(n, j)) < 10){pt2.x = j;pt2.y = n;break;}}ptc.x = j;ptc.y = (int)((n - i) /2) + i;//计算物体中点//计算人到物体中心距离//两点距离公式,距离再乘以0.5再除以0.25就是按压时间int S = (int)sqrt((ptc.x - ptm.x)*(ptc.x - ptm.x) + (ptc.y - ptm.y)*(ptc.y - ptm.y))*0.5 / 0.25;char ch[50] = { " " };//把按压时间与命令放到一个字符串上sprintf(ch, "adb shell input swipe 320 410 310 410 %d", S);//用system命令输入system(ch);cout << "\n" << ch << endl;}
头文件
#define _CRT_SECURE_NO_WARNINGS//关闭安全检查,须放到最前面
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <Windows.h>
#include <cmath>
using namespace cv;
using namespace std;
void draw_color(Mat &img);
void draw_garry(Mat &img, int x);//找出物体的中心位置

逐个添加进工程即可,至少分辨率的适配,调下里面那些数据就好, adb工具搜索下载即可。

希望期末考试不挂科不挂科

微信跳一跳辅助程序开发,基于C++与opencv图像识别相关推荐

  1. c语言跳一跳辅助源码,.NET 开发一个微信跳一跳辅助程序(附源码)

    原标题:.NET 开发一个微信跳一跳辅助程序(附源码) 来源:中国.NET研究协会 cnblogs.com/dotnet-org-cn/p/8149693.html 前言 微信更新了,出现了一个小游戏 ...

  2. c语言微信挑一挑编程,100行python代码实现微信跳一跳辅助程序

    写在前面 分享一下今天下午用python写的"跳一跳"小游戏的辅助程序.之前是准备用树莓派操控一个"机械手指"来代替人的触摸操作,但该方案还在酝酿中,实现了再分 ...

  3. 100行python代码做一个程序_100行python代码实现微信跳一跳辅助程序

    写在前面 分享一下今天下午用python写的"跳一跳"小游戏的辅助程序.之前是准备用树莓派操控一个"机械手指"来代替人的触摸操作,但该方案还在酝酿中,实现了再分 ...

  4. c语言微信跳一跳辅助开发程序

    一.开发环境 开发环境 使用语言:C/C++ IDE:VS2010+ 其他三方库 EasyX(http://www.easyx.cn/downloads/) ADB(链接: https://pan.b ...

  5. 微信跳一跳高分系列四:一个 JAVA 版开源的微信跳一跳辅助工具

    基于前三篇文章,我们一起来制作一个自动化工具,解放劳动力,通过机器自动完成跳一跳 wechat-jump-helper 一款JAVA版开源的微信跳一跳小程序辅助工具 传送门一:wechat-jump- ...

  6. python微信公众号秒杀代码_微信跳一跳辅助python代码实现

    微信跳一跳辅助python代码实现 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  微信跳一跳辅助python代码实现.txt ] (友情提示:右键点上行txt文档 ...

  7. 微信跳一跳python全部代码_微信跳一跳辅助python代码实现

    微信跳一跳辅助的python具体实现代码,供大家参考,具体内容如下 这是一个 2.5D 插画风格的益智游戏,玩家可以通过按压屏幕时间的长短来控制这个「小人」跳跃的距离.可能刚开始上手的时候,因为时间距 ...

  8. android跳一跳微信修改器,游戏蜂窝微信跳一跳辅助使用教程[多图]

    微信跳一跳怎么使用游戏蜂窝?很多玩家都还不知道,下面就让安卓乐园小编为大家带来,微信跳一跳辅助使用教程. 跳一跳是一个微信小程序.2017年12月28日,微信更新的 6.6.1 版本开放了小游戏,微信 ...

  9. 微信跳一跳辅助php,微信跳一跳辅助python代码实现

    微信跳一跳辅助的python具体实现代码,供大家参考,具体内容如下 这是一个 2.5D 插画风格的益智游戏,玩家可以通过按压屏幕时间的长短来控制这个「小人」跳跃的距离.可能刚开始上手的时候,因为时间距 ...

最新文章

  1. NR 5G UE初始接入流程
  2. 工厂方法模式与IoC/DI
  3. 给定一个n节点的二叉树,写出一个O(n)时间递归过程,将该树每个节点关键字输出(算法导论第十章10.4-2)
  4. 漫谈数据挖掘从入门到进阶
  5. 开源jumpserver 堡垒机搭建
  6. 一个突变基因保护了欧洲人祖先
  7. java stringutils api_StringUtils工具类常用api 转
  8. php : 开发记录(2017-03-10)
  9. jenkins+phantomjs环境搭建及使用
  10. 计算机组成原理经典试卷
  11. TELEPORTSTONE.LUA --传送宝石
  12. 我和数据类型抗争的血泪史(二十五分钟)
  13. ElasticSearch——路由(_routing)机制
  14. 软件评测师:数据库知识
  15. 如何解决1万个并发连接,用每个客户一个线程的方法
  16. Expected required, optional, or repeated.错误解决方法
  17. 7-112 斐波那契数列 (10 分)
  18. 「英语口语」六级口语考题应答模板
  19. java8 日期范围内 日/周/月/季度/年 的日期结果集
  20. 【新】使用setuptools打包Python项目

热门文章

  1. windows下搭建hadoop
  2. 【2021】03 C++
  3. flask使用redis
  4. java根据h5页面生成图片_Js实现将html页面或div生成图片
  5. 【超详细的贝叶斯滤波原理】(不看后悔)
  6. JS 只能输入数字,数字和字母等的正则表达式
  7. 微信小程序海报功能插件
  8. 苹果加码 iOS 16 的限制:继 AirPlay 后不再支持通过 HDMI 适配器投屏 DRM 内容
  9. 目标检测——FasterRCNN原理与实现
  10. Android 驱动和系统开发 1. 一个简单的例子(原创)