Convert between cv::Mat and QImage 两种图片类转换
在使用Qt和OpenCV混合编程时,我们有时需要在两种图片类cv::Mat和QImage之间进行转换,下面的代码参考了网上这个帖子:
//##### cv::Mat ---> QImage ##### // Shallow copy QImage mat2qimage_ref(cv::Mat &m, QImage::Format format) { return QImage(m.data, m.cols, m.rows, m.step, format); } // Deep copy QImage mat2qimage_cpy(cv::Mat &m, QImage::Format format) { return QImage(m.data, m.cols, m.rows, m.step, format).copy(); } //##### QImage ---> cv::Mat ##### // Shallow copy cv::Mat qimage2mat_ref(QImage &img, int format) { return cv::Mat(img.height(), img.width(), format, img.bits(), img.bytesPerLine()); } // Deep copy cv::Mat qimage2mat_ref(QImage &img, int format) { return cv::Mat(img.height(), img.width(), format, const_cast<uchar*>(img.bits()), img.bytesPerLine()).clone(); }
还可以用下面的这个代码,参考了这个帖子:
//##### cv::Mat ---> QImage ##### QImage cvMat_to_QImage(const cv::Mat &mat ) { switch ( mat.type() ) { // 8-bit, 4 channel case CV_8UC4: { QImage image( mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB32 ); return image; } // 8-bit, 3 channel case CV_8UC3: { QImage image( mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888 ); return image.rgbSwapped(); } // 8-bit, 1 channel case CV_8UC1: { static QVector<QRgb> sColorTable; // only create our color table once if ( sColorTable.isEmpty() ) { for ( int i = 0; i < 256; ++i ) sColorTable.push_back( qRgb( i, i, i ) ); } QImage image( mat.data, mat.cols, mat.rows, mat.step, QImage::Format_Indexed8 ); image.setColorTable( sColorTable ); return image; } default: qDebug("Image format is not supported: depth=%d and %d channels\n", mat.depth(), mat.channels()); break; } return QImage(); } //##### QImage ---> cv::Mat ##### cv::Mat QImage_to_cvMat( const QImage &image, bool inCloneImageData = true ) { switch ( image.format() ) { // 8-bit, 4 channel case QImage::Format_RGB32: { cv::Mat mat( image.height(), image.width(), CV_8UC4, const_cast<uchar*>(image.bits()), image.bytesPerLine() ); return (inCloneImageData ? mat.clone() : mat); } // 8-bit, 3 channel case QImage::Format_RGB888: { if ( !inCloneImageData ) { qWarning() << "ASM::QImageToCvMat() - Conversion requires cloning since we use a temporary QImage"; } QImage swapped = image.rgbSwapped(); return cv::Mat( swapped.height(), swapped.width(), CV_8UC3, const_cast<uchar*>(swapped.bits()), swapped.bytesPerLine() ).clone(); } // 8-bit, 1 channel case QImage::Format_Indexed8: { cv::Mat mat( image.height(), image.width(), CV_8UC1, const_cast<uchar*>(image.bits()), image.bytesPerLine() ); return (inCloneImageData ? mat.clone() : mat); } default: qDebug("Image format is not supported: depth=%d and %d format\n", image.depth(), image.format()); break; } return cv::Mat(); }