获取OpenCV中当前活动窗口的句柄

lmvvr0a8  于 2022-12-27  发布在  其他
关注(0)|答案(4)|浏览(366)

是否有GLUT glutGetWindow()/glutSetWindow()函数的OpenCV等价物,允许从您自己的代码中识别和切换当前活动窗口?
基本上,我希望能够从注册到所有窗口的鼠标回调函数中识别当前活动窗口,并让它为每个窗口调用另一个具有不同参数的处理函数。
任何帮助都将不胜感激。

hmtdttj4

hmtdttj41#

在OpenCV中没有函数可以实现这一点,但是,cvSetMouseCallback()的签名允许您为每个窗口注册一个回调函数。
您必须注册单独的回调函数来完成您需要做的事情。
以下是HIGHGUI模块支持的complete list功能。
另一个(hardcore)替代方案是深入研究你正在使用的操作系统的原生API,并搜索实现这一点的方法。问题是这个解决方案不是跨平台的。

tzxcd3kk

tzxcd3kk2#

实际上,cvGetWindowHandle(const char* windowname)在opencv/highgui/highgui_c. h中是可用的。在编写此答案之前,它一直可用到openCV 4。
我建议你加上

#include <opencv/highgui/highgui_c.h>

并使用

cvGetWindowHandle(window_name_.c_str())
mctunoxg

mctunoxg3#

包含〈opencv / highgui /highgui_c. h〉可能是一个解决方案,但它确实不会让您转向Opencv 4+。
对于那些仍在MFC对话框中使用OpenCV的人,有一种不同的解决方案
FindWindows返回父窗口句柄,MFC处理子窗口,因此您将需要FindWindow和FindWindowEx。
MFC和Opencv 4+的新源代码

namedWindow(windowname, WINDOW_AUTOSIZE);

////// This will work on opencv 4.X //////

HWND hParent = (HWND)FindWindow(NULL, windowname.c_str());
HWND hWnd = (HWND)FindWindowEx(hParent, NULL, L"HighGUI class", NULL);

::SetParent(hWnd, GetDlgItem(IDC_PICTURE)->m_hWnd);
::ShowWindow(hParent, SW_HIDE);

CWnd* pWnd = new CWnd();
pWnd->CWnd::Attach(hParent);

也许您仍然遇到麻烦,因为string到LPCWSTR的转换失败,并且hParent返回NULL。有许多方法可以将string转换为LPCWSTR,但是由于您使用的是MFC,请尝试

namedWindow(windowname, WINDOW_AUTOSIZE);

////// This will work on opencv 4.X //////

CString CstrWindowname = windowname.data();
    
HWND hParent = (HWND)FindWindow(NULL, CstrWindowname);
HWND hWnd = (HWND)FindWindowEx(hParent, NULL, L"HighGUI class", NULL);

::SetParent(hWnd, GetDlgItem(IDC_PICTURE)->m_hWnd);
::ShowWindow(hParent, SW_HIDE);

CWnd* pWnd = new CWnd();
pWnd->CWnd::Attach(hParent);

新代码应替换此旧代码

namedWindow(windowname, WINDOW_AUTOSIZE);

///// OLD version. Used on opencv 3.X on MFC Dialog Box /////

HWND hWnd = (HWND) cvGetWindowHandle(windowname.c_str());    
HWND hParent = ::GetParent(hWnd);

::SetParent(hWnd, GetDlgItem(IDC_PICTURE)->m_hWnd);
::ShowWindow(hParent, SW_HIDE);

CWnd* pWnd = new CWnd();
pWnd->CWnd::Attach(hParent);

试试看,

qltillow

qltillow4#

虽然没有OpenCV API来检索聚焦窗口,但是OS GUI Shell通常提供。使用这种方法会更好,因为鼠标回调不能检测ALT-TAB和编程聚焦。
下面是python for windows的一些示例代码,可以完成这项工作:

import ctypes
import cv2

user32 = ctypes.windll.user32

def exists_cv_window(title):
    # seems to work on python-opencv version 4.6.0
    return cv2.getWindowProperty(title, cv2.WND_PROP_VISIBLE) != 0.0

def get_active_cv_window():
    focused_window_handle = user32.GetForegroundWindow()
    length = user32.GetWindowTextLengthW(focused_window_handle)
    buffer = bytes([0]) * 2 * length
    buff_pointer = ctypes.c_char_p(buffer)
    user32.GetWindowTextW(window_handle, buff_pointer, length)
    active_window_title = buffer.decode('utf-16')
    if exists_cv_window(active_window_title):
        return active_window_title

# example use case for the function
def main():
    im1 = cv2.imread('cookie.png')
    im2 = cv2.imread('cat.png')
    cv2.imshow('figure 1', im1)
    cv2.imshow('figure 2', im2)
    while True:
        key = cv2.waitKey(10)
        if key == 23:   # CTRL + W
            title = get_active_cv_window()
            if title is not None:
                cv2.destroyWindow(title)

# in the example above the ability to target active window allows applying
# CTRL + W shortcut to a specific figure

可惜这不是OpenCV的一部分

相关问题