C++|C++ OpenCV模拟实现微信跳一跳
目录
- 前提精要:
- 实机演示Gif:
- 思路:
- 获取小黑人的位置:
- 获取终点的位置:
- 需要自定义的:
- 完整项目:
- 项目结构
- pch.h
- main.cpp
前提精要: 本程序参考了大量的大佬佬的代码,在此基础之上,改编而成。而且其实代码写的奇差无比,很容易就挂了。然后呢,这里只是稍微提供一些思路,作为参考,就酱。
【C++|C++ OpenCV模拟实现微信跳一跳】本程序依赖adb.exe和opencv425库。
本程序还有待优化,很渣很糟糕~
仅供学习交流使用,切勿使用在违规违法的环境之中。
实机演示Gif:
思路: 获取小黑人的位置,获得目标方块的位置,计算两者的距离,从而计算粗按压屏幕的时间是多少。
具体实现1:使用mumu模拟器获取截图
使用mumu模拟器,模拟手机端,然后使用adb调试工具截图,保存到本地,然后从OpenCV程序获取在本地的截图。
具体实现2:使用adb工具模拟按压
当计算完距离和时间之后,考虑使用模拟按压屏幕的方法,控制小人的移动。
具体实现3:按压的位置刚好在“再来一次”的按钮上
这样就算跳失败了,只要用户不停下,那么小程序就会一直的进行跳跃。
获取小黑人的位置: 很简单,只是使用OpenCV的matchTemplate就可以啦,注意使用“TM_CCORR_NORMED”方法。
获取终点的位置: 这里使用的是Canny边缘检测算法
需要自定义的: 一个文件夹,将图片,从mumu模拟器,保存到本地的目录文件夹。和Debug的缓存目录。
文章图片
文章图片
您还可以自定义,程序运行的循环次数:
//最大执行次数#define MaxRound 100
修改后面的100即可。
还有您的匹配模式图片位置:
character3.png
文章图片
文章图片
完整项目: 项目配置:DebugX64,包含头文件opencv头文件,lib选择为opencv_world425d.dll(好像是这个名字),这个lib一定要有d,因为我们是Debug模式,所以使用这个库。然后链接器的附加输入,也填入这个选项。
项目依赖:adb、opencv425
下面是完整的项目参考。
项目结构
文章图片
pch.h
#pragma once#include#include #include #include
main.cpp
//跳一跳作弊程序//版本 v1.0.2 作者:CSDN陈千里/** 程序使用说明:* 需要配合mumu模拟器使用,电脑需要安装adb调试工具,和opencv库。* 程序原理介绍:* 通过计算两点之间的距离,估算跳跃的长度,按压屏幕的时间间隔** 参考论文:* https://blog.csdn.net/qq_37406130/article/details/79007335* https://blog.csdn.net/sundy_2004/article/details/7749093* https://blog.csdn.net/q5222890/article/details/105533233* https://blog.csdn.net/qq_47342178/article/details/109779840* adb swip使用:* https://blog.csdn.net/u010042669/article/details/104066744* Canny 边缘检测:* https://blog.csdn.net/hensonwells/article/details/112557073*/#include "pch.h"#include#include using namespace cv; Mat srcImage; //存放跳一跳的截图Mat blackPeopleTem; //黑色小人匹配图std::stringstream ssm; //int转string//最大执行次数#define MaxRound 100//由于分辨率的不同,微调终点的位置#define Tuning 0.52f//Debug函数void DebugImg(const std::string& fileName, Mat& mat, const Point& point); void DebugImg(const std::string& fileName, Mat& mat); //刷新srcImage的信息(截图)void refreshSrcImage() { system("adb shell screencap -p /sdcard/ScreenCatch.png"); //您需要自定义的地方,下面的"C:\\adb" system("adb pull /sdcard/ScreenCatch.png C:\\adb\\temp"); srcImage = imread("C:\\adb\\temp\\ScreenCatch.png"); }//寻找跳一跳黑色小人的位置Point GetNowPoint(Mat& srcImage, Mat& Tem_img) { cv::Mat image_matched; matchTemplate(srcImage, Tem_img, image_matched, TM_CCORR_NORMED); // 匹配黑棋子 double minVal, maxVal; Point minLoc, maxLoc, matchLoc; DebugImg("黑人匹配图.png", image_matched); minMaxLoc(image_matched, &minVal, &maxVal, &minLoc, &maxLoc, Mat()); matchLoc = maxLoc; //matchLoc是最佳匹配的区域左上角点 //调试输出 DebugImg("1黑人位置.png", srcImage, Point(matchLoc.x + Tem_img.cols, matchLoc.y + Tem_img.rows)); //DebugImg("1黑人位置.png", srcImage, Point(matchLoc.x + Tem_img.cols * 0.5, matchLoc.y + Tem_img.rows)); return Point(matchLoc.x, matchLoc.y); }//获得小方块的目标点Point GetNextPoint(Mat& srcImage) { cv::Point point1; cv::Point point2; cv::GaussianBlur(srcImage, srcImage, cv::Size(5, 5), 0); //高斯滤波,降低噪声 Mat temp, temp2; //cv::threshold(srcImage, temp, 0, 255, 8); //srcImage = temp; Canny(srcImage, temp, 20, 30); //进行边缘检测 temp2 = srcImage; srcImage = temp; std::vector> contours; std::vector hierarchy; findContours(srcImage, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point()); //找到关键的角点 //遍历每一个轮廓,把多余的轮廓去掉 std::vector >::const_iterator it = contours.begin(); while (it != contours.end()) {if (it->size() < 150)it = contours.erase(it); else++it; } int nYMin = srcImage.rows; int nXMin = srcImage.cols; int nYMax = 0; int nXMax = 0; int nIdY = 0; for (int i = 0; i < contours.size(); i++) {//contours[i]代表的是第i个轮廓,contours[i].size()代表的是第i个轮廓上所有的像素点数for (int j = 0; j < contours[i].size(); j++) {if (contours[i][j].y < nYMin) {nYMin = contours[i][j].y; //找到最低的y值point1 = contours[i][j]; //记录y值最低点坐标nIdY = i; //记录哪个区域内的}} } int minY = srcImage.cols; for (int j = 0; j < contours[nIdY].size(); j++) { //在哪个区域内继续变量 找到x最大值if (contours[nIdY][j].x > nXMax) {nXMax = contours[nIdY][j].x; } } for (int j = 0; j < contours[nIdY].size(); j++) {//找到x中最大值上的最小值if (contours[nIdY][j].x == nXMax && contours[nIdY][j].y < minY) {point2 = contours[nIdY][j]; minY = contours[nIdY][j].y; //记录X点的最大值} } //调试输出 DebugImg("2目标点位置.png", temp2, Point(point1.x, point2.y)); DebugImg("边缘图.png", srcImage, Point(point1.x, point2.y)); return cv::Point(point1.x, point2.y); //返回中点坐标}//计算两个点的距离float GetDistance(Point& first_point, Point& next_point) { float A = first_point.x - next_point.x; float B = first_point.y - (next_point.y + 50); float result = pow(pow(A, 2) + pow(B, 2), 0.5); if (result > 600) {std::cout << "距离探测失误" << std::endl; result = 230; } return result; }//模拟按压屏幕跳跃void Jump(float& g_distance) { std::cout << "distance:" << g_distance << std::endl; int time = std::ceil(g_distance * 4 * Tuning); std::string str_Time, str; //模拟长按屏幕 ssm.clear(); ssm << time; ssm >> str_Time; str = "adb shell input swipe 461 1203 461 1203 " + str_Time; std::cout << str << std::endl; system(str.c_str()); }//主过程void Process() { Point pBlackPeople; Point pFinish; float dis; for (int i = 0; i < MaxRound; i++) {refreshSrcImage(); pBlackPeople = GetNowPoint(srcImage, blackPeopleTem); pFinish = GetNextPoint(srcImage); dis = GetDistance(pBlackPeople, pFinish); Jump(dis); Sleep(2000); }}int main() { /*srcImage = imread("C:/adb/Test/1.png"); blackPeopleTem = imread("C:/adb/Resources/character3.png"); GetNowPoint(srcImage, blackPeopleTem); */ //首先要链接端口 system("adb connect 127.0.0.1:7555"); refreshSrcImage(); blackPeopleTem = imread("C:/adb/Resources/character3.png"); //初始化到此结束 Process(); int x = 280; // 裁剪区域起始点 x坐标 int y = 400; // 裁剪区域起始点 y坐标 int width = 100; // 裁剪区域宽度 int height = 100; // 裁剪区域高度 //Rect area(x, y, width, height); //Mat guide_roi = srcImage(Rect(x, y, width, height)); //测试代码 //namedWindow("test opencv setup", WINDOW_AUTOSIZE); //imshow("test opencv setup", srcImage); //waitKey(0); return 0; }//保存图片和画点,用于调试void DebugImg(const std::string& fileName, Mat& mat, const Point& point) { Mat temp = mat; //在图片上面画点 circle(temp, point, 5, Scalar(0, 0, 255), -1); std::string path = "c:/adb/temp/", sR; sR = path + fileName; imwrite(sR, temp); }void DebugImg(const std::string& fileName, Mat& mat) { std::string path = "c:/adb/temp/", sR; sR = path + fileName; imwrite(sR, mat); }
到此这篇关于C++ OpenCV模拟实现微信跳一跳的文章就介绍到这了,更多相关C++ OpenCV微信跳一跳内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- opencv|opencv C++模板匹配的简单实现
- Java|Java OpenCV图像处理之SIFT角点检测详解
- C语言学习|第十一届蓝桥杯省赛 大学B组 C/C++ 第一场
- c++基础概念笔记
- 三门问题(蒙提霍尔悖论)分析与Golang模拟
- 投石机可连续抛射石头【Algodoo|投石机可连续抛射石头【Algodoo | 物理模拟】
- 牛逼!C++开发的穿越丛林真人游戏,游戏未上线就有百万人气
- OpenCV|OpenCV-Python实战(18)——深度学习简介与入门示例
- C++Primer之|C++Primer之 函数探幽
- c/c++|有感 Visual Studio 2015 RTM 简介 - 八年后回归 Dot Net,终于迎来了 Mvc 时代,盼走了 Web 窗体时代...