Bootstrap

OpenCV窗口显示在Qt的控件上

使用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几行,是很简单的,主要就是对窗口句柄的理解。 

;