4

opencv と qt を統合しようとしているアプリケーションを作成しようとしています。

以下のコードを使用して、cv::Mat を QImage に変換することに成功しました。

void MainWindow::loadFile(const QString &fileName)
{
    cv::Mat tmpImage = cv::imread(fileName.toAscii().data());
    cv::Mat image;

    if(!tmpImage.data || tmpImage.empty())
    {
        QMessageBox::warning(this, tr("Error Occured"), tr("Problem loading file"), QMessageBox::Ok);
        return;
    }

/* Mat to Qimage */
    cv::cvtColor(tmpImage, image, CV_BGR2RGB);
    img = QImage((const unsigned char*)(image.data), image.cols, image.rows, QImage::Format_RGB888);

    imgLabel->setPixmap(QPixmap::fromImage(img));
    imgLabel->resize(imgLabel->pixmap()->size());

    saveAsAct->setEnabled(true);
}

ただし、次のコードを使用して QImage を cv::Mat に変換しようとすると:

bool MainWindow::saveAs()
{
    if(fileName.isEmpty())
    {
        QMessageBox::warning(this, tr("Error Occured"), tr("Problem loading file"), QMessageBox::Close);
        return EXIT_FAILURE;
    }else{
        outputFileName = QFileDialog::getSaveFileName(this, tr("Save As"), fileName.toAscii().data(), tr("Image Files (*.png *.jpg *.jpeg *.bmp)\n *.png\n *.jpg\n *.jpeg\n *.bmp"));

    /* Qimage to Mat */
    cv::Mat mat = cv::Mat(img.height(), img.width(), CV_8UC4, (uchar*)img.bits(), img.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::imwrite(outputFileName.toAscii().data(), mat);
}

saveAct->setEnabled(true);
return EXIT_SUCCESS;
}

私は成功せず、結果は完全に無秩序なイメージです。私が検索したネットでは、人々が特定の問題について言及することなくこの方法を使用していることがわかりました. 何が問題を引き起こしているのかについて、誰かが何か考えを持っていますか? 前もって感謝します。

セオドア

PS私は、gnome-3.4を搭載したArch Linuxシステムでopencv 2.4とQt 4.8を使用しています

4

6 に答える 6

0

これは便利だと思います。http://www.jdxyw.com/?p=1480

IplImage を使用してデータを取得しますが、cv::Mat と Mat.data を使用して元の行列へのポインターを取得できます。これが役に立つことを願っています。

于 2012-06-23T17:44:06.343 に答える
0

これは、ホセのおかげでここから得たものです。これを乗り越えるのに役立ちます。

Qt (QImage) で OpenCV イメージ (cv::Mat) を視覚化するには、次の手順に従う必要があります。

  1. 色の順序を反転:cv::cvtColor(imageBGR, imageRGB, CV_BGR2RGB);
  2. 形式を OpenCV から Qt に変更します。QImage qImage((uchar*) imageRGB.data, imageRGB.cols, imageRGB.rows, imageRGB.step, QImage::Format_RGB888);
  3. QPainter を使用して画像をレンダリングします。

QImage::Format の使用に注意してください。この問題について Qt を読んでください。

于 2012-08-02T10:50:06.990 に答える
0

まだ解決策を探している場合。これが1つです:

Cv::Mat から QImage :

QImage Mat2QImage(cv::Mat &image )
{
    QImage qtImg;
    if( !image.empty() && image.depth() == CV_8U ){
        if(image.channels() == 1){
            qtImg = QImage( (const unsigned char *)(image.data),
                            image.cols,
                            image.rows,
                            QImage::Format_Indexed8 );
        }
        else{
            cvtColor( image, image, CV_BGR2RGB );
            qtImg = QImage( (const unsigned char *)(image.data),
                            image.cols,
                            image.rows,
                            QImage::Format_RGB888 );
        }
    }
    return qtImg; 
}

QImage から cv::Mat へ。

cv::Mat QImage2Mat(QImage &image) {

cv::Mat cvImage;
  switch (image.format()){
  case QImage::Format_RGB888:{
      cvImage = cv::Mat(image.height(),
                        image.width(),
                        CV_8UC3,
                        image.bits(),
                        image.bytesPerLine());
      cv::cvtColor(cvImage, cvImage, CV_RGB2BGR);
      return cvImage;
  }
  case QImage::Format_Indexed8:{
      cvImage = cv::Mat(image.height(),
                        image.width(),
                        CV_8U,
                        image.bits(),
                        image.bytesPerLine());
      return cvImage;
  }
  default:
      break;
  }
  return cvImage;
}
于 2016-04-30T18:05:03.753 に答える
0

このソースコードから

QImage MatToQImage(const Mat& mat)
{
    // 8-bits unsigned, NO. OF CHANNELS=1
    if(mat.type()==CV_8UC1)
    {
        // Set the color table (used to translate colour indexes to qRgb values)
        QVector<QRgb> colorTable;
        for (int i=0; i<256; i++)
            colorTable.push_back(qRgb(i,i,i));
        // Copy input Mat
        const uchar *qImageBuffer = (const uchar*)mat.data;
        // Create QImage with same dimensions as input Mat
        QImage img(qImageBuffer, mat.cols, mat.rows, mat.step, QImage::Format_Indexed8);
        img.setColorTable(colorTable);
        return img;
    }
    // 8-bits unsigned, NO. OF CHANNELS=3
    if(mat.type()==CV_8UC3)
    {
        // Copy input Mat
        const uchar *qImageBuffer = (const uchar*)mat.data;
        // Create QImage with same dimensions as input Mat
        QImage img(qImageBuffer, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);
        return img.rgbSwapped();
    }
    else
    {
        qDebug() << "ERROR: Mat could not be converted to QImage.";
        return QImage();
    }
} // MatToQImage()
于 2012-06-25T21:18:06.160 に答える
0

opencv イメージは、各行が 32 ビットの倍数で始まるようにステップ化されます。これにより、メモリ アクセスが高速になります。3 バイト/ピクセル形式を使用している場合、幅が 4 の倍数の 1/3 でない限り、各行の最後に「予備の」メモリがあります。

安全な方法は、イメージ データを一度に 1 行ずつコピーすることです。opencv mat.ptr(row) は各行の先頭へのポインターを返し、 QImage .scanline(row) メンバーは同じことを行います

Qt でこの 24 ビット イメージを出力する方法を参照してください。

編集:次のようなもの

for (int i=0;i<image.height();i++) {
    memcpy(mat.ptr(i),image.scanline(i),image.bytesperline());
}
于 2012-06-23T16:49:47.403 に答える