Qt學習——Qimage和Mat

 環境:windows10+Qt5.10.1+openCV3.3.1

 

一、Qimage

資料來源:http://doc.qt.io/qt-5/qimage.html

簡介:

Qimage類提供獨立於硬件的圖像描述,其允許直接對像素數據進行訪問,同時可以作爲繪畫對象使用。

Qt提供了四個用於圖像數據處理的類:QImage,QPixmap,QBitmap和QPicture。

(1)QImage:主要用於I / O和對圖像像素直接訪問和操作。

(2)QPixmap:主要用於在屏幕上顯示圖像。

(3)QBitmap:繼承QPixmap的類,用於確保深度爲1。

(4)QPicture:用於記錄和重放QPainter命令。

因爲QImage是QPaintDevice子類,所以可以使用QPainter直接繪製到QImage格式的圖像上。在QImage上使用QPainter時,可以在獨立於當前GUI線程之外的另一個線程中執行繪製。

QImage支持所多種圖像格式格式。這些包括單色,8位,32位和alpha混合圖像。

QImage提供了一系列功能,可用於獲取有關圖像的各種信息,同時也可用於圖像轉換。

由於QImage類使用隱式數據共享,因此QImage對象可以按值傳遞。QImage對象也可以進行流式處理和比較。

存儲在QImage中的每個像素由整數表示,其大小取決於圖像格式。

注意:如果想在Qt的靜態版本中加載QImage對象,需參閱http://doc.qt.io/qt-5/plugins-howto.html。

警告:不支持在QImage :: Format_Indexed8格式的QImage上畫圖。

支持圖片格式:

 Qimage格式:

Constant Value Description
QImage::Format_Invalid 0 The image is invalid.
QImage::Format_Mono 1 The image is stored using 1-bit per pixel. Bytes are packed with the most significant bit (MSB) first.
QImage::Format_MonoLSB 2 The image is stored using 1-bit per pixel. Bytes are packed with the less significant bit (LSB) first.
QImage::Format_Indexed8 3 The image is stored using 8-bit indexes into a colormap.
QImage::Format_RGB32 4 The image is stored using a 32-bit RGB format (0xffRRGGBB).
QImage::Format_ARGB32 5 The image is stored using a 32-bit ARGB format (0xAARRGGBB).
QImage::Format_ARGB32_Premultiplied 6 The image is stored using a premultiplied 32-bit ARGB format (0xAARRGGBB), i.e. the red, green, and blue channels are multiplied by the alpha component divided by 255. (If RR, GG, or BB has a higher value than the alpha channel, the results are undefined.) Certain operations (such as image composition using alpha blending) are faster using premultiplied ARGB32 than with plain ARGB32.
QImage::Format_RGB16 7 The image is stored using a 16-bit RGB format (5-6-5).
QImage::Format_ARGB8565_Premultiplied 8 The image is stored using a premultiplied 24-bit ARGB format (8-5-6-5).
QImage::Format_RGB666 9 The image is stored using a 24-bit RGB format (6-6-6). The unused most significant bits is always zero.
QImage::Format_ARGB6666_Premultiplied 10 The image is stored using a premultiplied 24-bit ARGB format (6-6-6-6).
QImage::Format_RGB555 11 The image is stored using a 16-bit RGB format (5-5-5). The unused most significant bit is always zero.
QImage::Format_ARGB8555_Premultiplied 12 The image is stored using a premultiplied 24-bit ARGB format (8-5-5-5).
QImage::Format_RGB888 13 The image is stored using a 24-bit RGB format (8-8-8).
QImage::Format_RGB444 14 The image is stored using a 16-bit RGB format (4-4-4). The unused bits are always zero.
QImage::Format_ARGB4444_Premultiplied 15 The image is stored using a premultiplied 16-bit ARGB format (4-4-4-4).
QImage::Format_RGBX8888 16 The image is stored using a 32-bit byte-ordered RGB(x) format (8-8-8-8). This is the same as the Format_RGBA8888 except alpha must always be 255.
QImage::Format_RGBA8888 17 The image is stored using a 32-bit byte-ordered RGBA format (8-8-8-8). Unlike ARGB32 this is a byte-ordered format, which means the 32bit encoding differs between big endian and little endian architectures, being respectively (0xRRGGBBAA) and (0xAABBGGRR). The order of the colors is the same on any architecture if read as bytes 0xRR,0xGG,0xBB,0xAA.
QImage::Format_RGBA8888_Premultiplied 18 The image is stored using a premultiplied 32-bit byte-ordered RGBA format (8-8-8-8).
QImage::Format_BGR30 19 The image is stored using a 32-bit BGR format (x-10-10-10).
QImage::Format_A2BGR30_Premultiplied 20 The image is stored using a 32-bit premultiplied ABGR format (2-10-10-10).
QImage::Format_RGB30 21 The image is stored using a 32-bit RGB format (x-10-10-10).
QImage::Format_A2RGB30_Premultiplied 22 The image is stored using a 32-bit premultiplied ARGB format (2-10-10-10).
QImage::Format_Alpha8 23 The image is stored using an 8-bit alpha only format.

