主要记录一下关于Qt界面的基本操作:这些操作在网上基本都有现成的代码。在这里主要是为了自己以后参考方便
使用QImage 的save函数可以对图片直接进行保存:比如现在有QImage 类型的变量Img,直接调用
Img.save(filename,"BMP",100)
就可以将此图片保存成“BMP”类型的图片。
但是一般用户是希望自己能够选择保存的文件夹的,所以,上述直接保存图片的方式是不够的。这里我们使用getSaveFileName 获取保存文件夹路径,该函数定义如下:
包含头文件:
#include
QImage saved_img;
char buf_save[100];
sprintf(buf_save, "img%d%d", params.ccd_change1, params.save_count_img);
QString filename = QFileDialog::getSaveFileName(this, tr("Save Image"), buf_save, tr("Images (*.bmp )"));
QByteArray ba = filename.toLatin1();
char* Filename = ba.data();
saved_img.save(Filename, "BMP", 100);
打开图片与保存图片类似,需要选择需要打开的图片是哪一张,这里主要使用到的函数是
getOpenFileName
同样需要添加头文件==#include
Qt提供的打开图片的当时有很多种,可以直接定义一个QImage 或者QPixmap的变量Img,调用==Img.load(Filename)即可。
但是由于我这里需要对图片进行处理,图片处理需要的数据类型是Mat类型。这样得到文件路径之后,直接使用OpenCV中提供的imread()==接口就可以了。
QImage imgshow;
Smart_img smart_d1;
QString filename = QFileDialog::getOpenFileName(this, tr("选择图像"), "", tr("Images (*.bmp)"));
if (filename.isEmpty())
return;
else
{
cv::Mat img;
string Filename = filename.toStdString();
img = imread(Filename, 0);
if (img.empty())
{
QMessageBox::information(this, tr("打开图像失败"), tr("打开图像失败!"));
return;
}
}
之后直接对Mat 类型的数据Mat操作就可以了。
这里的资源文件主要是一张图片。博主之前并没有资源文件的概念。直到甲方爸爸说要把他们的logo编译到我提供的dll文件中,还手把手教了一次之后(实验没有成功之后),博主后来又探索了一次,成功把资源文件加到了UI界面中。第一次没有成功主要是,我的这个生成dll的Qt工程中压根就没有加入UI,我每次进行编译的时候都是用VS那边生成好的ui_xxx.h编译我这边的Qt的库工程。至于为啥走了这么一条弯路,博主也不是很明白。
右键工程==》add new ==》然后选择下图Resource File ==》取名后确定 ==》添加前缀(随意取名) ==》 添加文件保存即可。
UI界面Qlabel显示资源文件
右键“改变样式表”==》添加资源 ==》选择资源(选择要显示的图,直接OK就可以了)
将Mat类型的数据转化成QImage的数据主要是为了在UI上展示图像处理的结果。
这个函数是参考网上的代码,但是忘记是哪个了。。。如果有侵权请联系我。
QImage cvMat2QImage(const cv::Mat& mat)
{
// 8-bits unsigned, NO. OF CHANNELS = 1
if (mat.type() == CV_8UC1)
{
QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
// Set the color table (used to translate colour indexes to qRgb values)
image.setColorCount(256);
for (int i = 0; i < 256; i++)
{
image.setColor(i, qRgb(i, i, i));
}
// Copy input Mat
uchar *pSrc = mat.data;
for (int row = 0; row < mat.rows; row++)
{
uchar *pDest = image.scanLine(row);
memcpy(pDest, pSrc, mat.cols);
pSrc += mat.step;
}
return image;
}
else if (mat.type() == CV_8UC3)
{
// Copy input Mat
const uchar *pSrc = (const uchar*)mat.data;
// Create QImage with same dimensions as input Mat
QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
return image.rgbSwapped();
}
}
我通过这个空间来控制是否在UI上显示某些内容。而且调试界面比较特殊,会不定时地打开与关闭。要求每次打开的时候要实时地显示当前控件的状态。所以需要从代码内部对空间赋值,也就是有没有checked。我有个全局变量的类专门记录当前系统的状态。通过这个类中的成员(也就是show_fps)就可以判断这个控件在调试界面关闭之前的状态,再次打开的时候,根据该数值进行判断,然后对控件赋对应的值。
if(params.show_fps ==2)
ui->checkBox_displayFPS->setCheckState(Qt::Checked);
if(params.show_fps == 0)
ui->checkBox_displayFPS->setCheckState(Qt::Unchecked);
我们的UI在使用之前需要调整参数,客户希望能够将第一次调整好的参数保存下来,以备下次打开系统的时候可以直接使用,而不用接着调整参数。
用一个txt文件记录。打开系统的时候调用parameter_To将上次的参数读入系统,关闭系统调用parameter_Save保存参数。
void Vision::parameter_Save(int flag)
{
double parray[7];
mutexVision->lock();
parray[0] = params.Inner_diameter;
parray[1] = params.Outer_diameter;
parray[2] = params.bina;
parray[3] = params.mwin;
parray[4] = params.gwin;
parray[5] = params.pixel_rate_correct;
parray[6] = params.img_enlarge;
mutexVision->unlock();
ofstream outfile;
if (flag == 1) //flag==1:下
outfile.open("parameters.txt");//定义文件流对象
if (flag == 0) //上
outfile.open("parameters1.txt");//定义文件流对象
if (!outfile) {
cerr << "open error!" << endl;
return;
}
for (int i = 0; i < 7; i++)
{
outfile << parray[i] << endl;
}
outfile.close();
}
void Vision::parameter_To(int flag)
{//规定文件中每个数值的意义
//文件只有一列,每个数值代表不同的参数
//分别是:内圆直径,外圆直径,二值化阈值,Mwin,Gwin,外径,放大系数
double parray[7];
int datalen = 0;
ifstream infile;
if(flag==1) //flag==1:下
infile.open("parameters.txt");//定义文件流对象
if (flag==0) //上
infile.open("parameters1.txt");//定义文件流对象
if (!infile) {
cerr << "open error!" << endl;
return;//打开文件失败,不对系统中的值做改变
}
while (!infile.eof())
{
infile >> parray[datalen++];
}
infile.close();//关闭文件
//mutexVision->lock();,open 的时候只有主线程在使用这些参数,所以应该不用加锁
params.Inner_diameter = parray[0];
params.Outer_diameter = parray[1];
params.bina = parray[2];
params.mwin = parray[3];
params.gwin = parray[4];
params.pixel_rate_correct = parray[5];
params.img_enlarge = parray[6];
//mutexVision->unlock();
}