您的位置:首页 > 编程语言 > Qt开发

QT中的QImage、QPixmap和opencv 中的mat转化

2017-12-01 09:19 253 查看
我们使用QT和opencv的过程中经常会碰到这样的问题:Mat怎么转化位QImage?Mat怎么转化为QPixmap?今天我来告诉大家一个比较好的解决方案(以下代码参考了别人的,增加了一些修改)

#include <QDebug>
#include <QImage>
#include <QPixmap>

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgproc/types_c.h"

namespace CVS
{
// 将Mat转化位QImage
inline QImage  cvMatToQImage( const cv::Mat &inMat )
{
switch ( inMat.type() )
{
// 8-bit, 4 channel
case CV_8UC4:
{
QImage image( inMat.data,
inMat.cols, inMat.rows,
static_cast<int>(inMat.step),
QImage::Format_ARGB32 );

return image;
}

// 8-bit, 3 channel
case CV_8UC3:
{
QImage image( inMat.data,
inMat.cols, inMat.rows,
static_cast<int>(inMat.step),
QImage::Format_RGB888 );

return image.rgbSwapped();
}

// 8-bit, 1 channel
case CV_8UC1:
{
#if QT_VERSION >= QT_VERSION_CHECK(5, 5, 0)
QImage image( inMat.data,
inMat.cols, inMat.rows,
static_cast<int>(inMat.step),
QImage::Format_Grayscale8 );//Format_Alpha8 and Format_Grayscale8 were added in Qt 5.5
#else//这里还有一种写法,最后给出
static QVector<QRgb>  sColorTable;

// only create our color table the first time
if ( sColorTable.isEmpty() )
{
sColorTable.resize( 256 );

for ( int i = 0; i < 256; ++i )
4000

{
sColorTable[i] = qRgb( i, i, i );
}
}

QImage image( inMat.data,
inMat.cols, inMat.rows,
static_cast<int>(inMat.step),
QImage::Format_Indexed8 );

image.setColorTable( sColorTable );
#endif

return image;
}

default:
qWarning() << "CVS::cvMatToQImage() - cv::Mat image type not handled in switch:" << inMat.type();
break;
}

return QImage();
}

//将Mat转化为QPixmap
inline QPixmap cvMatToQPixmap( const cv::Mat &inMat )
{
return QPixmap::fromImage( cvMatToQImage( inMat ) );
}
//将QImage转化为Mat
inline cv::Mat QImageToCvMat( const QImage &inImage, bool inCloneImageData = true )
{
switch ( inImage.format() )
{
// 8-bit, 4 channel
case QImage::Format_ARGB32:
case QImage::Format_ARGB32_Premultiplied:
{
cv::Mat  mat( inImage.height(), inImage.width(),
CV_8UC4,
const_cast<uchar*>(inImage.bits()),
static_cast<size_t>(inImage.bytesPerLine())
);

return (inCloneImageData ? mat.clone() : mat);
}

// 8-bit, 3 channel
case QImage::Format_RGB32:
case QImage::Format_RGB888:
{
if ( !inCloneImageData )
{
qWarning() << "CVS::QImageToCvMat() - Conversion requires cloning because we use a temporary QImage";
}

QImage   swapped = inImage;

if ( inImage.format() == QImage::Format_RGB32 )
{
swapped = swapped.convertToFormat( QImage::Format_RGB888 );
}

swapped = swapped.rgbSwapped();

return cv::Mat( swapped.height(), swapped.width(),
CV_8UC3,
const_cast<uchar*>(swapped.bits()),
static_cast<size_t>(swapped.bytesPerLine())
).clone();
}

// 8-bit, 1 channel
case QImage::Format_Indexed8:
{
cv::Mat  mat( inImage.height(), inImage.width(),
CV_8UC1,
const_cast<uchar*>(inImage.bits()),
static_cast<size_t>(inImage.bytesPerLine())
);

return (inCloneImageData ? mat.clone() : mat);
}

default:
qWarning() << "CVS::QImageToCvMat() - QImage format not handled in switch:" << inImage.format();
break;
}

return cv::Mat();
}

//将QPixmap转化为Mat
inline cv::Mat QPixmapToCvMat( const QPixmap &inPixmap, bool inCloneImageData = true )
{
return QImageToCvMat( inPixmap.toImage(), inCloneImageData );
}
}


//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;


新建一个头文件,将代码(CV_8UC1你自己挑一个吧)添加进去。

如何调用函数?在你要调函数的
.cpp
文件中添加
using namespace CVS;
即可。我推荐你这样去做
CVS::函数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: