2021-01-05 03:37:50 -0600
| received badge | ● Famous Question
(source)
|
2020-04-06 11:01:40 -0600
| received badge | ● Notable Question
(source)
|
2020-01-13 12:08:38 -0600
| received badge | ● Popular Question
(source)
|
2017-08-10 03:06:43 -0600
| commented question | Finding object on screen using multi-scale template matching It is not the whole one. :)
The first three are just the core part of the logic.
Overall, above functions are the smallest part of source code to understand the logic. |
2017-08-10 02:08:10 -0600
| asked a question | Finding object on screen using multi-scale template matching I am new to OpenCV.
I am using the following code to find objects on the screen: //---------------------------------------------------------------------------
static Point FindTemplate(const Mat &Image, const Mat &Template, double &Val)
{
Point ResultLoc(-1, -1);
Val = 0;
if (Image.empty() || Template.empty())
{
return ResultLoc;
}
Mat ResImage;
int Res_cols = Image.cols - Template.cols + 1;
int Res_rows = Image.rows - Template.rows + 1;
ResImage.create(Res_rows, Res_cols, CV_32FC1);
matchTemplate(Image, Template, ResImage, CV_TM_CCOEFF_NORMED);
minMaxLoc(ResImage, nullptr, &Val, nullptr, &ResultLoc, Mat());
return ResultLoc;
}
//---------------------------------------------------------------------------
static bool GetScreenShot(Mat &Img)
{
HWND Wnd = GetDesktopWindow();
HDC WndDC = GetWindowDC(Wnd);
if (WndDC == 0)
{
return false;
}
HBITMAP Bmp = 0;
RECT R;
int Width, Height;
bool Result = false;
HDC CompatibleDC = CreateCompatibleDC(WndDC);
if (CompatibleDC == 0 || GetWindowRect(Wnd, &R) == 0)
{
goto Return;
}
Width = R.right - R.left;
Height = R.bottom - R.top;
if ((Bmp = CreateCompatibleBitmap(WndDC, Width, Height)) == 0 ||
SelectObject(CompatibleDC, Bmp) == 0 ||
BitBlt(CompatibleDC, 0, 0, Width, Height, WndDC, 0, 0, SRCCOPY) == 0)
{
goto Return;
}
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 = 0;
BI.biYPelsPerMeter = 0;
BI.biClrUsed = 0;
BI.biClrImportant = 0;
Img.create(Height, Width, CV_8UC4);
GetDIBits(CompatibleDC, Bmp, 0, Height, Img.data, (BITMAPINFO*)&BI, DIB_RGB_COLORS);
Result = !Img.empty();
Return:
if (Bmp != 0)
{
DeleteObject(Bmp);
}
if (CompatibleDC != 0)
{
DeleteDC(CompatibleDC);
}
ReleaseDC(Wnd, WndDC);
return Result;
}
//---------------------------------------------------------------------------
static Point UpDownSample(const Mat &Image, const Mat &Templ, const bool Up, Point *p2 = nullptr)
{
std::vector<double> Vals;
double pc = 1.00, AvrVal = 0, MaxVal = 0, scx = 1, scy = 1;
const double d = 0.05;
Point MaxP(-1, -1);
while (Up ? pc <= 1.5 : pc >= 0.5)
{
Mat Tmpimg(Image);
double Val = 0;
resize(Image, Tmpimg, Size(), pc, pc);
Point P = FindTemplate(Tmpimg, Templ, Val);
Vals.push_back(Val);
AvrVal += Val;
if (Val > MaxVal)
{
MaxVal = Val;
MaxP = P;
scx = Tmpimg.cols * 1.0 / Image.cols * 1.0;
scy = Tmpimg.rows * 1.0 / Image.rows * 1.0;
if (p2 != nullptr)
{
p2->x = (double)(Templ.cols / scx);
p2->y = (double)(Templ.rows / scy);
}
}
pc = Up ? pc + d : pc - d;
}
AvrVal = AvrVal / Vals.size();
pc = abs(MaxVal - AvrVal) / AvrVal;
if (pc < 0.25)
{
MaxP.x = MaxP.y = -1;
}
else
{
MaxP.x = (double)(MaxP.x / scx) + 1;
MaxP.y = (double)(MaxP.y / scy) + 1;
}
return MaxP;
}
For example, to find existence of a window on the screen, I am using the following function (it calls above functions). Note, using WinAPI to find the window doesn't work on my environment. bool Find_Welcome_Window(const DWORD Timeout)
{
static Mat AppNameTempl;
if (AppNameTempl.empty())
{
if ((AppNameTempl = imread("AccScreen\\AppName.png")).empty())
{
return false;
}
cvtColor(AppNameTempl, AppNameTempl, CV_RGB2GRAY);
Canny(AppNameTempl, AppNameTempl, 50, 200);
}
bool Result = false;
DWORD T0 = GetTickCount();
while (!Result && (GetTickCount() - T0) < Timeout)
{
Mat Tmpimg;
if (!GetScreenShot(Tmpimg))
{
return false;
}
Tmpimg.convertTo(Tmpimg, CV_8UC3);
cvtColor(Tmpimg, Tmpimg, CV_RGB2GRAY);
Canny(Tmpimg, Tmpimg, 50, 200);
Point P = UpDownSample(Tmpimg, AppNameTempl, false);
Result = P.x > 0 && P.y > 0;
if (!Result)
{
P = UpDownSample(Tmpimg, AppNameTempl, true);
Result = P.x > 0 && P.y > 0;
}
}
return Result;
}
Above logic works for ... (more) |
2017-07-29 02:23:21 -0600
| received badge | ● Enthusiast
|
2017-07-28 07:03:32 -0600
| asked a question | minMaxLoc() always returns values even template doesn't exist in image matchTemplate(Image, Template, ResImage, CV_TM_CCOEFF);
double Min, Max;
Point MinLoc, MaxLoc;
minMaxLoc(ResImage, &Min, &Max, &MinLoc, &MaxLoc, Mat());
minMaxLoc() always returns values even "Template" doesn't exist in "Image".
How do we know if it really exists or not? The documentation says that if CV_TM_CCOEFF is used, the best match is MaxLoc.
But MaxLoc always contains values. |
2017-07-28 07:02:03 -0600
| asked a question | minMaxLoc() always returns values even template doesn't exist in image matchTemplate(Image, Template, ResImage, CV_TM_CCOEFF);
double Min, Max;
Point MinLoc, MaxLoc;
minMaxLoc(ResImage, &Min, &Max, &MinLoc, &MaxLoc, Mat());
minMaxLoc() always returns values even "Template" doesn't exist in "Image".
How do we know if it really exists or not? The documentation says that if CV_TM_CCOEFF is used, the best match is MaxLoc.
But MaxLoc always contains values. |
2017-07-28 06:58:57 -0600
| asked a question | minMaxLoc() returnes values even template doesn't exist in image matchTemplate(Image, Template, ResImage, CV_TM_CCOEFF);
double Min, Max;
Point MinLoc, MaxLoc;
minMaxLoc(ResImage, &Min, &Max, &MinLoc, &MaxLoc, Mat());
minMaxLoc() always returns values even "Template" doesn't exist in "Image".
How do we know if it really exists or not? The documentation says that if CV_TM_CCOEFF is used, the best match is MaxLoc.
But MaxLoc always contains values. |
2017-07-28 02:31:34 -0600
| received badge | ● Scholar
(source)
|
2017-07-27 11:09:16 -0600
| commented answer | How does macthTemplate() deal with scaling? |
2017-07-27 11:05:59 -0600
| received badge | ● Supporter
(source)
|
2017-07-27 07:31:03 -0600
| received badge | ● Student
(source)
|
2017-07-27 05:07:20 -0600
| commented answer | How does macthTemplate() deal with scaling? @LBerger Thank you. I will try that too. |
2017-07-27 05:06:38 -0600
| commented answer | How does macthTemplate() deal with scaling? |
2017-07-27 03:08:46 -0600
| asked a question | How does macthTemplate() deal with scaling? matchTemplate(Image, Template, ResImage, CV_TM_SQDIFF);
If size of "Image" changes, matchTemplate() can't find location of "Template" in the "Image". Should "Template" be exact part of "Image" in order for matchTemplate() to find its location? |
2017-07-09 23:16:40 -0600
| commented question | Window detection/recognition on the screen (without WinAPI) I already know this. But it cannot help me. |
2017-07-09 23:02:35 -0600
| commented question | Window detection/recognition on the screen (without WinAPI) @berak Sure. I can capture a screenshot using WinAPI first, and then can send it to opencv. |
2017-07-09 22:29:24 -0600
| asked a question | Window detection/recognition on the screen (without WinAPI) Hello, I need to detect/recognize windows on the screen. That is, the solution needs to find a particular window or its title on the screen. I know this can be done using WinAPI, but for my environment, WinAPI is not a solution.
Can you please advice? Many thanks! |