亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

基于VS+Opencv2.4.10微信跳一跳輔助工具

 更新時間:2018年01月10日 11:00:01   作者:att0206  
這篇文章主要為大家詳細介紹了基于VS+Opencv2.4.10微信跳一跳輔助工具,具有一定的參考價值,感興趣的小伙伴們可以參考一下

最近微信的跳一跳小程序可謂火了一把,不是因為它本身多好玩,而是有大部分的程序員們加入其中,利用各種領(lǐng)域方法,實現(xiàn)了微信跳一跳的外掛,分數(shù)輕松上千或上萬。之前也看了基于Python開源的代碼,GitHub上現(xiàn)在的star已經(jīng)快超過1W了,簡直不敢想。趁著今天禮拜天,在實驗室中也簡單的實現(xiàn)了一下微信跳一跳的輔助工具,精度還不夠高,我跑了一下才到90,純屬娛樂好玩的,后期再繼續(xù)改進,主要是依賴C++來實現(xiàn)了一下。
環(huán)境: Win10+VS2012+Opencv2.4.10+ADB工具
環(huán)境的搭建請查閱相關(guān)資料!

主要思路:

通過adb圖像獲取部分大家可以查閱相關(guān)資料,代碼也很簡單:

adb shell screencap -p /sdcard/autojump.png
adb pull /sdcard/autojump.png

利用上面兩行代碼即可將手機當前的屏幕進行截圖并且上傳到工程文件路徑下。

首先就是在上傳的autojump.png圖片上進行模板匹配,匹配出小人,并計算小人的坐標;
然后就是通過Canny()函數(shù)進行圖像的邊緣檢測,這里使用的閾值為5,10基本可以檢測出所有邊緣信息;
然后根據(jù)一般下一個要跳的地點始終在小人的左半屏或又半屏部分這一先驗知識,來進行查找范圍的確定,進行行掃描,掃描到的第一個值為255的即返回當前坐標值;然后通過計算與小人坐標的距離即可得到下一步要跳躍的距離,(注:本代碼中在下一個坐標的縱坐標進行+50處理,由于本文中只利用了一個關(guān)鍵點進行測試的,這樣做是顯然不合理的,接下來可以再利用第二個關(guān)鍵點進行下一個跳躍目標中心點的計算),由于本人手機是1080*1920的所以再得到距離過后乘以一個跳躍系數(shù)1.35,(這里不同分辨率的手機系數(shù)是不一樣的),這樣就得到了跳躍按壓時間,從而通過system()命令進行調(diào)用ADB工具進行與手機通訊實現(xiàn)模擬人的點擊。本文僅僅是簡單的實現(xiàn)了一下看看效果,如果想跑高分還得進行代碼的優(yōu)化與更改!其次因為每次按壓的地點肯定是不一樣的,而本文也采用簡單的同一位置按壓,這樣做很容易被騰訊反作弊給查出來的,所以這里可以添加一個隨機數(shù)從而可以簡單的避免位置重復!

代碼如下:

/*
 時間:2018-1-7
 地點:SHNU
 功能:wechat簡單跳一跳C++代碼的實現(xiàn),有待改進,僅供學習之用!歡迎大家提出新算法
*/

#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>

using namespace cv;
using namespace std;

//全局變量定義區(qū)
Mat srcImage;
Mat dstImage;
Mat Character;
//get_screenshot();獲取手機上的圖像
void get_screenshot();
//Canny_Dec();邊緣檢測
void Canny_Dec(Mat& srcImage);
//獲取Character坐標
Point get_Character_Loc(Mat& srcImage,Mat& Tem_img);
//獲取下一個要跳的點
Point get_next_img_Loc(Mat& srcImage,Point& Character_Loc);
//計算距離
int get_distance(Point& first_point,Point& next_point);
//跳躍
void jump(int&g_distance);
int main(int argc,char** argv)
{
 system("color 3F");
 while (true)
 {
 get_screenshot();
 srcImage = imread("autojump.png");
 dstImage = srcImage.clone();
 Character = imread("./Template/character.png");
 //imshow("Character",Character);
 //cvtColor(srcImage,srcImage,CV_BGR2GRAY);
 Point next_p = get_Character_Loc(srcImage,Character);
 cout<<"next_p:"<<1111<<endl;

 Point get_next = get_next_img_Loc(srcImage,next_p);

 int g_distance = get_distance(next_p,get_next);

 jump(g_distance);
 //cout<<"get_next_img_Loc:"<<get_next<<endl;
 circle(dstImage,get_next,8,Scalar(0,221,2));
 //imshow("test",dstImage);
 imwrite("Canny.png",dstImage);
 _sleep(1500);
 }
 return 0;
}

