模板匹配屏幕截图在断言时失败
Template Matching a screenshot fails on assertion
我正在尝试使用 OpenCV 进行屏幕截图的模板匹配。每当我调用 cv::matchTemplate()
函数时,我都会遇到错误。
我得到的错误:
OpenCv Error: Assertion failed ((depth == CV_8U || depth == CV_32F) && type == _templ.type() && _img.dims() <= 2) in cv::matchTemplate, file C:\builds\master_PackSlave-win64-vc12-shared\opencv\modules\imgproc\src\templmatch.cpp
我试过的:
但解决方案没有帮助,因为这就是我已经在做的事情。我已经仔细检查了调试器中的所有内容。没有什么是 NULL,所有东西都有多个行和列以及 2 个维度。
主要
HWND handle = GetForegroundWindow();
cv::Mat mat;
if (handle != 0){
mat = windowToMat(handle);
}
myTemplateMatch(mat, playerTemplate);
模板匹配---
#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <ctime>
#include <Windows.h>
#include <iostream>
#include <string>
XYposition myTemplateMatch(cv::Mat &img, cv::Mat &mytemplate)
{
cv::Mat result(img.rows - mytemplate.rows + 1, img.cols - mytemplate.cols + 1, CV_32F);
//***************BREAKS RIGHT HERE****************************
cv::matchTemplate(img, mytemplate, result, CV_TM_SQDIFF_NORMED);
cv::normalize(result, result, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
double minVal; double maxVal;
cv::Point minLoc;
cv::Point maxLoc;
cv::Point matchLoc;
cv::minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, cv::Mat());
XYposition playerData = {
maxLoc.x + mytemplate.cols, maxLoc.y + mytemplate.rows
};
rectangle(result, matchLoc, cv::Point(matchLoc.x + mytemplate.cols, matchLoc.y + mytemplate.rows),
cv::Scalar(0, 0, 255), 4, 8, 0);
cv::namedWindow("cvImage", CV_WINDOW_AUTOSIZE);
cv::imshow("cvImage", result);
cv::waitKey(0);
return playerData;
}
创建屏幕截图
cv::Mat windowToMat(HWND hwnd){
HDC hwindowDC, hwindowCompatibleDC;
int height, width, srcheight, srcwidth;
HBITMAP hbwindow;
cv::Mat src;
BITMAPINFOHEADER bi;
hwindowDC = GetDC(hwnd);
hwindowCompatibleDC = CreateCompatibleDC(hwindowDC);
SetStretchBltMode(hwindowCompatibleDC, COLORONCOLOR);
RECT windowsize; // get the height and width of the screen
GetClientRect(hwnd, &windowsize);
srcheight = windowsize.bottom;
srcwidth = windowsize.right;
height = windowsize.bottom / 2; //change this to whatever size you want to resize to
width = windowsize.right / 2;
src.create(height, width, CV_32F);
// create a bitmap
hbwindow = CreateCompatibleBitmap(hwindowDC, width, height);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = width;
bi.biHeight = -height; //this is the line that makes it draw upside down or not
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
// use the previously created device context with the bitmap
SelectObject(hwindowCompatibleDC, hbwindow);
// copy from the window device context to the bitmap device context
StretchBlt(hwindowCompatibleDC, 0, 0, width, height, hwindowDC, 0, 0, srcwidth, srcheight, SRCCOPY); //change SRCCOPY to NOTSRCCOPY for wacky colors !
GetDIBits(hwindowCompatibleDC, hbwindow, 0, height, src.data, (BITMAPINFO *)&bi, DIB_RGB_COLORS); //copy from hwindowCompatibleDC to hbwindow
// avoid memory leak
DeleteObject(hbwindow); DeleteDC(hwindowCompatibleDC); ReleaseDC(hwnd, hwindowDC);
return src;
}
问题是所使用的 Mat
图像类型不同。如果您使用 Mat 的 .type()
函数,您可以检查传递给该函数的参数。将该值与 table
交叉引用
A Mapping of Type to Numbers in OpenCV
C1 C2 C3 C4
CV_8U 0 8 16 24
CV_8S 1 9 17 25
CV_16U 2 10 18 26
CV_16S 3 11 19 27
CV_32S 4 12 20 28
CV_32F 5 13 21 29
CV_64F 6 14 22 30
并且您可以更改屏幕截图的类型
src.create(height, width, CV_32F);
在 屏幕截图创建
无论值是多少。
我正在尝试使用 OpenCV 进行屏幕截图的模板匹配。每当我调用 cv::matchTemplate()
函数时,我都会遇到错误。
我得到的错误:
OpenCv Error: Assertion failed ((depth == CV_8U || depth == CV_32F) && type == _templ.type() && _img.dims() <= 2) in cv::matchTemplate, file C:\builds\master_PackSlave-win64-vc12-shared\opencv\modules\imgproc\src\templmatch.cpp
我试过的:
主要
HWND handle = GetForegroundWindow();
cv::Mat mat;
if (handle != 0){
mat = windowToMat(handle);
}
myTemplateMatch(mat, playerTemplate);
模板匹配---
#include "stdafx.h"
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <ctime>
#include <Windows.h>
#include <iostream>
#include <string>
XYposition myTemplateMatch(cv::Mat &img, cv::Mat &mytemplate)
{
cv::Mat result(img.rows - mytemplate.rows + 1, img.cols - mytemplate.cols + 1, CV_32F);
//***************BREAKS RIGHT HERE****************************
cv::matchTemplate(img, mytemplate, result, CV_TM_SQDIFF_NORMED);
cv::normalize(result, result, 0, 1, cv::NORM_MINMAX, -1, cv::Mat());
double minVal; double maxVal;
cv::Point minLoc;
cv::Point maxLoc;
cv::Point matchLoc;
cv::minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, cv::Mat());
XYposition playerData = {
maxLoc.x + mytemplate.cols, maxLoc.y + mytemplate.rows
};
rectangle(result, matchLoc, cv::Point(matchLoc.x + mytemplate.cols, matchLoc.y + mytemplate.rows),
cv::Scalar(0, 0, 255), 4, 8, 0);
cv::namedWindow("cvImage", CV_WINDOW_AUTOSIZE);
cv::imshow("cvImage", result);
cv::waitKey(0);
return playerData;
}
创建屏幕截图
cv::Mat windowToMat(HWND hwnd){
HDC hwindowDC, hwindowCompatibleDC;
int height, width, srcheight, srcwidth;
HBITMAP hbwindow;
cv::Mat src;
BITMAPINFOHEADER bi;
hwindowDC = GetDC(hwnd);
hwindowCompatibleDC = CreateCompatibleDC(hwindowDC);
SetStretchBltMode(hwindowCompatibleDC, COLORONCOLOR);
RECT windowsize; // get the height and width of the screen
GetClientRect(hwnd, &windowsize);
srcheight = windowsize.bottom;
srcwidth = windowsize.right;
height = windowsize.bottom / 2; //change this to whatever size you want to resize to
width = windowsize.right / 2;
src.create(height, width, CV_32F);
// create a bitmap
hbwindow = CreateCompatibleBitmap(hwindowDC, width, height);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = width;
bi.biHeight = -height; //this is the line that makes it draw upside down or not
bi.biPlanes = 1;
bi.biBitCount = 32;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
// use the previously created device context with the bitmap
SelectObject(hwindowCompatibleDC, hbwindow);
// copy from the window device context to the bitmap device context
StretchBlt(hwindowCompatibleDC, 0, 0, width, height, hwindowDC, 0, 0, srcwidth, srcheight, SRCCOPY); //change SRCCOPY to NOTSRCCOPY for wacky colors !
GetDIBits(hwindowCompatibleDC, hbwindow, 0, height, src.data, (BITMAPINFO *)&bi, DIB_RGB_COLORS); //copy from hwindowCompatibleDC to hbwindow
// avoid memory leak
DeleteObject(hbwindow); DeleteDC(hwindowCompatibleDC); ReleaseDC(hwnd, hwindowDC);
return src;
}
问题是所使用的 Mat
图像类型不同。如果您使用 Mat 的 .type()
函数,您可以检查传递给该函数的参数。将该值与 table
A Mapping of Type to Numbers in OpenCV
C1 C2 C3 C4
CV_8U 0 8 16 24
CV_8S 1 9 17 25
CV_16U 2 10 18 26
CV_16S 3 11 19 27
CV_32S 4 12 20 28
CV_32F 5 13 21 29
CV_64F 6 14 22 30
并且您可以更改屏幕截图的类型
src.create(height, width, CV_32F);
在 屏幕截图创建
无论值是多少。