#define _CRT_SECURE_NO_WARNINGS
#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
#include <windows.h>
#include <list>
using namespace cv;
using namespace std;
//截取跳一跳屏幕
void ScreenShot(void);
//获取Character坐标
Point GetNowPoint(Mat& srcImage, Mat& Tem_img);
//获取下一个要跳的点
Point GetNextPoint(Mat& srcImage);
//计算距离
int GetDistance(Point& first_point, Point& next_point);
//跳跃
void Jump(int&g_distance);
int main(int argc, char** argv)
{
ScreenShot(); //截取图片
Sleep(1000);
Mat dstImage;
Mat Character;
// system("color 3F");
while (true)
{
// get_screenshot();
Mat srcImage = imread("helloworld.jpg", IMREAD_GRAYSCALE); //读取图片
dstImage = srcImage.clone();
Character = imread("template.jpg", IMREAD_GRAYSCALE); //读取样本
//imshow("Character",Character);
//cvtColor(srcImage,srcImage,CV_BGR2GRAY);
Point nowPoint = GetNowPoint(srcImage, Character);
cout << "nowPoint:" << nowPoint << endl;
Point nextPoint = GetNextPoint(srcImage);
cout << "nextPoint:" << nextPoint << endl;
int nDistance = GetDistance(nowPoint, nextPoint);
Jump(nDistance);
Sleep(1000);
ScreenShot();
Sleep(1000);
}
return 0;
}
Point GetNowPoint(Mat& srcImage, Mat& Tem_img)
{
cv::Mat image_matched;
matchTemplate(srcImage, Tem_img, image_matched, CV_TM_SQDIFF);// 匹配黑棋子
double minVal, maxVal;
Point minLoc, maxLoc, matchLoc;
minMaxLoc(image_matched, &minVal, &maxVal, &minLoc, &maxLoc, Mat());
matchLoc = minLoc; //matchLoc是最佳匹配的区域左上角点
return Point(matchLoc.x + Tem_img.cols*0.5, matchLoc.y + Tem_img.rows);
}
Point GetNextPoint(Mat& srcImage)
{
cv::Point point1;
cv::Point point2;
cv::GaussianBlur(srcImage, srcImage, cv::Size(5, 5), 0); //高斯滤波,降低噪声
// cv::threshold(srcImage, srcImage, 0, 255, 8);
Canny(srcImage, srcImage, 20, 30); //进行边缘检测
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(srcImage, contours, hierarchy, CV_RETR_TREE, CV_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点的最大值
}
}
return cv::Point(point1.x, point2.y); //返回中点坐标
}
int GetDistance(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)
{
cout << "distance:" << g_distance << endl;
int time = g_distance*4+330;
RECT rect;
HWND hwnd = ::FindWindow(NULL, L"实时演示");
GetWindowRect(hwnd, &rect);
::SetCursorPos(rect.left+100, rect.bottom-500);
INPUT Input = { 0 }; //鼠标按下
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(1, &Input, sizeof(INPUT));
Sleep(time);//鼠标下的时间
Input = { 0 }; //鼠标松开
Input.type = INPUT_MOUSE;
Input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1, &Input, sizeof(INPUT));
}
void ScreenShot(void)
{
RECT rect;
HWND hwnd = ::FindWindow(NULL, L"实时演示"); //获取360演示的句柄
GetWindowRect(hwnd, &rect); //获取图像的位置
char sScreenShot[64];
sprintf(sScreenShot, "grab.exe %d %d %d %d", rect.left, rect.top+135, rect.right, rect.bottom-50);//组成字符串
system(sScreenShot); //调用python截取图片
}