void get_screenshot()
{
 system("adb shell screencap -p /sdcard/autojump.png");
 system("adb pull /sdcard/autojump.png");
}

Point get_Character_Loc(Mat& srcImage,Mat& Tem_img)
{
 matchTemplate(srcImage,Tem_img,dstImage,CV_TM_SQDIFF);
 double minVal,maxVal;
 Point minLoc,maxLoc,matchLoc;
 minMaxLoc(dstImage,&minVal,&maxVal,&minLoc,&maxLoc,Mat());
 matchLoc = minLoc; //matchLoc是最佳匹配的區(qū)域左上角點

 rectangle(srcImage,Rect(matchLoc,Size(Character.cols,Character.rows)),Scalar(255,255,0),1,8,0);
 //Canny(srcImage,srcImage,1,10);
 putText(srcImage,"Wang",Point(matchLoc.x+Character.cols*0.5,matchLoc.y+Character.rows),1,2,Scalar(0,0,255));//畫出Character小人的坐標
 return Point(matchLoc.x+Character.cols*0.5,matchLoc.y+Character.rows);
}

Point get_next_img_Loc(Mat& srcImage,Point& Character_Loc)
{
 cout<<"get_next_img_Loc"<<endl;
 cvtColor(srcImage,srcImage,CV_BGR2GRAY);
 Canny(srcImage,srcImage,5,10);
 imwrite("get_next_img_Loc.png",srcImage);
 //imshow("get",srcImage);
 cout<<"Character_Loc.x:"<<Character_Loc.x<<endl;
 if(Character_Loc.x < 540)
 {
  for(int j = int(srcImage.rows*0.2);j<int(srcImage.rows*0.8);j++)
  {
   uchar* data = srcImage.ptr<uchar>(j);
   for(int i = 1079;i > 540 ;i--)
   {

    if(data[i] == 255)
    {
     return Point(i,j);
     //cout<<"Point:"<<Point(i,j)<<endl;
    }
   }
  }
 }
 else
 {
  for(int j = int(srcImage.rows*0.2);j<int(srcImage.rows*0.8);j++)
  {
   uchar* data = srcImage.ptr<uchar>(j);
   for(int i = 0;i<540;i++)
   {
    if(data[i] == 255)
     return Point(i,j);
   }
  }
 }
}

int get_distance(Point& first_point,Point& next_point)
{
 int A = first_point.x - next_point.x;
 int B = first_point.y - (next_point.y+50);
 return int(pow(pow(A,2)+pow(B,2),0.5));
}

void jump(int&g_distance)
{
 char AA[50];
 int distance_ = g_distance * 1.35;
 sprintf(AA,"adb shell input swipe 320 410 320 410 %d",distance_);
 cout<<AA<<endl;
 system(AA);
}

邊緣檢測圖片:

這里寫圖片描述

下一個關(guān)鍵點定位:

這里寫圖片描述

上圖中畫出的小圈圈,不太清晰,將就著看下!小菜水平有限,僅僅是基于好玩就弄了下!

結(jié)果:用開源的隨便跑跑幾百,自己的怎么跑,90 【累哭】

這里寫圖片描述

華麗的分割線————————————————

又來更新一下啦!

晚上不想看論文就想到了之前的跳一跳,經(jīng)過一邊顯示命令窗口輸出和一邊顯示Canny()邊緣化處理終于找到了上次跑的分數(shù)低的原因啦!

主要原因如下所示:

這里寫圖片描述

如上所示,由于之前選取的Canny()中的閾值為1和10,這導致一旦要跳到的下一個目標物體的顏色和背景色很接近時就很容易使得邊緣的梯度小于10,因此就不會被認為是邊緣,從而導致上面的這種情況出現(xiàn)。索性今天就將閾值設(shè)為3和8,并在Canny()函數(shù)前面加上了一個高斯濾波器。如下:

GaussianBlur(srcImage,srcImage,Size(3,3),0);

