Qt界面开发纪实:保存打开图片 添加资源文件 Mat 转化成QImage 文件操作(QT C++ MSVC MinGW )(4)

Qt界面开发纪实:保存打开图片 添加资源文件 Mat 转化成QImage 文件操作(QT C++ MSVC MinGW )(4)

    • 保存图片
    • 打开图片
    • 添加资源文件
    • Mat转化成QImage
    • QCheckBox
    • 记录参数

主要记录一下关于Qt界面的基本操作:这些操作在网上基本都有现成的代码。在这里主要是为了自己以后参考方便

保存图片

使用QImage 的save函数可以对图片直接进行保存:比如现在有QImage 类型的变量Img,直接调用
Img.save(filename,"BMP",100)
就可以将此图片保存成“BMP”类型的图片。
但是一般用户是希望自己能够选择保存的文件夹的,所以,上述直接保存图片的方式是不够的。这里我们使用getSaveFileName 获取保存文件夹路径,该函数定义如下:
Qt界面开发纪实:保存打开图片 添加资源文件 Mat 转化成QImage 文件操作(QT C++ MSVC MinGW )(4)_第1张图片
包含头文件:
#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 ==》取名后确定 ==》添加前缀(随意取名) ==》 添加文件保存即可。
Qt界面开发纪实:保存打开图片 添加资源文件 Mat 转化成QImage 文件操作(QT C++ MSVC MinGW )(4)_第2张图片
Qt界面开发纪实:保存打开图片 添加资源文件 Mat 转化成QImage 文件操作(QT C++ MSVC MinGW )(4)_第3张图片

Qt界面开发纪实:保存打开图片 添加资源文件 Mat 转化成QImage 文件操作(QT C++ MSVC MinGW )(4)_第4张图片
UI界面Qlabel显示资源文件
在这里插入图片描述
右键“改变样式表”==》添加资源 ==》选择资源(选择要显示的图,直接OK就可以了)
Qt界面开发纪实:保存打开图片 添加资源文件 Mat 转化成QImage 文件操作(QT C++ MSVC MinGW )(4)_第5张图片

Mat转化成QImage

将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();
	}
}

QCheckBox

我通过这个空间来控制是否在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();

}

你可能感兴趣的:(OpenCV,Qt,工业相机)