I am running an infinite loop and every frame I'm taking a screenshot from a desired window and turning it into a Mat then searching that Mat for a template image using matchTemplate. If I read in the template image and the entire image, I can use the function successfully using the TM_SQDIFF method. However, when I run the below code, a rectangle is always drawn even if the template isn't there and is never over the template if the template is present. Any ideas?
#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;
}
There is no condition given for rectangle to not to be drawn. If you want it to be drawn only if the template found you should create a condition for that.
You may check some detection examples as well.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.