【问题标题】:How to display an image in full screen borderless window in openCV如何在openCV的全屏无边框窗口中显示图像
【发布时间】:2011-09-24 14:54:47
【问题描述】:

我想在全屏无边框窗口中显示 OpenCV 中的图像。 换句话说,只会出现图像像素,没有菜单、工具栏或窗口背景。

使用imshow()cvShowImage() 不要启用它:

  1. 窗口增长为全屏 宽度而不是高度。它遗漏了几个像素。
  2. 即使更改窗口设置,我也无法使其无边框 处理程序。

我认为问题的根源在于cvNamedWindow() 方法,该方法创建主WS_OVERLAPPED 窗口,然后创建一个子窗口,并且所有函数(如imshow()cvGetWindowHandle())都对子窗口进行操作。

因此连windows命令:

SetWindowLong((HWND)cvGetWindowHandle(winName), GWL_STYLE, WS_VISIBLE | WS_EX_TOPMOST | WS_POPUP);

没有帮助,因为孩子不能成为无边界WS_POPUP。有人有解决方法吗?

  • 也许,向窗口显示 opencv mat 不使用 opencv 内置方法
  • 或者某种窗口技巧

附:我尝试了以下代码:

cvMoveWindow("AAA",0,0);
cvSetWindowProperty("AAA", CV_WINDOW_FULLSCREEN, CV_WINDOW_FULLSCREEN);

// Also I tried this:
HWND hwnd = (HWND)cvGetWindowHandle("AAA");
RECT windowRect;
windowRect.left = 0;
windowRect.top = 0;
windowRect.right = cxScreen; //Display resolution
windowRect.bottom = cyScreen; //Display resolution
AdjustWindowRect(&windowRect,WS_VISIBLE,false);
long p_OldWindowStyle = SetWindowLongPtr(hwnd,GWL_STYLE,WS_POPUP);
SetWindowPos(hwnd,HWND_TOP,0,0,windowRect.right,windowRect.bottom,SWP_FRAMECHANGED | SWP_SHOWWINDOW);
SetWindowLong(hwnd, GWL_STYLE, WS_VISIBLE | WS_EX_TOPMOST | WS_POPUP); 

【问题讨论】:

    标签: c image winapi opencv


    【解决方案1】:

    您是否已发出cvShowImage() 来显示窗口?因为看起来你没有这样做。无论如何,您可能想为此调用 win32 API,因此在SetWindowPos() 之后添加对ShowWindow(hwnd, SW_SHOW); 的调用。

    如果您当前对 SetWindowPos() 的调用不起作用,请查看以下答案:Hide border of window, if i know a handle of this window

    我建议您先不要调用cvSetWindowProperty() 进行测试,以确保您能找到有效的方法。

    请注意,如果您查看modules/highgui/src/window_w32.cpp,您可以看到 OpenCV 如何在 Windows 上创建窗口。

    编辑

    以下代码实现了我之前给出的提示,并绕过了 OP 报告的问题。诀窍是不使用cvGetWindowHandle() 来检索窗口的句柄并直接使用 win32 API:FindWindow()

    IplImage* cv_img = cvLoadImage("test.jpg", CV_LOAD_IMAGE_UNCHANGED);
    if(!cv_img)
    {
        printf("Failed cvLoadImage\n");
        return -1;
    }
    
    cvNamedWindow("main_win", CV_WINDOW_AUTOSIZE);
    cvMoveWindow("main_win", 0, 0);
    cvSetWindowProperty("main_win", CV_WINDOW_FULLSCREEN, CV_WINDOW_FULLSCREEN);
    
    cvShowImage("main_win", cv_img);
    
    //HWND cv_hwnd = (HWND)cvGetWindowHandle("main_win");
    //if (!cv_hwnd)
    //{
    //  printf("Failed cvGetWindowHandle\n");
    //}
    //printf("cvGetWindowHandle returned %p\n", *cv_hwnd);
    
    HWND win_handle = FindWindow(0, L"main_win");
    if (!win_handle)
    {
        printf("Failed FindWindow\n");
    }
    
    SetWindowLong(win_handle, GWL_STYLE, GetWindowLong(win_handle, GWL_EXSTYLE) | WS_EX_TOPMOST);
    ShowWindow(win_handle, SW_SHOW);
    
    cvWaitKey(0);
    
    cvReleaseImage(&cv_img);
    cvDestroyWindow("main_win");
    

    此代码将使 OpenCV 创建的窗口无边界,但您仍可能需要调整一件事或另一件事以使此操作完美。你会明白为什么。一种想法是调整窗口大小并使其与图像大小一致。

    编辑

    好吧,既然你说:

    编写演示可能非常困难

    我也决定为你做最后一部分,因为我是个好人=]

    这是对上面代码的一个小改进:

    HWND win_handle = FindWindow(0, L"main_win");
    if (!win_handle)
    {
        printf("Failed FindWindow\n");
    }
    
    // Resize
    unsigned int flags = (SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER);
    flags &= ~SWP_NOSIZE;
    unsigned int x = 0;
    unsigned int y = 0;
    unsigned int w = cv_img->width;
    unsigned int h = cv_img->height;
    SetWindowPos(win_handle, HWND_NOTOPMOST, x, y, w, h, flags);
    
    // Borderless
    SetWindowLong(win_handle, GWL_STYLE, GetWindowLong(win_handle, GWL_EXSTYLE) | WS_EX_TOPMOST);
    ShowWindow(win_handle, SW_SHOW);
    

    在我的系统上,它会准确地显示您提出的问题。

    【讨论】:

    • 我会尝试为您编写一个演示,并在 10 小时内发布到这里。
    • 现在,无论谁对我的回答投了反对票,请解释原因。这些是非常有效的考虑因素,OP 可能会遗漏一些明显的东西。
    • 你有没有看到我是如何重新提出我的问题的。我找到了问题的根源。所以写一个演示可能会很困难......
    • 哇!谢谢。你真的为我实现并优化了它。我认为你刚刚投入的爱和帮助比我从朋友那里得到的更多:-)。
    • 金块“不要使用 cvGetWindowHandle 并改用 WinAPI 的 FindWindow”刚刚解决了我遇到的一个类似问题,即我无法使用 WS_EX_TOPMOST 让我的 OpenCV 窗口始终保持在顶部。谢谢!
    猜你喜欢
    • 2012-03-15
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 2011-07-31
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多