Ask Your Question

CVLearner17's profile - activity

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?

Thank you very much!

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?

@StevenPuttemans Thank you. Your answer gave me some hope.

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!