「Qtの基礎 - 画像処理」の版間の差分

ナビゲーションに移動 検索に移動
編集の要約なし
編集の要約なし
1行目: 1行目:
== 概要 ==
== 概要 ==
Qtでは画像を取り扱うクラスとしてQBitmap、QPixmap、QImageの3種類あり、それぞれ使い分けが必要である。<br>
Qtでは画像を取り扱うクラスとして、<code>QBitmap</code>クラス、<code>QPixmap</code>クラス、<code>QImage</code>クラスの3種類あり、それぞれ使い分けが必要である。<br>
<br>
<br>
ここでは、ウィジェット上に画像を表示する手順を記載する。<br>
ここでは、ウィジェット上に画像を表示する手順を記載する。<br>
7行目: 7行目:
== QGraphicsViewクラスを使用する ==
== QGraphicsViewクラスを使用する ==
画像を表示する機能を持っているウィジェットは無いため、ビュークラスを継承して派生クラスを作成する。<br>
画像を表示する機能を持っているウィジェットは無いため、ビュークラスを継承して派生クラスを作成する。<br>
(元々、QGraphicsViewクラスは、QGraphicsSceneクラスを表示するためのものである)<br>
(元々、<code>QGraphicsView</code>クラスは、<code>QGraphicsScene</code>クラスを表示するためのものである)<br>
<br>
<br>
ビュークラスを継承した派生クラスには、元の画像のデータを保持するメンバ変数を定義する。<br>
ビュークラスを継承した派生クラスには、元の画像のデータを保持するメンバ変数を定義する。<br>
31行目: 31行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
QGraphicsViewクラスのpaintEventメソッドは、再描画時に呼び出される仮想関数である。<br>
<code>QGraphicsView</code>クラスの<code>paintEvent</code>メソッドは、再描画時に呼び出される仮想関数である。<br>
paintEventメソッドをオーバーライドして描画部分を記述する。<br>
<code>paintEvent</code>メソッドをオーバーライドして描画部分を記述する。<br>
<br>
<br>
paintEventメソッドとsetImgメソッドの定義は、以下の通りである。<br>
paintEventメソッドとsetImgメソッドの定義は、以下の通りである。<br>
<br>
<br>
以下の例では、paintEventメソッドを使用してQImageクラスのインスタンス(描画用)を生成して、QPainter::drawImageメソッドで描画している。<br>
以下の例では、paintEventメソッドを使用して<code>QImage</code>クラスのインスタンス(描画用)を生成して、<code>QPainter::drawImage</code>メソッドで描画している。<br>
描画用の画像は、ウィジェットのサイズに合わせてリサイズしている。<br>
描画用の画像は、ウィジェットのサイズに合わせてリサイズしている。<br>
<br>
<br>
57行目: 57行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
OpenCVライブラリのcv::Matを使用する場合、OpenCVで画像を処理してその画像を表示するには、以下のように記述する。<br>
OpenCVライブラリの<code>cv::Mat</code>メソッドを使用する場合、OpenCVで画像を処理してその画像を表示するには、以下のように記述する。<br>
カラー画像の場合は、色配列をRGBからBGRに変換する必要がある。<br>
<u>カラー画像の場合は、色配列をRGBからBGRに変換する必要がある。</u><br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
  void MyGraphicsView::paintEvent(QPaintEvent *event)
  void MyGraphicsView::paintEvent(QPaintEvent *event)
65行目: 65行目:
     widgetpainter.setWorldTransform(m_matrix);
     widgetpainter.setWorldTransform(m_matrix);
   
   
     // ここでのm_imgはcv::Mat型オブジェクト
     // メンバ変数m_imgはcv::Matクラスのインスタンス
     QImage qimg = QImage(m_img.ptr(), m_img.cols, m_img.rows, m_img.step, QImage::Format_RGB888);
     QImage qimg = QImage(m_img.ptr(), m_img.cols, m_img.rows, m_img.step, QImage::Format_RGB888);
     qimg = qimg.scaled(viewport()->width(), viewport()->height(), Qt::KeepAspectRatio,Qt::FastTransformation);
     qimg = qimg.scaled(viewport()->width(), viewport()->height(), Qt::KeepAspectRatio,Qt::FastTransformation);
91行目: 91行目:
<br><br>
<br><br>


== ズームイン・ズームアウト・移動 ==
== 画像の拡大・縮小・移動 ==
画像を表示する機能には、ズームイン・ズームアウト、移動等の制御が必要になる場合が多い。<br>
画像を表示する機能には、拡大・縮小、移動等の制御が必要になる場合が多い。<br>
これらの機能を実装するには、QTransformクラスを使用する。<br>
これらの機能を実装するには、<code>QTransform</code>クラスを使用する。<br>
<br>
<br>
まず、QTransformクラスのメンバ変数を2つ宣言する。<br>
まず、<code>QTransform</code>クラスのメンバ変数を2つ宣言する。<br>
QTransformクラスのデフォルトコンストラクタを呼び出す場合、単位行列で初期化される。<br>
<code>QTransform</code>クラスのデフォルトコンストラクタを呼び出す場合、単位行列で初期化される。<br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
  QTransform m_matrix;
  QTransform m_matrix;
