使用Qt建立第一个OpenCV的Gui应用

 

写在前面

    学习OpenCV有一些小日子了,发现群里还有不少初学OpenCV的人像我当初同样跌跌撞撞处处找资料,因此在这里把学习笔记分享给你们,但愿有志学习OpenCV进行计算机视觉活动的小伙伴们能少走一些弯路。 html

    通过多方面查阅资料,了解到Qt开发平台对OpenCV的支持很好,可是在网上这方面的资料不多,能查到的大部分的图形交互设计都是基于OpenCV2.0以前的数据结构IplImage,而OpenCV如今官方已经更新到2.4.9版本了。偶然发现一本好书最近获得了一本好书《 OpenCV 2 Computer Vision Application Programming Cookbook》,下载的连接为http://ishare.iask.sina.com.cn/f/20485520.html?retcode=0, 2011年5月出版,全书都是基于OpenCV2.2版本的实现,采用了新的数据结构,该书如今已经有中文版《OpenCV2计算机视觉编程手册》2013年7月科学出版社出版。我这里强烈建议利用C++开发的朋友们不要再使用老版本的数据结构了,实在影响开发效率。至于你们最熟悉的参考书《learning OpenCV》和《OpenCV教程——基础篇》这两本广为流传的书,个人见解是已经远远不能知足OpenCV新版本的学习了。老版本的OpenCV头文件的包含格式通常是: 编程

#include "cv.h"
#include "highgui.h"

     而2.2之后的版本头文件包含通常为:数据结构

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

    为了保持对以前版本的兼容,这些头文件仍然可以使用,可是建议使用新的包含方式。函数

打开并显示图片

       在Qt中,信号与槽是最重要的机制,这里咱们能够建立一个按钮、或者菜单、工具条,来做为发射信号的载体,用一个槽函数来接收打开这个动做。 工具

QPushButton  OpenImageButton = new QPushButton( tr("Find Image") );
OpenImageButton->setDefault( false );
OpenImageButton->setEnabled( true );
       槽函数:打开文件能够利用Qt类QFileDialog来实现。
void qttest1::on_OpenImage_clicked()
{
   QString fileName = QFileDialog::getOpenFileName( this, tr( "Open Image" ), ".", tr("Image Files(*.png*.jpg*.jpeg*.bmp)"));
   image = cv::imread( fileName.toLocal8Bit().data());
   cv::imshow("Source Image", image);
}

     上面的函数已经实现了打开并显示图片。咱们再添加一个按钮,并定义一个函数来对图片进行操做。学习

void qttest1::on_Process_clicked()
{
   cv::flip(image, image, 1);
   cv::namedWindow("Output Image");
   cv::imshow("Output Image", image);
}

      对于初学者,这些工做都作完以后,固然不要忘记链接信号与槽。ui

connect(OpenImageButton,SIGNAL(clicked()),SLOT(on_OpenImage_clicked()));
connect(ProcessButton,SIGNAL(clicked()),SLOT(on_Process_clicked()));

    这些工做作完之后,就能够打开并显示图片啦!this

1

    3

        固然,有些同窗可能会出现下面这样的状况,记得在你的析构函数里释放对象,spa

       cvDestroyAllWindows(); 设计

       按理说,OpenCV2是自动释放对象的,楼主这里尚未搞清楚,也请搞清楚的同窗留言,很是感谢。

2

    小小改进一下吧

      单独弹出一个窗口并显示老是给人突兀的感受,下面实现Qt的窗体中显示图片,显示的方法有不少,不一样的显示方法存在着效率等各方面的问题,这里使用QImage转QPixmap,而后用QLabel::setPixmap()来完成显示,还有比较经常使用的方法是在paintEvent()中直接画,具体的差别没有去探究。

      咱们写一个小函数来实现:

void qttest1::displayMat(cv::Mat image)
{
   cv::Mat rgb;
   QImage img;
   if(image.channels()==3)
   {
       //cvt Mat BGR 2 QImage RGB
       cv::cvtColor(image,rgb,CV_BGR2RGB);
       img =QImage((const unsigned char*)(rgb.data),
                   rgb.cols,rgb.rows,
                   rgb.cols*rgb.channels(),
                   QImage::Format_RGB888);
   }
   else
   {
       img =QImage((const unsigned char*)(image.data),
                   image.cols,image.rows,
                   image.cols*image.channels(),
                   QImage::Format_RGB888);
   }

   imagelabel->setPixmap(QPixmap::fromImage(img));
   imagelabel->resize(imagelabel->pixmap()->size());
}

       最后的效果是这样,是否是简洁明了了不少?

4

相关文章
相关标签/搜索