Opencv Qt QImage转Mat

Oskar_Sun 2015-06-29 09:08:26
目的:在Qt creator中用QImage读取内存里的一张图片,转换成cv::Mat格式(或Iplimage格式)进行图像算法处理
我实验用本地磁盘里的一张24位或者8位图像,可以顺利从QImage转成Mat,但从内存读取的图像就不行。
读取本地图片代码如下:(8位图像,只用了一个通道)
    QImage image("E:/Test_Picture/ver.tif");
qDebug()<<image.format();
cv::Mat mat = cv::Mat(image.height(),image.width(),
CV_8UC1, (uchar*)image.bits(), image.bytesPerLine());
cv::Mat mat2 = cv::Mat(mat.rows, mat.cols, CV_8UC1 );
int from_to[] = {0,0,1,1,2,2};
cv::mixChannels(&mat,1,&mat2,1,from_to,1);
namedWindow("QImage2Mat");
imshow("QImage2Mat",mat2);

读取本地图片代码(24位,QImage4个通道转成mat三个通道):
    QImage image("D:/Picture/boy.jpg");
qDebug()<<image.format();
cv::Mat mat = cv::Mat(image.height(),image.width(),
CV_8UC4, (uchar*)image.bits(), image.bytesPerLine());
cv::Mat mat2 = cv::Mat(mat.rows, mat.cols, CV_8UC3 );
int from_to[] = {0,0,1,1,2,2};
cv::mixChannels(&mat,1,&mat2,1,from_to,3);

namedWindow("QImage2Mat");
imshow("QImage2Mat",mat2);

这两个都成功了,但是当我读取相机采集到内存的图片时,无论QImage以什么格式保存都报错
代码如下:
    QImage image(aa->m_pRawBuffer,1000,700,QImage::Format_RGB888);
Mat mat =Mat(image.height(),image.width(),
CV_8UC3, (uchar*)image.bits(), image.bytesPerLine());
Mat mat2 =Mat(mat.rows, mat.cols, CV_8UC3 );
int from_to[] = {0,0,1,1,2,2};
mixChannels(&mat,1,&mat2,1,from_to,3);

namedWindow("test");
imshow("test",mat2);


按道理说都是三个通道不应该出错啊,问题出在了哪里呢?
第三段代码中如果QImage以Format_Index8格式读取的话,只拷贝第一个通道也是可以的,但是图片的结果是全部是蓝色,也就是Mat中B这个通道。求高手解答。



或者从内存中能不能直接用Mat格式或者Iplimage格式读取,这样我就不用QImage转Mat了。
...全文
544 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
667778 2016-03-01
  • 打赏
  • 举报
回复
大家好,RGB24是24位像素,内存中RGB的排列顺序是BGRBGR,而RGB888也是24位像素,那RGB24是不是就是RGB888呢?
shiter 2015-12-03
  • 打赏
  • 举报
回复



cv::Mat QImage2cvMat(QImage image)  
48.{  
49.    cv::Mat mat;  
50.    qDebug() << image.format();  
51.    switch(image.format())  
52.    {  
53.    case QImage::Format_ARGB32:  
54.    case QImage::Format_RGB32:  
55.    case QImage::Format_ARGB32_Premultiplied:  
56.        mat = cv::Mat(image.height(), image.width(), CV_8UC4, (void*)image.constBits(), image.bytesPerLine());  
57.        break;  
58.    case QImage::Format_RGB888:  
59.        mat = cv::Mat(image.height(), image.width(), CV_8UC3, (void*)image.constBits(), image.bytesPerLine());  
60.        cv::cvtColor(mat, mat, CV_BGR2RGB);  
61.        break;  
62.    case QImage::Format_Indexed8:  
63.        mat = cv::Mat(image.height(), image.width(), CV_8UC1, (void*)image.constBits(), image.bytesPerLine());  
64.        break;  
65.    }  
66.    return mat;  
67.}  

shiter 2015-12-03
  • 打赏
  • 举报
回复



QImage cvMat2QImage(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();
    }
}
cv::Mat QImage2cvMat(QImage image)
{
    cv::Mat mat;
    qDebug() << image.format();
    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;
}


667778 2015-12-03
  • 打赏
  • 举报
回复
您好,我将采集的摄像头的信息,使用您的方法,效果是长这样的,程序如下:frame->loadFromData((uchar *)pp,320,240*3*sizeo(char));
qDebug()<<image.format();
cv::Mat mat = cv::Mat(image.height(),image.width(),
CV_8UC4, (uchar*)image.bits(), image.bytesPerLine());
cv::Mat mat2 = cv::Mat(mat.rows, mat.cols, CV_8UC3 );
int from_to[] = {0,0,1,1,2,2};
cv::mixChannels(&mat,1,&mat2,1,from_to,3);

cv::cvColor(mat2,mat2,CV_BGR2RGB);
QImage img = QImage((const unsigned char*)mat2.data, mat2.cols, mat2.rows,mat2.cols * mat.2channels(), QImage::Format_RGB888);
667778 2015-12-03
  • 打赏
  • 举报
回复
灰常感谢~~~~
mothe123 2015-07-01
  • 打赏
  • 举报
回复
相机读进来的图有可能是4通道的,需要转化为3通道

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