一、首先了解cv::Mat結構體
cv::Mat::step與QImage轉換有著較大的關系。
step的幾個類別區分:
- step:矩陣第一行元素的字節數
- step[0]:矩陣第一行元素的字節數
- step[1]:矩陣中一個元素的字節數
- step1(0):矩陣中一行有幾個通道數
- step1(1):一個元素有幾個通道數(channel())
cv::Mat cvmat(3, 4, CV_16UC4, cv::Scalar_<uchar>(1, 2, 3, 4));std::cout << cvmat<< std::endl;std::cout << "step:" << cvmat.step << std::endl;std::cout << "step[0]:" << cvmat.step[0] << std::endl;std::cout << "step[1]:" << cvmat.step[1] << std::endl;std::cout << "step1(0):" << cvmat.step1(0) << std::endl;std::cout << "step1(1):" << cvmat.step1(1) << std::endl;
運行結果:
分析:
創建了一個3?4的16位4通道的矩陣;
每一個元素賦值為1,2,3,4;可以看到生成了3*4*4的矩陣;
因為創建的是16位的,所以每一個通道是2個字節數;
所以一行共有4*4*2=32個字節數,故step和step[0]都為32;
因為一個元素有4個通道,每個通道2個字節,所以1個元素的字節數step[1]為4*2=8;
一行是4個元素,每個元素是4個通道,所以一行的通道數,step1(0)為4*4=16,step1(1)為4;
二、cv::Mat轉QImage
代碼示例為拷貝轉換:
QImage cvMat2QImage(const cv::Mat& mat)
{if (mat.empty()){return QImage();}QImage image;switch (mat.type()){case CV_8UC1:{image = QImage((const uchar*)(mat.data),mat.cols, mat.rows, mat.step,QImage::Format_Grayscale8);return image.copy();}case CV_8UC2:{mat.convertTo(mat, CV_8UC1);image = QImage((const uchar*)(mat.data),mat.cols, mat.rows, mat.step,QImage::Format_Grayscale8);return image.copy();}case CV_8UC3:{// Copy input Matconst uchar *pSrc = (const uchar*)mat.data;// Create QImage with same dimensions as input MatQImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);return image.rgbSwapped();}case CV_8UC4:{// Copy input Matconst uchar *pSrc = (const uchar*)mat.data;// Create QImage with same dimensions as input MatQImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);return image.copy();}case CV_32FC1:{Mat normalize_mat;normalize(mat, normalize_mat, 0, 255, NORM_MINMAX, -1);normalize_mat.convertTo(normalize_mat, CV_8U);const uchar *pSrc = (const uchar*)normalize_mat.data;QImage image(pSrc, normalize_mat.cols, normalize_mat.rows, normalize_mat.step, QImage::Format_Grayscale8);return image.copy();}case CV_32FC3:{Mat normalize_mat;normalize(mat, normalize_mat, 0, 255, NORM_MINMAX,-1);normalize_mat.convertTo(normalize_mat, CV_8U);const uchar *pSrc = (const uchar*)normalize_mat.data;// Create QImage with same dimensions as input MatQImage image(pSrc, normalize_mat.cols, normalize_mat.rows, normalize_mat.step, QImage::Format_RGB888);return image.rgbSwapped();}case CV_64FC1:{Mat normalize_mat;normalize(mat, normalize_mat, 0, 255, NORM_MINMAX, -1);normalize_mat.convertTo(normalize_mat, CV_8U);const uchar *pSrc = (const uchar*)normalize_mat.data;QImage image(pSrc, normalize_mat.cols, normalize_mat.rows, normalize_mat.step, QImage::Format_Grayscale8);return image.copy();}case CV_64FC3:{Mat normalize_mat;normalize(mat, normalize_mat, 0, 255, NORM_MINMAX, -1);normalize_mat.convertTo(normalize_mat, CV_8U);const uchar *pSrc = (const uchar*)normalize_mat.data;// Create QImage with same dimensions as input MatQImage image(pSrc, normalize_mat.cols, normalize_mat.rows, normalize_mat.step, QImage::Format_RGB888);return image.rgbSwapped();}case CV_32SC1:{Mat normalize_mat;normalize(mat, normalize_mat, 0, 255, NORM_MINMAX, -1);normalize_mat.convertTo(normalize_mat, CV_8U);const uchar *pSrc = (const uchar*)normalize_mat.data;QImage image(pSrc, normalize_mat.cols, normalize_mat.rows, normalize_mat.step, QImage::Format_Grayscale8);return image.copy();}case CV_32SC3:{Mat normalize_mat;normalize(mat, normalize_mat, 0, 255, NORM_MINMAX, -1);normalize_mat.convertTo(normalize_mat, CV_8U);const uchar *pSrc = (const uchar*)normalize_mat.data;// Create QImage with same dimensions as input MatQImage image(pSrc, normalize_mat.cols, normalize_mat.rows, normalize_mat.step, QImage::Format_RGB888);return image.rgbSwapped();}case CV_16SC1:{Mat normalize_mat;normalize(mat, normalize_mat, 0, 255, NORM_MINMAX, -1);normalize_mat.convertTo(normalize_mat, CV_8U);const uchar *pSrc = (const uchar*)normalize_mat.data;QImage image(pSrc, normalize_mat.cols, normalize_mat.rows, normalize_mat.step, QImage::Format_Grayscale8);return image.copy();}case CV_16SC3:{Mat normalize_mat;normalize(mat, normalize_mat, 0, 255, NORM_MINMAX, -1);normalize_mat.convertTo(normalize_mat, CV_8U);const uchar *pSrc = (const uchar*)normalize_mat.data;// Create QImage with same dimensions as input MatQImage image(pSrc, normalize_mat.cols, normalize_mat.rows, normalize_mat.step, QImage::Format_RGB888);return image.rgbSwapped();}case CV_8SC1:{//Mat normalize_mat;//normalize(mat, normalize_mat, 0, 255, NORM_MINMAX, -1);mat.convertTo(mat, CV_8U);const uchar *pSrc = (const uchar*)mat.data;QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_Grayscale8);return image.copy();}case CV_8SC3:{mat.convertTo(mat, CV_8U);const uchar *pSrc = (const uchar*)mat.data;QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);return image.rgbSwapped();}default:mat.convertTo(mat, CV_8UC3);QImage image((const uchar*)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);return image.rgbSwapped();return QImage();break;}
}
三、QImage轉cv::Mat
示例代碼為共享內存轉換:
cv::Mat QImage2cvMat(QImage& image)
{cv::Mat mat;//qDebug() << image.format();switch (image.format()){case QImage::Format_ARGB32:mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());break;case QImage::Format_RGB32:mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());//cv::cvtColor(mat, mat, CV_BGR2RGB);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;case QImage::Format_Grayscale8:mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());break;}return mat;
}