還有就是上面的_sleep(1500)函數(shù),這里如果閑時間比較久的話也是可以改為1000的,速度上有所提升。
同時加上按壓位置的隨機數(shù),使得每次按壓點都是在(320,410)—(350,460)之間。代碼如下:

 int rand_x = int(320+rand()%50); //加上隨機數(shù)使得每次按壓都是在點(320,410)-(370,460)之間
 int rand_y = int(410+rand()%50);
 sprintf(AA,"adb shell input swipe %d %d %d %d %d",rand_x,rand_y,rand_x,rand_y,distance_);

如下圖所示:

由上圖可知,每次按壓的位置都是在變的。

完整版代碼如下:

/*
 時間:2018-1-7
 地點:SHNU
 功能:wechat簡單跳一跳C++代碼的實現(xiàn),有待改進,僅供學習之用!歡迎大家提出新算法
*/

#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
#include<stdlib.h>//rand()隨機數(shù)頭文件

using namespace cv;
using namespace std;

//全局變量定義區(qū)
Mat srcImage;
Mat dstImage;
Mat Character;

static int i = 0;
//get_screenshot();獲取手機上的圖像
void get_screenshot();
//Canny_Dec();邊緣檢測
void Canny_Dec(Mat& srcImage);
//獲取Character坐標
Point get_Character_Loc(Mat& srcImage,Mat& Tem_img);
//獲取下一個要跳的點
Point get_next_img_Loc(Mat& srcImage,Point& Character_Loc);
//計算距離
int get_distance(Point& first_point,Point& next_point);
//跳躍
void jump(int&g_distance);
int main(int argc,char** argv)
{
 system("color 3F");
 while (true)
 {
 get_screenshot();
 srcImage = imread("autojump.png");
 dstImage = srcImage.clone();
 Character = imread("./Template/character.png");
 //imshow("Character",Character);
 //cvtColor(srcImage,srcImage,CV_BGR2GRAY);
 Point next_p = get_Character_Loc(srcImage,Character);
 //cout<<"next_p:"<<1111<<endl;

 Point get_next = get_next_img_Loc(srcImage,next_p);

 int g_distance = get_distance(next_p,get_next);

 jump(g_distance);
 //cout<<"get_next_img_Loc:"<<get_next<<endl;
 circle(dstImage,get_next,8,Scalar(0,221,2));
 //imshow("test",dstImage);
 imwrite("Canny.png",dstImage);
 _sleep(1000);
 }
 return 0;
}

void get_screenshot()
{
 system("adb shell screencap -p /sdcard/autojump.png");
 system("adb pull /sdcard/autojump.png");
}

Point get_Character_Loc(Mat& srcImage,Mat& Tem_img)
{
 matchTemplate(srcImage,Tem_img,dstImage,CV_TM_SQDIFF);
 double minVal,maxVal;
 Point minLoc,maxLoc,matchLoc;
 minMaxLoc(dstImage,&minVal,&maxVal,&minLoc,&maxLoc,Mat());
 matchLoc = minLoc; //matchLoc是最佳匹配的區(qū)域左上角點
 cout<<"maxVal:"<<maxVal<<endl;
 rectangle(srcImage,Rect(matchLoc,Size(Character.cols,Character.rows)),Scalar(255,255,0),1,8,0);
 //Canny(srcImage,srcImage,1,10);
 putText(srcImage,"Wang",Point(matchLoc.x+Character.cols*0.5,matchLoc.y+Character.rows),1,2,Scalar(0,0,255));//畫出Character小人的坐標
 return Point(matchLoc.x+Character.cols*0.5,matchLoc.y+Character.rows);
}

Point get_next_img_Loc(Mat& srcImage,Point& Character_Loc)
{
 cout<<"get_next_img_Loc"<<endl;
 cvtColor(srcImage,srcImage,CV_BGR2GRAY);
 GaussianBlur(srcImage,srcImage,Size(3,3),0);
 Canny(srcImage,srcImage,3,8);
 char AA[30];
 sprintf(AA,"get_next_img_Loc_%d.png",i);
 cout<<AA<<endl;
 imwrite(AA,srcImage);
 i++;
 //imshow("get",srcImage);
 cout<<"Character_Loc.x:"<<Character_Loc.x<<endl;
 if(Character_Loc.x < 540)
 {
  for(int j = int(srcImage.rows*0.2);j<int(srcImage.rows*0.8);j++)
  {
   uchar* data = srcImage.ptr<uchar>(j);
   for(int i = 1079;i > 540 ;i--)
   {    
    if(data[i] == 255)
    {
     return Point(i,j);
     //cout<<"Point:"<<Point(i,j)<<endl;
    }
   }
  }
 }
 else
 {
  for(int j = int(srcImage.rows*0.2);j<int(srcImage.rows*0.8);j++)
  {
   uchar* data = srcImage.ptr<uchar>(j);
   for(int i = 0;i<540;i++)
   {
    if(data[i] == 255)
     return Point(i,j);
   }
  }
 }
 return Character_Loc;
}

int get_distance(Point& first_point,Point& next_point)
{
 int A = first_point.x - next_point.x;
 int B = first_point.y - (next_point.y+50);
 return int(pow(pow(A,2)+pow(B,2),0.5));
}

void jump(int&g_distance)
{
 char AA[50];
 int distance_ = g_distance * 1.35;
 int rand_x = int(320+rand()%50); //加上隨機數(shù)使得每次按壓都是在點(320,410)-(370,460)之間
 int rand_y = int(410+rand()%50);
 sprintf(AA,"adb shell input swipe %d %d %d %d %d",rand_x,rand_y,rand_x,rand_y,distance_);
 cout<<AA<<endl;
 system(AA);
}

通過測試效果如下:輕松得榜首,到五百多時程序依然可以一直在運行,我覺得時間太長,所以就直接弄掛了。不過并不影響榜首的位置!上圖:

總結(jié):主要本人剛好也是視覺圖像方向的,哈哈,就閑的無聊測試了一把,經(jīng)過更改和測試。如果不遇到那種與背景色特別相近的,上榜首是沒問題的! 嗯,說了這么多,這個博客也就到此結(jié)束啦,有問題歡迎留言!

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C++模擬實現(xiàn)vector流程詳解

    C++模擬實現(xiàn)vector流程詳解

    這篇文章主要介紹了C++容器Vector的模擬實現(xiàn),Vector是一個能夠存放任意類型的動態(tài)數(shù)組,有點類似數(shù)組,是一個連續(xù)地址空間,下文更多詳細內(nèi)容的介紹,需要的小伙伴可以參考一下
    2022-08-08
  • C++如何使用new來初始化指向類的指針

    C++如何使用new來初始化指向類的指針

    這篇文章主要介紹了C++如何使用new來初始化指向類的指針問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 利用C語言編輯畫圖程序的實現(xiàn)方法(推薦)

    利用C語言編輯畫圖程序的實現(xiàn)方法(推薦)

    下面小編就為大家?guī)硪黄肅語言編輯畫圖程序的實現(xiàn)方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • 詳解C++中的萬能頭文件

    詳解C++中的萬能頭文件

    C++萬能頭文件它是一個包含了每一個標準庫的頭文件,接下來通過本文給大家介紹C++中的萬能頭文件及優(yōu)缺點,需要的朋友可以參考下
    2023-02-02
  • C++中volatile和mutable關(guān)鍵字用法詳解

    C++中volatile和mutable關(guān)鍵字用法詳解

    這篇文章主要介紹了C++中volatile和mutable關(guān)鍵字用法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-02-02
  • 關(guān)于C語言動態(tài)內(nèi)存管理介紹

    關(guān)于C語言動態(tài)內(nèi)存管理介紹

    大家好,本篇文章主要講的是關(guān)于C語言動態(tài)內(nèi)存管理介紹,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • C語言判斷一個數(shù)是否是2的冪次方或4的冪次方

    C語言判斷一個數(shù)是否是2的冪次方或4的冪次方

    本文中我們來看一下如何用C語言判斷一個數(shù)是否是2的冪次方或4的冪次方的方法,并且判斷出來是多少次方,需要的朋友可以參考下
    2016-06-06
  • C++多線程編程和同步機制實例演示

    C++多線程編程和同步機制實例演示

    C++中的多線程編程和同步機制使得程序員可以利用計算機的多核心來提高程序的運行效率和性能,本文將介紹多線程編程和同步機制的基本概念和使用方法
    2023-09-09
  • 簡單介紹C++中變量的引用

    簡單介紹C++中變量的引用

    這篇文章主要簡單介紹了C++中變量的引用,是C++入門學習中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • C++你最好不要做的幾點小結(jié)

    C++你最好不要做的幾點小結(jié)

    整理如下,主要是方便剛開始接觸c++的朋友
    2013-01-01

最新評論