VS2010+Opencv2.4.9+QT4.8.0实现图像处理
1.首先,安装vs2010,安装QT4.8.0,QT下载连接如下,下载“qt-win-opensource-4.8.0-vs2010.exe”
http://download.qt.io/archive/qt/4.8/4.8.0/
1)点击qt-win-opensource-4.8.0-vs2010.exe安装,我安装到了D:\QT4.8.0。
2)点击qt-vs-addin-1.1.11.exe安装。
3)点击:计算机->属性->高级系统设置->环境变量
环境变量:新建环境变量 名字“QTDIR”;值为“D:\QT4.8.0”
系统变量:在PATH环境变量中添加“D:\QT4.8.0\bin”,使用“;”和其他路径分隔开。
打开vs2010,如果菜单栏出现Qt,则安装成功。
2.然后下载opencv2.4.9,链接如下。
https://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.4.9/opencv-2.4.9.exe/download
1)配置环境变量,右键,我的电脑->高级系统设置->环境变量,在系统变量中找到Path,点击编辑(操作如上述QT,只不过这个不需要配置环境变量,只需要添加系统变量中的Path即可)。
然后,新建两个路径,路径为你刚才安装后的opencv2.4.9的文件夹下的(我安装在D盘):D:\opencv2.4.9\opencv\build\x64\vc10\bin
D:\opencv2.4.9\opencv\build\x86\vc10\bin
3.配置完成后,打开VS2010,新建项目,点击第一个Qt Application
弹出QT界面设置,点击Finish即可。
新建完成后,在左侧解决方案资源管理器下,项目test右键,点击“属性”,进行配置opencv。
1)在VC++目录中的包含目录下,添加三个路径
D:\opencv2.4.9\opencv\build\include
D:\opencv2.4.9\opencv\build\include\opencv
D:\opencv2.4.9\opencv\build\include\opencv2
2)在VC++目录中的库目录下,添加路径
D:\opencv2.4.9\opencv\build\x86\vc10\lib
D:\opencv2.4.9\opencv\build\x64\vc10\lib
3)在链接器->输入,附加依赖项,添加如下:
opencv_calib3d249d.lib
opencv_contrib249d.lib
opencv_core249d.lib
opencv_features2d249d.lib
opencv_flann249d.lib
opencv_gpu249d.lib
opencv_highgui249d.lib
opencv_imgproc249d.lib
opencv_legacy249d.lib
opencv_ml249d.lib
opencv_nonfree249d.lib
opencv_objdetect249d.lib
opencv_ocl249d.lib
opencv_photo249d.lib
opencv_stitching249d.lib
opencv_superres249d.lib
opencv_ts249d.lib
opencv_video249d.lib
opencv_videostab249d.lib
4.配置完成后,左侧test项目下拉后->Form Files文件夹->test.ui,右键选择打开方式,选择Qt Designer设置为默认打开方式,如下图。
设置完成后,双击test.ui,弹出QT设计窗体界面,进行窗体控件设计。
在这里,我们需要拖一个Label和一个PushButton控件到窗体中去。
然后,在Header Files文件夹下的test.h中,添加以下代码,来定义一个槽,用来传递信号。
C++
private slots://定义私有的槽函数
void openImage();
在Source Files文件夹下的test.cpp写入以下代码:
C++
#include "test.h"
#include "ui_test.h"
#include <QFile>
#include <QDir>
#include <QFileDialog>
#include <QString>
#include <QStringList>
#include <QTextStream>
#include <QDebug>
#include <iostream>
#include <opencv\cv.h>
#include <opencv2\highgui\highgui.hpp>
#include <QMessageBox>
using namespace std;
using namespace cv;
test::test(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
connect(ui.btn_openimage, SIGNAL(clicked()),this, SLOT(openImage()));
}
test::~test()
{
}
int OTSU(const Mat srcImage);
void test::openImage()
{
QString pFileName;
pFileName=QFileDialog::getOpenFileName(0,QString::fromLocal8Bit("请选择图像:"),QString::fromLocal8Bit("C:\\Users\\zj790\\Desktop\\"),/*".",*/QString::fromLocal8Bit("Images (*.png *.bmp *.jpg *.tif *.GIF )"));
Mat srcImage,grayImage,dstImage;
char* pChar;
QByteArray pByteArray = pFileName.toLatin1();
pChar=pByteArray.data();
srcImage=imread(pChar,1);
cvtColor(srcImage,grayImage,CV_RGB2GRAY);
int thresholdValue=OTSU(grayImage);
qDebug()<<thresholdValue;
threshold(grayImage,dstImage,thresholdValue,255,THRESH_BINARY);
QImage pImage;
pImage=QImage((const unsigned char*)dstImage.data,dstImage.cols,dstImage.rows,QImage::Format_Indexed8);
pImage = pImage.scaled(ui.lb_displayimage->size(),
Qt::KeepAspectRatio,
Qt::SmoothTransformation);
ui.lb_displayimage->setPixmap(QPixmap::fromImage(pImage));
}
int OTSU(Mat srcImage)
{
int nCols = srcImage.cols;
int nRows = srcImage.rows;
int threShold = 0;
//init the parameters
int nSumPix[256];
float nProDis[256];
for (int i = 0; i < 256; i++)
{
nSumPix[i] = 0;
nProDis[i] = 0;
}
//统计灰度集中每个像素在整幅图像中的个数
for (int i = 0; i < nRows; i++)
{
for (int j = 0; j < nCols; j++)
{
nSumPix[(int)srcImage.at<uchar>(i, j)]++;
}
}
//计算每个灰度级占图像中的概率分布
for (int i = 0; i < 256; i++)
{
nProDis[i] = (float)nSumPix[i] / (nCols*nRows);
}
//遍历灰度级【0,255】,计算出最大类间方差下的阈值
float w0, w1, u0_temp, u1_temp, u0, u1, delta_temp;
double delta_max = 0.0;
for (int i = 0; i < 256; i++)
{
//初始化相关参数
w0 = w1 = u0 = u1 = u0_temp = u1_temp = delta_temp = 0;
for (int j = 0; j < 256; j++)
{
//背景部分
if (j <= i)
{
w0 += nProDis[j];
u0_temp += j*nProDis[j];
}
//前景部分
else
{
w1 += nProDis[j];
u1_temp += j*nProDis[j];
}
}
//计算两个分类的平均灰度
u0 = u0_temp / w0;
u1 = u1_temp / w1;
//依次找到最大类间方差下的阈值
delta_temp = (float)(w0*w1*pow((u0 - u1), 2)); //前景与背景之间的方差(类间方差)
if (delta_temp > delta_max)
{
delta_max = delta_temp;
threShold = i;
}
}
return threShold;
}
最后运行程序,实现简单OTSU二值化处理图片。
原图:
二值化后的图像:
PS:如果运行不成功,则需要打开QT窗体设计器,点击窗体->查看代码,将里面的代码全部复制后,打开ui_test.h,将里面的代码全部替换掉,即可。主要是嵌入vs2010的QT界面设计无法及时与VS2010相互更新,所以控件名称不能及时更新。
详细参考以下两篇博文,感谢你们:
https://blog.youkuaiyun.com/silent_gods/article/details/81046919
https://www.cnblogs.com/woshitianma/p/3853447.html