opencv与Qt的结合使用

作为新手,不得不说自己学的比较吃力,所以记录下整个实现过程的点滴。
这次的程序涉及到opencv的彩色图显示,彩色转换为灰度图的显示,灰度图转换为二值图的显示,以及Qt信号槽的使用,即opencvQt的结合使用。

先展示一下自己的结果:

 


 

这是自己所做的效果图,主要功能就是Qt的界面上有4push button,它们担当的是四个功能键,从上到下button依次作用:
点击按钮显示彩色图,第一个按钮就变白,不再起作用,第二个按钮可以使用;
点击按钮显示灰度图,第二个按钮就变白,不再起作用,第三个按钮可以使用;
点击按钮显示二值图,第三个按钮就变白,不再起作用,第四个按钮可以使用;
点击按钮退出Qt界面。
给出程序如下:
//qt_gray_binary.h
#ifndef QT_GRAY_BINARY_H
#define QT_GRAY_BINARY_H

#include 
#include "ui_qt_gray_binary.h"
#include 
#include 
#include 
class qt_gray_binary : public QMainWindow
{
Q_OBJECT

public:
qt_gray_binary(QWidget *parent = 0);
~qt_gray_binary();
 IplImage* image;//
此指针的定义主要是用于保存图片
 IplImage* imageGray;
    public slots:
       void read_in();//
显示彩色图片
       void gray_img();//
彩色图转换为灰度图并显示
       void binary_img();//
灰度图转换为二值图并显示
       void exit();//
用于点击button后退出Qt的界面
private:
Ui::qt_gray_binaryClass ui;//
不太理解,不过是用于信号槽显示的。

};

#endif // QT_GRAY_BINARY_H

//qt_gray_binary.cpp
#include "qt_gray_binary.h"
#include 

#include 
#include 
#include 

qt_gray_binary::qt_gray_binary(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
connect(ui.pushButton,SIGNAL(clicked()),this,SLOT(read_in()));//
信号槽的连接,主要用于点击button后显示彩色图
connect(ui.pushButton_2,SIGNAL(clicked()),this,SLOT(gray_img()));//
点击button后显示灰度图
connect(ui.pushButton_3,SIGNAL(clicked()),this,SLOT(binary_img()));//
点击button后显示二值图
connect(ui.pushButton_4,SIGNAL(clicked()),this,SLOT(exit()));//
点击button后,退出Qt界面

 

//下面的四个"ui."主要实现的功能是在进入界面后只能先点击按钮read_in,显示彩色图,其他的键显白色,不起作用。

//这个方法的使用,是强制的让运行的人员只能按显示彩色图->显示灰度图->显示二值图->退出来点击按钮,避免了运行显示的错误和重复点击导致的内存泄漏。
ui.pushButton->setEnabled(true);
ui.pushButton_2->setEnabled(false);
ui.pushButton_3->setEnabled(false);
ui.pushButton_4->setEnabled(false);


}

//
显示彩色图
void qt_gray_binary ::read_in()
{  
IplImage *src=cvLoadImage("C:\\Users\\801\\Desktop\\3.jpeg");
image=cvCreateImage(cvGetSize(src),src->depth,src->nChannels);
cvCopy(src,image);
cvNamedWindow("image",CV_WINDOW_AUTOSIZE);
cvShowImage("image",image);
cvWaitKey(0);
cvReleaseImage(&src);
cvDestroyWindow("image");

ui.pushButton->setEnabled(false);
ui.pushButton_2->setEnabled(true);
ui.pushButton_3->setEnabled(false);
ui.pushButton_4->setEnabled(false);
}

 void qt_gray_binary ::gray_img()//
灰度图显示
{  
imageGray=cvCreateImage(cvGetSize(image),image->depth,1);

cvCvtColor(image,imageGray,CV_RGB2GRAY);//
cvNamedWindow("gray_image",CV_WINDOW_AUTOSIZE);
cvShowImage("gray_image",imageGray);
cvWaitKey(0);
cvDestroyWindow("gray_image");

ui.pushButton->setEnabled(false);
ui.pushButton_2->setEnabled(false);
ui.pushButton_3->setEnabled(true);
ui.pushButton_4->setEnabled(false);
}
void qt_gray_binary ::binary_img()//
二值图显示
{
    cvThreshold(imageGray,imageGray, 0, 200, CV_THRESH_OTSU);// 
转为二值图
cvNamedWindow("g_pBinaryImage",CV_WINDOW_AUTOSIZE);
cvShowImage("g_pBinaryImage",imageGray);
    cvWaitKey(0);
cvReleaseImage(&imageGray);
cvDestroyWindow("g_pBinaryImage");

ui.pushButton->setEnabled(false);
ui.pushButton_2->setEnabled(false);
ui.pushButton_3->setEnabled(false);
ui.pushButton_4->setEnabled(true);

}


void qt_gray_binary ::exit()//
退出
{   

QApplication::quit();
}

qt_gray_binary::~qt_gray_binary()
{

}
//main.cpp
#include "qt_gray_binary.h"
#include 
#include "opencv/cv.h"
#include "opencv/highgui.h"

int main(int argc, char *argv[])
{  
QApplication a(argc, argv);
    qt_gray_binary bb;
bb.show();//
这个函数当时不小心注释掉了,它的作用主要用于Qt界面的显示。
return a.exec();
}
以上记录的是实现此功能的全部程序,然后通过自己编程的思路和问题来详细的解读一下:
当初要实现上述功能的时候,我首先想到的是图像在opencv中的转换问题,第一步实现彩色图的显示,第二步实现彩色图转换为灰度图,第三步实现灰度图转换为二值图。这个需要对opencv中的图像转换有个了解,我用的是learning opencv》(Gary Bradsk&Adirian Kaebler)与《OpenCV教程》(刘瑞祯、于仕琪)的书,有一定的基础,所以这个不难,网上的信息也很多,具体的函数的实现,我就不详细记录了。
当中遇到的问题就是,我开始时是在每个小函数里都要设置绝对路径来获取图片,为了简化程序,就设置了一个私有指针*image,然后在显示彩色图像的函数中加载图片,然后指针所指向的内存在程序的运行中存储的东西变化了,然后再在彩色变灰度的图像中使用此内容,然后随着彩色转变为灰度图的运行,指针所指向的内存空间的图片也随之变为一张灰度图,以此类推,在灰度转化为二值图的函数中,*image所指向的内存空间的的内容已经变为灰度图,当灰度转化为二值图的函数运行结束时,*image所指向的内存空间的的内容已经变为二值图。
其次,实现Qt的界面我用的是C++ GUI Qt4编程(第二版)》网上也有关于信号槽的信息,以下网址是我Qt入门的重要资源
http://blog.51cto.com/zt/20/1/
这个里面有关于信号槽具体介绍。

在解决信号槽的问题时,遇到的一个问题就是,也是我今后需要注意的是为了正确的连接信号槽,信号和槽的参数个数、类型以及出现的顺序都必须相同

起初的时候自己就是没有注意到参数的个数以及类型保持一致所以总是无法使得图片以及信号槽连用起来。

 

 


你可能感兴趣的:(openCV,Qt)