c++编译器(c++用什么软件编程)

技术C++ OpenCV如何模拟实现微信跳一跳小编给大家分享一下C++ OpenCV如何模拟实现微信跳一跳,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!实机演示Gif:思路:获取小黑人的位置,获得目标方

边肖将与大家分享OpenCV如何模拟微信跳转。希望大家看完这篇文章后有所收获。我们一起讨论一下吧!

实机演示Gif:

C++OpenCV如何模拟实现微信跳一跳

00-1010,得到小黑人的位置,得到目标方块的位置,并计算它们之间的距离,从而计算出大致按下屏幕的时间。

实现1:使用牧牧模拟器获取截图。

使用牧牧模拟器模拟手机,然后使用adb调试工具的截图,保存在本地,然后从OpenCV程序中获取本地截图。

实现2:使用adb工具模拟压制。

计算完距离和时间后,考虑用模拟按屏的方法来控制反派的移动。

实施例3:按压的位置正好在“再按一次”按钮上。

即使跳转失败,只要用户不停止,小程序也会继续跳转。

00-1010很简单,只需使用OpenCV的matchTemplate,注意“TM _ ccorr _ normalized”方法。

00-1010这里使用了Canny边缘检测算法。

思路:

将图片从牧牧模拟器保存到本地目录文件夹的文件夹。和调试的缓存目录。

C++OpenCV如何模拟实现微信跳一跳

C++OpenCV如何模拟实现微信跳一跳

您还可以自定义程序运行的周期数:

//最大执行次数

#defineMaxRound100只需修改下一个100。

和您匹配的图案图片位置:

character3.png

C++OpenCV如何模拟实现微信跳一跳

C++OpenCV如何模拟实现微信跳一跳

00-1010项目配置:DebugX64,其中包含头文件opencv头文件。lib被选择为opencv_world425d.dll(因为它似乎是名称)。这个库必须有d。因为我们处于调试模式,所以我们使用这个库。然后链接器的附加输入也填充这个选项。

项目依赖:adb,opencv425

以下是完整的项目参考。

获取小黑人的位置:

C++OpenCV如何模拟实现微信跳一跳

获取终点的位置:

#pragmaonce

#includeopencv2/opencv.hpp

#包括牡蛎

#includeopencv.hpp

#includewindows.h

需要自定义的:

//跳过作弊程序

//版本v1.0.2作者:CSDN陈李倩

/*

*程序使用说明:

*需要配合牧牧模拟器使用,电脑需要安装adb调试工具和opencv库。

*介绍程序原理:

*通过计算两点之间的距离,估计跳跃的长度和按下屏幕的时间间隔。

*

*参考文件:

* https://blog . csdn . net/QQ _ 37406130/article/details/79007335

* https://blog . csdn . net/sundy _ 2004/article/details/7749093

* https://blog . csdn . net/q 5222890/article/details/105533233

* https://blog . csdn . net/QQ _ 47342178/article/details/109779840

*adbswip使用情况:

*https://blog.c

sdn.net/u010042669/article/details/104066744
* Canny 边缘检测:
* https://blog.csdn.net/hensonwells/article/details/112557073
*/

#include "pch.h"
#include <windows.h>
#include <sstream>
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<std::vector<Point>> contours;
std::vector<Vec4i> hierarchy;
findContours(srcImage, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point()); //找到关键的角点
//遍历每一个轮廓,把多余的轮廓去掉
std::vector<std::vector<cv::Point> >::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如何模拟实现微信跳一跳”有了一定的了解,如果想了解更多相关知识,欢迎关注行业资讯频道,感谢各位的阅读!

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/150319.html

(0)

相关推荐

  • mysql的cmake方式有哪些

    技术mysql的cmake方式有哪些这篇文章主要介绍“mysql的cmake方式有哪些”,在日常操作中,相信很多人在mysql的cmake方式有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家

    攻略 2021年10月20日
  • AQS AbstractQueuedSynchronizer的同步框架是什么

    技术AQS AbstractQueuedSynchronizer的同步框架是什么这篇文章将为大家详细讲解有关AQS AbstractQueuedSynchronizer的同步框架是什么,文章内容质量较高,因此小编分享给大

    攻略 2021年10月20日
  • VB.NET局部静态变量的示例分析

    技术VB.NET局部静态变量的示例分析这篇文章将为大家详细讲解有关VB.NET局部静态变量的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。VB支持用Static关键字声明局部变

    攻略 2021年12月1日
  • 如何用MYSQL或者ORACLE的方法管理 POSTGRESQL

    技术如何用MYSQL或者ORACLE的方法管理 POSTGRESQL这期内容当中小编将会给大家带来有关如何用MYSQL或者ORACLE的方法管理 POSTGRESQL ,文章内容丰富且以专业的角度为大家分析和叙述,阅读

    攻略 2021年10月25日
  • 圣诞节送女朋友什么礼物好,圣诞节送女朋友什么礼物好

    技术圣诞节送女朋友什么礼物好,圣诞节送女朋友什么礼物好很多朋友可能会觉得送一些时尚、劲爆的礼物会比较好,但其实流行因素在每个人心中的定位都是不一样的,小编认为,送最适宜对方的礼物就是最好的礼物。▲ 如何包装礼物,礼物包装

    生活 2021年10月24日
  • js数组去重效率最高的方法(js数组遍历的三种方法)

    技术七种JS实现数组去重的方式分别是什么这篇文章将为大家详细讲解有关七种JS实现数组去重的方式分别是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。例:将下面数组去除重

    攻略 2021年12月14日