QImage图像转换为CV图像失败

时间:2018-02-19 01:20:48

标签: qt opencv

我是opencv和opencv的新手。我正在做的是将QImage图像转换为opencv Mat图像,然后显示它们。这是我转换的代码:

     i = new QImage("lena.png");
    QImage lena = i->scaled(labW,labH,Qt::IgnoreAspectRatio);

    //Original
    QImage lenaRGB = lena.convertToFormat(QImage::Format_RGB888);
    ui->imgWindow->setPixmap(QPixmap::fromImage(lena,Qt::AutoColor));

    //method 1
    Mat lena_cv, out;
    QImage lena2 = lenaRGB.rgbSwapped();
    QImage swapped = lena2;
    swapped = swapped.rgbSwapped();
    lena_cv = Mat(swapped.width(),swapped.height(),CV_8UC3, swapped.bits(),swapped.bytesPerLine()).clone();
    namedWindow("CV Image");
    imshow("CV Image", lena_cv);

    //method 2
    Mat out2,out3;
    out2.create(Size(lena2.width(),lena2.height()),CV_8UC3);
    int width = lena2.width();
    int height = lena2.height();
    memcpy(out2.data, lena2.bits(), sizeof(char)*width*height*3);
    cvtColor(out2,out3,CV_RGB2GRAY);
    namedWindow("CV Image2");
    imshow("CV Image2",out3);

以上两种转换都无法产生所需的图像,如下所示: enter image description here

还注意到,如果不使用rgbSwapped,即:

,转换就无法进行
lena_cv = Mat(lenaRGB.width(),lenaRGB.height(),CV_8UC3, lenaRGB.bits(),lenaRGB.bytesPerLine());

,因为: enter image description here

enter image description here

无法显示生成的图像lena_cv。如果在图像显示之前使用lena_cvcvtColor转换为BGR格式的附加步骤:

    Exception at 0x7ffdff394008, code: 0xe06d7363: C++ exception, flags=0x1  
   (execution cannot be continued) (first chance) at c:\opencv-3.2.0
    \sources\modules\core\src\opencl\runtime\opencl_core.cpp:278

这表示转换为BGR的转换失败。我不确定将QImage转换为CV图像的RGB到BGR转换(QImage)是否必要。 任何人都可以帮助识别上述代码的问题。谢谢:))

1 个答案:

答案 0 :(得分:1)

"倾斜"在第三个图像中几乎可能是假设每条扫描线正好占据width*3个字节的结果。通常是一个"步幅" (或"步骤")考虑许多图像格式图像中的每一行,使得每行的字节数在某个4字节或16字节边界上。幸运的是,QImage有一个名为bytesPerLine的辅助方法,可以告诉你每个源行的持续时间。

所以不要这样:

memcpy(out2.data, lena2.bits(), sizeof(char)*width*height*3);

这样做:

unsigned char* src = lena2.bits();
unsigned char* dst = out2.data;
int stride = lena2.bytesPerLine();
for (int row = 0; row < height; row++)
{
    memcpy(dst + width*3*row, src+row*stride, width*3); // copy a single row, accounting for stride bytes
}

所有这些都假设它是具有步幅字节的QImage,而不是您正在转换位的目标Mat图像。如果我向后反转,则调整代码以考虑Mat的步骤成员。 (我没有看到你使用它,所以我愿意成为你需要的上述代码。)

&#34;蓝色&#34;图像很可能只是需要为每个像素交换的RGB颜色字节。不知道你为什么要调用rgbSwapped,除非那是你想要的效果。哦,等等,你可能指的是图像底部的噪音效果。我愿意打赌你需要思考&#34; stride&#34;字节也在这里。