我正在运行一个无限循环,每一帧我都从所需的窗口截取屏幕截图并将其转换为 Mat,然后使用 matchTemplate 在该 Mat 中搜索模板图像。如果我读入模板图像和整个图像,我可以使用 TM_SQDIFF 方法成功使用该函数。但是,当我运行下面的代码时,即使模板不存在,也会始终绘制一个矩形,并且如果模板存在,则永远不会超过模板。有任何想法吗?
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include "opencv2/imgproc.hpp"
#include <Windows.h>
#include <iostream>
using namespace std;
using namespace cv;
Mat getMat(HWND hWND);
int main()
{
//Window capture
LPCWSTR windowTitle = L"imgName - Paint";
HWND hWND = FindWindow(NULL, windowTitle);
while (!hWND)
{
system("cls");
cout << "Start game" << endl;
hWND = FindWindow(NULL, windowTitle);
Sleep(100);
}
enum TemplateMatchModes
{
TM_SQDIFF = 0,
TM_SQDIFF_NORMED = 1,
TM_CCORR = 2,
TM_CCORR_NORMED = 3,
TM_CCOEFF = 4,
TM_CCOEFF_NORMED = 5
};
TemplateMatchModes option = TM_SQDIFF;
Mat templateImage = imread("images/templateImg.jpg", IMREAD_COLOR);
Mat otherThing;
templateImage.convertTo(otherThing, CV_8UC4);
namedWindow("Result", WINDOW_NORMAL);
while (true)
{
double minVal;
double maxVal;
Point minLoc;
Point maxLoc;
Point matchLoc;
Mat theImage = getMat(hWND);
Mat result;
Mat background;
theImage.copyTo(background);
cvtColor(theImage, theImage, COLOR_BGR2HSV);
matchTemplate(theImage, otherThing, result, option);
normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());
minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());
if (option == TM_SQDIFF || option == TM_SQDIFF_NORMED)
{
matchLoc = minLoc;
}
else
{
matchLoc = maxLoc;
}
rectangle(background, matchLoc, Point(matchLoc.x + otherThing.cols, matchLoc.y + otherThing.rows), Scalar(0, 255, 0), 2, 8, 0);
imshow("Result", background);
waitKey(30);
}
}
Mat getMat(HWND hWND)
{
HDC deviceContext = GetDC(hWND);
HDC memoryDeviceContext = CreateCompatibleDC(deviceContext);
RECT windowRect;
GetClientRect(hWND, &windowRect);
int height = windowRect.bottom;
int width = windowRect.right;
HBITMAP bitmap = CreateCompatibleBitmap(deviceContext, width, height);
SelectObject(memoryDeviceContext, bitmap);
BitBlt(memoryDeviceContext, 0, 0, width, height, deviceContext, 0, 0, SRCCOPY);
BITMAPINFOHEADER bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = width;
bi.biHeight = -height;
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 1;
bi.biYPelsPerMeter = 1;
bi.biClrUsed = 1;
bi.biClrImportant = 1;
Mat mat = Mat(height, width, CV_8UC4);
GetDIBits(memoryDeviceContext, bitmap, 0, height, mat.data, (BITMAPINFO*)&bi, DIB_RGB_COLORS);
DeleteObject(bitmap);
DeleteDC(memoryDeviceContext);
ReleaseDC(hWND, deviceContext);
return mat;
}