Miyabiarts.net

一年に一度の更新頻度

Qt+OpenCVで画像を表示

OpenCV2.2から、OpenCVに対してQtを組み込むことが出来ますが、反対のQtにOpenCVを組み込む方法を今更紹介します。
組み込むというか、単純にOpenCVの画像をQtのWidgetで表示するだけです。
表示するためのクラスとして、QWidget(もしくは、QDialog)を継承したImageWidgetクラスを作成します。

対象とするOpenCVは2.2以上で、C++インタフェースのみを対象としています。
画像形式は、グレースケール画像(cv::Mat_)とRGB画像(cv::Mat_)です。
ちなみにエラー処理は行っていないため、設定する画像形式を間違ったらおかしなことになるでしょう。

あまり詳しい説明はしないのですが、下記がImageWidgetクラスの実装となります。

#include <QWidget>
#include <QImage>
#include <opencv2/opencv.hpp>

// 画像表示用ウィジェット
class ImageWidget : public QImage
{
public:
  // 画像を設定(グレースケール画像用)
  void setImage( const cv::Mat_< unsinged char > &img )
  {
    // 画像作成
    cv::Mat_< unsigned char > tmp;
    cv::cvtColor( img, tmp, CV_GRAY2BGR );
    img_ = QImage( tmp.data, img.cols, img.rows, QImage::Format_RGB888 );

      // 更新
     update();
  }

  // 画像を設定(RGB画像用)
  void setImage( const cv::Mat_< cv::Vec3b > &img )
  {
    // 画像を作成
    img_ = QImage( img.data, img.cols, img.rows, QImage::Format_RGB888 );

    // 更新
    update();
  }
private:
  QImage img_;  // 保持するための画像

  // 描画
  void paintEvent( QPaint  * )
  {
    QPainter painter( this );
    // 画像を描画
    painter.drawImage( QPoint( 0, 0 ), img_ );
  }
};

やっていることは、単純にメンバ変数としてQtで画像を扱うQImageのインスタンスを保持しておいて、setImageが呼び出されたら、内部でcv::Mat_からQImageに対応する画素のコピーしているだけです。注意することは、cv::Mat_はあくまで行列なのでQImageとは画像の方向が異なることです。

利点としては、、OpenCVからQtを使うためには色々とめんどくさいことをしないといけないのですが、こちらはQtに対してOpenCVを組み込むので、普通にQtはQtとして使うことができます。
より便利にするためには、元のOpenCVの画像を参照として持っておいて、そちらに変化したら表示も変わるようにするとかですかね。

やりかたは概ね同じであるため、OpenGLで表示させるようにQGLWidgetを継承したクラスについてもいずれ載せたいと思います。

広告

Qt+OpenCVで画像を表示」への1件のフィードバック

  1. ピンバック:Tweets that mention Qt+OpenCVで画像を表示 | Miyabiarts.net -- Topsy.com

%d人のブロガーが「いいね」をつけました。