Qt界面開發紀實:保存打開圖片 添加資源文件 Mat 轉化成QImage 文件操作(QT C++ MSVC MinGW )(4)

Qt界面開發紀實:保存打開圖片 添加資源文件 Mat 轉化成QImage 文件操作(QT C++ MSVC MinGW )(4)

主要記錄一下關於Qt界面的基本操作:這些操作在網上基本都有現成的代碼。在這裏主要是爲了自己以後參考方便

保存圖片

使用QImage 的save函數可以對圖片直接進行保存:比如現在有QImage 類型的變量Img,直接調用
Img.save(filename,"BMP",100)
就可以將此圖片保存成“BMP”類型的圖片。
但是一般用戶是希望自己能夠選擇保存的文件夾的,所以,上述直接保存圖片的方式是不夠的。這裏我們使用getSaveFileName 獲取保存文件夾路徑,該函數定義如下:
在這裏插入圖片描述
包含頭文件:
#include <QFileDialog>

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 <QFileDialog>==
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

將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();

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章