不同格式之間可以通過函數進行轉換:

QImage QImage::convertToFormat(QImage::Format format, Qt::ImageConversionFlags flags = Qt::AutoColor) const &
QImage QImage::convertToFormat(QImage::Format format, Qt::ImageConversionFlags flags = Qt::AutoColor) &&

注意:若使用QPainter,建議採用QImage::Format_ARGB32_Premultiplied代替ARGB32,可以獲得更高速度。

 

二、Mat

Mat用於在OpenCV中實現圖像的存儲和處理,在官方文檔中,在程序編寫過程中Mat可以自動分配空間或者自動釋放內存,但是在實際編寫中依然會出現內存報錯或者溢出的問題,其中需要注意的爲內存的深拷貝和淺拷貝。

Mat包含兩個部分,矩陣頭(包含矩陣大小,用於存儲的方法,存儲矩陣的地址等信息)和指向包含像素值的矩陣的指針(其維度取決於選擇的存儲方法)。矩陣頭的大小是恆定的,但是矩陣本身的大小會隨着圖像的改變而變化,並且通常大幾個數量級。

常用Mat格式及其對應數據格式:

CV_8U: 1-byte unsigned integer (unsigned char).
CV_32S: 4-byte signed integer (int).
CV_32F: 4-byte floating point (float).

Mat初始化

1、默認形式

cv::Mat m;


2、指定類型和大小(行列)的二維數組

cv::Mat m(int rows, int cols, int type)


3、有初始化值的指定類型和大小(行列)的二維數組

cv::Mat m(int rows, int cols, int type, const Scalar& s);


4、使用預先存在數據定義的指定類型和大小(行列)的二維數組

cv::Mat m(int rows, int cols, int type, void* data, size_t step = AUTO_STEP);


5、指定大小(size)和類型的二維數組

cv::Mat m(cv::Size sz, int type, const Scalar& s);


6、使用預先存在的數據定義的指定大小(size)和類型的二維數組

cv::Mat m(cv::Size sz, int type, void* data, size_t step = AUTO_STEP);


7、指定類型的多維數組

cv::Mat m(int ndims, const int* sizes, int type);


8、有初始化值的指定類型多維數組
cv::Mat m(int ndims, const int* sizes, int type, const Scalar& s);

9、使用預先存在的數據定義的指定類型的多維數組
cv::Mat m(int ndims, const int* sizes, int type, void* data, size_t step = AUTO_STEP);

Mat深拷貝和淺拷貝

//淺拷貝:  

Mat A;  

A = image  // 第一種方式  

Mat A(image); // 第二種方式

//淺copy爲共享相同存儲空間,但擁有不同的矩陣頭。當圖像矩陣發生變化時,兩者相關聯,都會變化。


//深拷貝

Mat A,B;  

A = image.clone(); // 第一種方式  

image.copyTo(B);  // 第二種方式  

//深拷貝爲真正的複製了一個新的圖像矩陣,此時image,A,B三者相互沒有影響。

 

三、Qimage和Mat轉換

轉換部分內容參考https://blog.csdn.net/dancing_night/article/details/51545524

(1) Qimage轉換爲Mat:

cv::Mat MainWindow::QImage2cvMat(QImage image)
{
    cv::Mat mat;
    qDebug() << image.format();
    switch(image.format())
    {
    case QImage::Format_ARGB32:
        break;
    case QImage::Format_RGB32:
        break;
    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;
    default:
        break;
    }
    return mat;
}

(2) Mat轉換爲Qimage:


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

 

參考:

http://doc.qt.io/qt-5/qimage.html

https://docs.opencv.org/3.4.1/d3/d63/classcv_1_1Mat.html

https://blog.csdn.net/guduruyu/article/details/66973415

https://blog.csdn.net/dancing_night/article/details/51545524 

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