19. CVUI 2.7.0 鼠标和 OpenCV 窗口:Multiple OpenCV windows 【有问题 未解决】(官方文档翻译)

官网文档链接:https://dovyski.github.io/cvui/advanced-multiple-windows/


多 OpenCV 窗口 (Multiple OpenCV windows)

如果项目使用了多个 OpenCV 窗口,例如,显示中间结果,而且那些窗口有 cvui 组件,用户需要执行一些额外的步骤来确保 UI 组件正常工作。以下部分展示了如何在多个窗口中使用 cvui 组件。


1. 创建窗口 (Create the windows)

cvui 使用 OpenCV 中的 cv::setMouseCallback() 来监视每个窗口上的交互,因此在调用 cvui::init() 之前,应用程序使用的窗口必须存在。这样,cvui 就可以对它们中的每一个设置回调。

最简单的方法是让 cvui 在 cvui::init() 中创建窗口。下面是一个使用窗口名数组调用 cvui::init() 的示例,这样 cvui 将自动创建窗口:

#define WINDOW1_NAME "Window 1"
#define WINDOW2_NAME "Windows 2"
#define WINDOW3_NAME "Windows 3"
#define WINDOW4_NAME "Windows 4"

#include <opencv2/opencv.hpp>

#define CVUI_IMPLEMENTATION
#include "cvui.h"

int main() {
  // Tell cvui to init and create 4 windows.
  const cv::String windows[] = { WINDOW1_NAME, WINDOW2_NAME, WINDOW3_NAME, WINDOW4_NAME };  
  cvui::init(windows, 4);

  while(true) {
    // your logic here
  }
}

1.1 创建自己的窗口 ( (Optional) Create your own windows)

如果要创建自己的窗口,请确保在调用 cvui::init() 之前使用 cv::namedWindow() 来创建它们。

当使用 cvui::init() 初始化 cvui 时,仍然需要指定窗口的名称(这将是默认的窗口),然后为 cvui 要监视的每个后续窗口调用 cvui::watch()

#define CVUI_IMPLEMENTATION
#define CVUI_DISABLE_COMPILATION_NOTICES
#include "cvui.h"

#include <iostream>

#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#define WINDOW1_NAME "Windows 1"
#define WINDOW2_NAME "Windows 2"
#define WINDOW3_NAME "Windows 3"
#define WINDOW4_NAME "Windows 4"

int main(int argc, char** argv)
{
	// Create OpenCV windows
	cv::namedWindow(WINDOW1_NAME);
	cv::namedWindow(WINDOW2_NAME);
	cv::namedWindow(WINDOW3_NAME);
	cv::namedWindow(WINDOW4_NAME);

	// Init cvui, using WINDOW1_NAME as the default window.
	// The last parameter is false, informing cvui to not
	// create any new window.
	cvui::init(WINDOW1_NAME, -1, false);

	// Tell cvui to monitor the windows,
	// otherwise UI interactions will not work on them.
	cvui::watch(WINDOW2_NAME);
	cvui::watch(WINDOW3_NAME);
	cvui::watch(WINDOW4_NAME);

	while (true)
	{
		// your logic here
	}

	return 0;
}

2. 指定并渲染 cvui 窗口 (Tell cvui about the window, then render it)

当在多个窗口中使用 cvui 组件时,需要通知 cvui 这些组件属于哪个窗口。这样做的方法是将 cvui::context(NAME)cvui::imshow(NAME, frame) 对之间的所有 cvui 组件调用封装起来,其中 NAME 是正在处理的窗口的名称。

下面的示例演示了如何在两个不同的窗口(例如:“window1” 和 “window2”)中渲染一些组件,假设这些窗口之前已经创建并正确初始化了:

// Create a frame for the windows
cv::Mat frame = cv::Mat(200, 500, CV_8UC3);

cvui::context("window1");                    // Inform cvui that the components to be rendered from now one belong to "window1"
cvui::text(frame, 10, 50, "Hello, window1");
cvui::imshow("window1", frame);              // update cvui interactions on window "window1" and show it

cvui::context("window1");                     // Inform cvui that the components to be rendered from now one belong to "window2"
cvui::text(frame, 5, 5, "Hey, window2");
cvui::imshow("window1", frame);               // update cvui interactions on window "window2"
问题

完整代码

#define CVUI_IMPLEMENTATION
#define CVUI_DISABLE_COMPILATION_NOTICES
#include "cvui.h"

#include <iostream>

#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#define WINDOW1_NAME "Windows 1"
#define WINDOW2_NAME "Windows 2"
#define WINDOW3_NAME "Windows 3"
#define WINDOW4_NAME "Windows 4"

int main(int argc, char** argv)
{
	cv::namedWindow("window1");
	cv::namedWindow("window2");

	cvui::init("window1", -1, false);

	// Create a frame for the windows
	cv::Mat frame = cv::Mat(200, 500, CV_8UC3);
	frame = cv::Scalar(100, 100, 100);

	cvui::context("window1");			// Inform cvui that the components to be rendered from now one belong to "window1"
	cvui::text(frame, 10, 50, "Hello, window1");
	cvui::imshow("window1", frame);		// update cvui interactions on window "window1" and show it

	cvui::context("window2");			// Inform cvui that the components to be rendered from now one belong to "window2"
	cvui::text(frame, 5, 5, "Hey, window2");
	cvui::imshow("window2", frame);		// update cvui interactions on window "window2" and show it

	cv::waitKey(500);

	cvui::watch("window1");
	cv::waitKey(0);

	cvui::watch("window2");
	cv::waitKey(0);

	return 0;
}

运行结果

在这里插入图片描述

如图所示,window2 中也包含了 window1 的组件,不知所以。


2.1 精细控制更新和显示 ((Optional) Fine control update and show)

用户可以忽略 cvui::imshow(),这是 cvui 增强版的 cv::imshow(),但用户需要控制每个窗口的更新和显示,例如,通过自己调用 cv::imshow(),可以实现

在这种情况下,可以将所有 cvui 组件调用封装在一对 cvui::context(NAME)cvui::update(NAME) 之间,其中 NAME 是正在处理的窗口的名称。

注意:实际上,cvui::imshow() 所做的就是调用 cvui::update(),然后调用 cv::imshow(),免去用户自己调用这一步。

下面的示例中演示了如何在两个不同的窗口(例如 “window1” 和 “window2”)中分别更新和呈现一些组件,前提是这些窗口之间已经创建并正确初始化了:

// Create a frame for this window and fill it with a nice color
cv::Mat frame = cv::Mat(200, 500, CV_8UC3);

cvui::context("window1");                     // Inform cvui that the components to be rendered from now one belong to "window1"
cvui::text(frame, 10, 50, "Hello, window1");
cvui::update("window1");                      // update cvui interactions on window "window1"

// Show the content of window "window1" on the screen
cvui::imshow("window1", frame);

cvui::context("window1");                     // Inform cvui that the components to be rendered from now one belong to "window2"
cvui::text(frame, 5, 5, "Hey, window2");
cvui::update("window1");                      // update cvui interactions on window "window2"

// Show the content of window "window2" on the screen
cvui::imshow("window2", frame);
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值