自动识别图像目标并判断

希望能帮忙编写一个程序
最好是C或者C++
大致需求如下:
在运行开始前由用户输入所需要的对应名称(如:ABCD)
在图像左上角自动点击随机因子,
当侦测到下方出现已匹配到挑战:ABCD时结束随机(不用自动点击确认开始)
(附加:需要在第一次匹配完成后可以手动重新开启随机)
如图,就是自动点击右上方的开始随机,并在下方绿字部分出现已匹配到挑战:ABCD时结束随机
在程序执行前应有用户所需要的ABCD对应的名称(均为四字)

img

该回答引用ChatGPT
这个问题需要使用图像处理和模式识别技术来实现。以下是一个基本的思路:
1. 使用OpenCV库读取屏幕截图,并将其转换为灰度图像。
2. 使用模板匹配算法在灰度图像中搜索目标图像(即用户输入的名称)。
3. 如果找到了目标图像,则停止随机因子的点击。
4. 如果没有找到目标图像,则继续点击随机因子,并重复步骤1-3。
以下是一个简单的C++代码示例,用于实现上述思路:
c++
#include
#include
using namespace cv;
using namespace std;
int main()
{
// 读取目标图像
Mat target = imread("target.png", IMREAD_GRAYSCALE);
// 获取屏幕分辨率
int screen_width = GetSystemMetrics(SM_CXSCREEN);
int screen_height = GetSystemMetrics(SM_CYSCREEN);
// 创建窗口
namedWindow("Screen", WINDOW_NORMAL);
resizeWindow("Screen", screen_width, screen_height);
// 循环处理屏幕截图
while (true)
{
// 截取屏幕图像
Mat screen;
HDC hdcScreen = GetDC(NULL);
HDC hdc = CreateCompatibleDC(hdcScreen);
HBITMAP hBitmap = CreateCompatibleBitmap(hdcScreen, screen_width, screen_height);
HGDIOBJ hOld = SelectObject(hdc, hBitmap);
BitBlt(hdc, 0, 0, screen_width, screen_height, hdcScreen, 0, 0, SRCCOPY);
screen = Mat(screen_height, screen_width, CV_8UC4);
GetBitmapBits(hBitmap, screen_height * screen_width * 4, screen.data);
SelectObject(hdc, hOld);
DeleteDC(hdc);
ReleaseDC(NULL, hdcScreen);
cvtColor(screen, screen, COLOR_BGRA2GRAY);
// 模板匹配
Mat result;
matchTemplate(screen, target, result, TM_CCOEFF_NORMED);
double minVal, maxVal;
Point minLoc, maxLoc;
minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);
// 判断是否找到目标图像
if (maxVal > 0.9)
{
// 停止随机因子的点击
break;
}
else
{
// 点击随机因子
// ...
}
// 显示屏幕截图
imshow("Screen", screen);
waitKey(1);
}
// 释放窗口
destroyWindow("Screen");
return 0;
}

需要注意的是,这个代码示例只是一个基本的框架,实际应用中还需要根据具体情况进行调整和优化。例如,需要根据实际情况调整模板匹配算法的参数,以提高匹配的准确性和速度。同时,还需要考虑如何处理屏幕分辨率不同的情况,以及如何处理多个目标图像的情况等。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
这个问题需要针对具体的图像识别目标和程序实现细节的不同情况进行编写,以下是一个示例代码。

示例代码使用C++编写,需要安装OpenCV库作为图像处理库。代码中通过OpenCV读取计算机屏幕的截屏,然后在截屏中查找指定的图像目标,并在找到目标后自动点击鼠标。

#include <iostream>
#include <string>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <Windows.h>

using namespace std;
using namespace cv;

Mat screenCapture() {
    HWND hwndDesktop = GetDesktopWindow();
    HDC hdcDesktop = GetDC(hwndDesktop);
    int x = GetSystemMetrics(SM_XVIRTUALSCREEN);
    int y = GetSystemMetrics(SM_YVIRTUALSCREEN);
    int width = GetSystemMetrics(SM_CXVIRTUALSCREEN);
    int height = GetSystemMetrics(SM_CYVIRTUALSCREEN);
    HDC hdcCapture = CreateCompatibleDC(hdcDesktop);
    HBITMAP hbmScreen =
        CreateCompatibleBitmap(hdcDesktop, width, height);
    HGDIOBJ hOld = SelectObject(hdcCapture, hbmScreen);
    BitBlt(hdcCapture, 0, 0, width, height, hdcDesktop, x, y, SRCCOPY);
    SelectObject(hdcCapture, hOld);
    DeleteDC(hdcCapture);
    ReleaseDC(hwndDesktop, hdcDesktop);

    Mat screen = Mat(height, width, CV_8UC4);
    GetBitmapBits((HBITMAP)hbmScreen, width * height * 4, screen.data);
    DeleteObject(hbmScreen);

    Mat screen_rgb;
    cvtColor(screen, screen_rgb, CV_BGRA2RGB);

    return screen_rgb;
}

Mat getTargetMat(string targetImagePath) {
    Mat target = imread(targetImagePath, IMREAD_COLOR);

    cvtColor(target, target, COLOR_BGR2GRAY);
    threshold(target, target, 127, 255, THRESH_BINARY);

    return target;
}

bool findTarget(Mat screen, Mat target) {
    Mat result;
    matchTemplate(screen, target, result, TM_CCORR_NORMED);

    double maxValue;
    Point maxLoc;
    minMaxLoc(result, NULL, &maxValue, NULL, &maxLoc);

    if (maxValue > 0.9) {
        int x = maxLoc.x + target.cols / 2;
        int y = maxLoc.y + target.rows / 2;
        SetCursorPos(x, y);
        mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, 0);
        mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, 0);
        return true;
    }

    return false;
}

int main() {
    string targetName = "ABCD";
    string targetImagePath = "target.png";

    namedWindow("screen", WINDOW_NORMAL);

    while (true) {
        Mat screen = screenCapture();
        imshow("screen", screen);
        waitKey(1);

        if (findTarget(screen, getTargetMat(targetImagePath))) {
            cout << "Matched target: " << targetName << endl;
            break;
        }
    }

    return 0;
}

在运行程序前,需要先准备一个包含目标图像的PNG文件,并将文件名指定在代码中的 targetImagePath 变量中。在代码中,我们假设这个目标图像是一个黑底白字的四字字符串,通过这个图像来匹配用户输入的四字字符串。

程序会不断地在屏幕上进行截屏,并在截屏中查找目标图像。当程序找到目标图像后,就会自动点击鼠标在屏幕上的对应位置,结束程序的运行。用户输入的四字字符串通过代码中的 targetName 变量进行指定。

这个示例代码仅仅是一个简单的脚手架,可以根据具体的需求进行修改和优化。例如,如果需要支持手动重启随机,可以在程序中添加用户重新输入指定字符串的逻辑,并在找到目标图像后清空指定的字符串变量,以便用户可以重新开始随机。
如果我的回答解决了您的问题,请采纳!

以下是一个简单的C++程序,可以实现您所需的功能。请注意,该程序仅供参考,您需要根据实际情况进行修改和调整,确保程序能够正确运行。

#include <iostream>
#include <Windows.h>

using namespace std;

int main()
{
    // 获取窗口句柄
    HWND hwnd = FindWindowA(NULL, "窗口标题");

    // 获取随机因子的位置
    int x = 100;
    int y = 200;

    // 获取挑战名称
    string name;
    cout << "请输入挑战名称:";
    cin >> name;

    while (true)
    {
        // 在随机因子位置左键点击
        SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(x, y));
        SendMessage(hwnd, WM_LBUTTONUP, MK_LBUTTON, MAKELPARAM(x, y));

        // 等待一段时间
        Sleep(500);

        // 检测是否匹配到挑战名称
        HDC hdc = GetDC(NULL);
        COLORREF color = GetPixel(hdc, x + 100, y + 50);
        ReleaseDC(NULL, hdc);

        if (color == RGB(0, 255, 0))
        {
            cout << "已匹配到挑战:" << name << endl;
            break;
        }

        // 等待一段时间后,再次执行点击操作
        Sleep(500);
    }

    return 0;
}

在上面的代码中:

  • hwnd 变量用于存储目标窗口的句柄,需要根据实际情况进行修改;
  • xy 变量用于存储随机因子的位置,需要根据实际情况进行修改;
  • name 变量用于存储挑战名称,需要用户输入;
  • 在循环中,先模拟左键点击操作,再等待一段时间后检测是否匹配到挑战名称,如果已经匹配到,则退出循环。

请注意,上述程序仅是一个基础框架,您还需要考虑异常处理、错误提示、用户交互等方面的问题。同时,为了确保程序能够正确运行,请务必对代码进行测试和调试。

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^