102行目: 102行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
次に、QGraphicsViewクラスのpaintEventメソッドをオーバーライドする。<br>
次に、<code>QGraphicsView</code>クラスの<code>paintEvent</code>メソッドをオーバーライドする。<br>
以下のように記述することで、QTransformクラスの情報が反映されるようになる。<br>
以下のように記述することで、<code>QTransform</code>クラスの情報が反映されるようになる。<br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
  void MyGraphicsView::paintEvent(QPaintEvent *event)
  void MyGraphicsView::paintEvent(QPaintEvent *event)
116行目: 116行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
ズームイン・ズームアウトの機能は、以下の通りである。<br>
拡大・縮小の機能は、以下の通りである。<br>
scaleViewメソッドは、ズームイン・ズームアウトの限界値を設定して、変換行列に拡大率を設定する。<br>
既にズームが適用されている場合のために、予め、ズームの中心を移動している。<br>
<br>
<br>
ズームインする場合、scaleViewメソッドの第1引数に正の値を指定する。<br>
以下の例では、拡大・縮小の限界値を設定して、変換行列に拡大率を設定する。<br>
ズームアウトする場合、scaleViewメソッドの第1引数に負の値を指定する。<br>
既に拡大・縮小が適用されている場合のために、予め、ズームの中心を移動している。<br>
第2引数には、ズームイン・ズームアウトの中心となる点を指定する。<br>
<br>
第1引数には、拡大する場合は正の値、縮小する場合は負の値を指定する。<br>
第2引数には、拡大・縮小の中心となる点を指定する。<br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
  void MyGraphicsView::scaleView(qreal factor, QPointF center)
  void MyGraphicsView::scaleView(qreal factor, QPointF center)
159行目: 159行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
controlImagePositionメソッドは、ズームアウトする時、余白が表示されないように画像位置を調整する。<br>
controlImagePositionメソッドは、拡大する時、余白が表示されないように画像位置を調整する。<br>
controlImagePositionメソッドの最後で、viewport()->update();を実行して画面を更新する。<br>
controlImagePositionメソッドの最後で、viewport()->update();を実行して画面を更新する。<br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
166行目: 166行目:
     qreal left, top, right, bottom;
     qreal left, top, right, bottom;
   
   
     //after check top-left, bottom right corner to avoid getting "out" during zoom/panning
     // after check top-left, bottom right corner to avoid getting "out" during zoom/panning
  m_matrix.map(0,0,&left,&top);
    m_matrix.map(0, 0, &left, &top);
   
   
  if(left > 0)
    if(left > 0)
  {
    {
      m_matrix.translate(-left,0);
      m_matrix.translate(-left, 0);
      left = 0;
      left = 0;
  }
    }
   
   
  if(top > 0)
    if(top > 0)
  {
    {
      m_matrix.translate(0,-top);
      m_matrix.translate(0, -top);
      top = 0;
      top = 0;
  }
    }
   
   
  QSize sizeImage = size();
    QSize sizeImage = size();
  m_matrix.map(sizeImage.width(),sizeImage.height(),&right,&bottom);
    m_matrix.map(sizeImage.width(), sizeImage.height(), &right, &bottom);
   
   
  if(right < sizeImage.width())
    if(right < sizeImage.width())
  {
    {
      m_matrix.translate(sizeImage.width()-right,0);
      m_matrix.translate(sizeImage.width() - right, 0);
      right = sizeImage.width();
      right = sizeImage.width();
  }
    }
   
   
  if(bottom < sizeImage.height())
    if(bottom < sizeImage.height())
  {
    {
      m_matrix.translate(0,sizeImage.height()-bottom);
      m_matrix.translate(0, sizeImage.height() - bottom);
      bottom = sizeImage.height();
      bottom = sizeImage.height();
  }
    }
   
   
  m_matrix_inv = m_matrix.inverted();
    m_matrix_inv = m_matrix.inverted();
   
   
     viewport()->update();
     viewport()->update();
203行目: 203行目:
<br>
<br>
以下の例では、移動はマウスの左ボタンを押してドラッグする場合に適用している。<br>
以下の例では、移動はマウスの左ボタンを押してドラッグする場合に適用している。<br>
また、ズームインしている場合にのみ適用している。<br>
また、拡大している場合にのみ適用している。<br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
  void MyGraphicsView::mouseMoveEvent(QMouseEvent *event)
  void MyGraphicsView::mouseMoveEvent(QMouseEvent *event)
335行目: 335行目:
     if(left > 0)
     if(left > 0)
     {
     {
       m_matrix.translate(-left,0);
       m_matrix.translate(-left, 0);
       left = 0;
       left = 0;
     }
     }
341行目: 341行目:
     if(top > 0)
     if(top > 0)
     {
     {
       m_matrix.translate(0,-top);
       m_matrix.translate(0, -top);
       top = 0;
       top = 0;
     }
     }
359行目: 359行目:
     if(bottom < limBottom)
     if(bottom < limBottom)
     {
     {
       m_matrix.translate(0, limBottom-bottom);
       m_matrix.translate(0, limBottom - bottom);
       bottom = limBottom;
       bottom = limBottom;
     }
     }

案内メニュー