OpenCV窗口显示在Qt的控件上

本文介绍了如何在Qt应用中避免将OpenCV的cv::Mat转换为QImage,而是直接利用OpenCV的HighGUI模块在Qt界面上显示图像。通过获取OpenCV窗口的句柄并设置为Qt控件的父窗口,实现了在Qt界面中显示OpenCV图像,提高了效率。
摘要由CSDN通过智能技术生成

使用OpenCV打开一张图片是一件很简单的事情,并且显示出来也非常的轻松,简单到只需两行代码,这是因为OpenCV本身提供了一个HighGui模块,用来做图片的交互显示。

#include<opencv2/opencv.hpp>

int main(){
    cv::Mat src = cv::imread("lena.jpg");
    std::string winName = "lena";
    cv::namedWindow(winName, cv::WINDOW_AUTOSIZE);
    cv::imshow(winName, src);

}

但通常情况下,我们需要自己制作一个ui,用来显示一张图像。如果以Qt作为一个制作UI的工具,网上常用的方法是将cv::Mat格式转换为QImage,或者QPixel格式,然后输出在Qt的控件上。

那有没有可能在qt中直接使用OpenCV的highgui显示cv::Mat类型的数据,而不作转换呢?当然是可以的,而且省略了一步转换,效率更高:

首先准备一个简单的测试界面:由一个widget控件和一个pushButten控件,这样点击按钮打开图像动作和载体都有了。

 fig1. 一个widget和一个按钮

1. OpenCV  HighGUI

 用OpenCV的方式打开一个图片,并显示在nameWindow窗口:

#include "MatShow.h"
#include<opencv2/opencv.hpp>

MatShow::MatShow(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	connect(ui.pushButton, &QPushButton::clicked, [&]() {
		//我们所熟悉的Opencv打开一张图片,并显示
		cv::Mat src = cv::imread("lena.jpg");
		std::string winName = "lena";
		cv::namedWindow(winName, cv::WINDOW_AUTOSIZE);
		cv::imshow(winName, src);				
		});
}

 执行之后,这样的结果很明显不是我们想要的。 

2. Qt嵌入HighGUI

 既然nameWindow窗口也是一个窗口,那么我们可以将nameWindow窗口的句柄 传递给Qt的ui控件上,需要注意的是:

  • 需要注意的是 opencv4之后使用cvGetWindowHandle需要添加头文件#include <opencv2/highgui/highgui_c.h>
  • 使用windows的api需要添加#include<Windows.h>
#include "MatShow.h"
#include<opencv2/opencv.hpp>
#include<Windows.h>
#include <opencv2/highgui/highgui_c.h>

MatShow::MatShow(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	connect(ui.pushButton, &QPushButton::clicked, [&]() {
		//我们所熟悉的Opencv打开一张图片,并显示
		cv::Mat src = cv::imread("lena.jpg");
		std::string winName = "lena";
		cv::namedWindow(winName, cv::WINDOW_AUTOSIZE);
		cv::imshow(winName, src);
		//再Qt控件上显示cv::nameWindow窗口
		HWND hwnd = (HWND)cvGetWindowHandle(winName.c_str());
		HWND paraent = GetParent(hwnd);//得到nameWindow窗口的父句柄
		SetParent(hwnd, (HWND)ui.widget->winId());//设置ui控件的句柄是父句柄
		ShowWindow(paraent, SW_HIDE);//隐藏掉nameWindow窗口
		cv::resizeWindow(winName, cv::Size(ui.widget->width(), ui.widget->height()));		
		});

}

 运行起来就是这个样子了:

 3. 后记

 整体代码就这20几行,是很简单的,主要就是对窗口句柄的理解。 

### 回答1: 在Qt中调用OpenCV库,可以实现高效的图像处理和显示功能。通过使用Qt的QWidget,可以创建一个GUI窗口,并在其中添加一个QLabel控件,用于显示OpenCV捕获的摄像头图像。 具体步骤如下: 1. 首先,需要在Qt项目中添加OpenCV库。 2. 然后,在Qt窗口中创建一个QLabel控件用于显示摄像头图像。 3. 其次,使用OpenCV打开摄像头,读取图像数据。 4. 然后,将OpenCV读取的图像数据转换为QPixmap格式,以便显示在QLabel控件上。 5. 最后,在GUI窗口中循环调用OpenCV读取摄像头图像,并将转换后的图像数据显示在QLabel上。 以下是示例代码: //首先,需要在Qt项目中添加OpenCV库 #include "opencv2/opencv.hpp" #include "opencv2/highgui.hpp" #include "opencv2/imgproc.hpp" //在Qt窗口中创建一个QLabel控件用于显示摄像头图像 QLabel *label = new QLabel(); //使用OpenCV打开摄像头,读取图像数据 cv::VideoCapture cap(0); cv::Mat frame; while(1) { //循环调用OpenCV读取摄像头图像 cap.read(frame); //将OpenCV读取的图像数据转换为QPixmap格式 QPixmap img = QPixmap::fromImage(QImage(frame.data, frame.cols, frame.rows, QImage::Format_RGB888)); //将转换后的图像数据显示在QLabel上 label->setPixmap(img); } ### 回答2: Qt是一种流行的跨平台应用程序开发框架,而OpenCV是一种广泛应用于计算机视觉领域的开放源代码计算机视觉库。使用QtOpenCV可以轻松实现对摄像头的调用和显示。 首先,需要使用Qt中的QWidget类创建一个窗口,然后添加一个QLabel类对象。这个QLabel类对象将用于显示从摄像头捕捉到的图像。在程序中创建一个新的OpenCV摄像头对象,并使用OpenCV中提供的实时捕捉数据的方法从摄像头读取数据。 要在Qt显示从摄像头读取的数据,需要使用OpenCV提供的cv::cvtColor()函数将数据从BGR格式转换为RGB格式。然后,使用Qt提供的QImage类将OpenCV图像转换为Qt图像格式,并在QLabel类对象中显示图像。 最后,通过Qt窗口控制方式可以实现对摄像头进行各种控制操作,例如调节曝光时间、对焦等等。在完成以上步骤后,便可通过QtOpenCV实现对摄像头的调用和显示操作。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值