在使用VS+QT+OpenCV做圖像處理的過程中,對OpenCV中的Mat類型的資料格式一直很頭疼CV_8UC4,CV_32F等等格式的輸出如果是在使用namewindow+imshow的組合進行彈窗輸出時确實是沒有什麼大問題,但是當需要把圖檔轉成QImage輸出到控件上時就會出大問題了,因為不同圖檔格式的Mat在轉成QImage時需要使用不同的參數。
但是好在Mat類型在自身的不同格式間轉換時沒有什麼阻礙的。是以就此整理出以下Mat類型輸出到QT控件的方法。
一、輸出灰階圖像,輸出灰階圖像在格式轉換前後通常來說不會有太大的影響,僅有的影響也就隻有因為QImage可能會隻顯示圖檔的左上角某一部分(長三分之一,寬三分之一),在我看來應該是圖像中每個像素資料所占的位數不一樣導緻的。是以通常隻需要在轉成QImage前把圖檔使用mat.convertTo(mat,CV_8UC3){也可以用其他格式}轉換格式後再轉成QImage(轉成QImage的方法在下面會給出)。
二、輸出RGB圖,輸出RGB圖在通常時和輸出灰階圖是一樣的(這個通常情況指的是讀取的是RGB圖,輸出這個讀取的RGB圖),但是如果對RGB圖進行了三個通道的拆分後,對RGB通道分别處理以後再重新合成RGB圖像的話(使用vector<Mat> vmat讀取B G R三個通道的資料并分别處理,最後使用merge(vmat,mat)組成輸出的圖像),需要在merge後再次使用convertTO轉變mat的格式,然後才能統一輸出,至于轉成什麼格式,推薦是CV_8UC1,CV_8UC3,CV_8UC4,原因的話,因為本人對QImage的資料格式不了解,隻能參照其他部落客的QImage和Mat類型的格式轉換方法,在之前搜尋的資料中看到過兩個部落客的代碼是可用的,根據自己的使用體驗推薦下面這段代碼
[cpp] view plain copy
- QImage MatToQImage(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;
- }
- // 8-bits unsigned, NO. OF CHANNELS = 3
- 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();
- }
- else if(mat.type() == CV_8UC4)
- {
- qDebug() << "CV_8UC4";
- // 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_ARGB32);
- return image.copy();
- }
- else
- {
- qDebug() << "ERROR: Mat could not be converted to QImage.";
- return QImage();
- }
- }
[cpp] view plain copy
- cv::Mat QImageToMat(QImage image)
- {
- cv::Mat mat;
- switch (image.format())
- {
- case QImage::Format_ARGB32:
- case QImage::Format_RGB32:
- case QImage::Format_ARGB32_Premultiplied:
- mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());
- break;
- case QImage::Format_RGB888:
- mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());
- cv::cvtColor(mat, mat, CV_BGR2RGB);
- break;
- case QImage::Format_Indexed8:
- mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());
- break;
- }
- return mat;
- }
在圖檔格式轉換完成後,使用
ui.QLabel->setPixmap(QPixmap::fromImage(QImage));
ui.QLabel->resize(ui.QLabel->pixmap()->size());
完成QImage輸出到QLabel的操作
本文代碼片段來源:http://blog.csdn.net/dancing_night/article/details/51545524,如有侵犯,請聯系本人好及時删除。