【C#】HALCON de 画像処理(画像回転 方法2)

スポンサーリンク

今回も画像を回転させる内容を紹介しようと思います。
前回は回転中心を画像中心としていましたが、今回は【回転中心を指定して画像を回転】します。

今回使用する関数

使う関数としては下記3つになります。

HOperatorSet.HomMat2dIdentity(out HTuple)
   ⇒ 均一な2D行列を生成
HOperatorSet.HomMat2dRotate(HTuple, HTuple, HTuple, HTuple, out HTuple)
  ⇒ 均一な2D行列に回転を追加HOperatorSet.AffineTransImage(HObject , out HObject, HTuple, HTuple, HTuple)
  ⇒ 任意のアフィン2D行列を画像に適用(変換)

にわか知識ですが、ホモグラフィー行列の計算(射影変換の一種[回転])を行って、画像を変換する流れだと思っています。
※こんな細かい事はいいのですw

■HOperatorSet.HomMat2dIdentity(out HTuple)
   第1引数:行列(出力)

■HOperatorSet.HomMat2dRotate(HTuple, HTuple, HTuple, HTuple, out HTuple)
  第1引数:行列
  第2引数:回転する角度(ラジアン)
  第3引数:回転中心X
  第4引数:回転中心Y
  第5引数:変換後の行列

■HOperatorSet.AffineTransImage(HObject , out HObject, HTuple, HTuple, HTuple)
  第1引数:入力画像
  第2引数:変換後の画像(出力画像)
  第3引数:行列
  第4引数:保管の方法("bicubic","bilinear","constant","nearest_neighbor","weighted")
  第5引数:出力画像のサイズの適用("false" or "true")

※太字は、デフォルト値

難しい事は分かりませんが、流れは下記の通りになります。
①行列を生成
②その行列に回転を加味した行列に変換
③回転を加味した行列を画像に変換

座学をしても分からないので次に実際に作ってみます。

詳しい事を知りたい方は、下記内容を参考にしてください。
hom_mat2d_identity [HALCON Operator Reference / Version 13.0.4] (mvtec.com)
hom_mat2d_rotate [HALCON Operator Reference / Version 13.0.4] (mvtec.com)
affine_trans_image [HALCON Operator Reference / Version 13.0.4] (mvtec.com)

サンプルを作ってみる

今回も画像中心を回転中心として、回転させたいと思います。
その為、回転前には画像のサイズを取得して、取得したサイズの縦・横 各々の半分の値を回転中心として指定します。

操作画面

前回の記事の内容をそのまま流用し、クリックイベントの処理だけ変更しました。

ボタンの処理概要については、下記記事を参照してください。
【C#】HALCON de 画像処理(画像回転) | 育児パパの人生備忘録 (t19488sns.com)

右に45度回転(右回転:時計回り)

画像サイズを取得し、取得したサイズ(縦、横)の半分の数値を半分にした数値をHomMat2dRotate()で指定する事で、回転中心を画像中心にすることが出来ます。

private void btnRotateR45_Click(object sender, EventArgs e)
{
    if (DispOrgImg == null) return;    //読み込んでいるかどうか

    //画像サイズ取得
    HOperatorSet.GetImageSize(DispOrgImg, out HTuple wb, out HTuple hb);

    ValueRotate -= Math.PI / 4;     //[PI = 180度]
    ValueRotate %= 2 * Math.PI;     //360度で割った時の余りの数値にする(360°= 0°)

    //画像回転
    HOperatorSet.HomMat2dIdentity(out HTuple HTmpIdentity);
    HOperatorSet.HomMat2dRotate(HTmpIdentity, ValueRotate, hb / 2, wb / 2, out HTuple hTmp);
    HOperatorSet.AffineTransImage(DispOrgImg, out HObject tmpImg, hTmp, "constant", "true");

    //Zoom方式で表示
    HTuple hwndOrg = hWindowControl1.HalconWindow;
    HOperatorSet.ClearWindow(hwndOrg);
    DispZoom(hwndOrg, tmpImg);
}

※前回の関数[RotateImage()]の場合は、回転の単位が『度(degree)』でしたが、今回の関数は『ラジアン(rad)』になっているので注意しましょう。
※プラス方向の数値は、反時計回りなので注意しましょう

左に45度回転(左回転:反時計回り)

private void btnRotateL45_Click(object sender, EventArgs e)
{
    if (DispOrgImg == null) return;    //読み込んでいるかどうか

    //画像サイズ取得
    HOperatorSet.GetImageSize(DispOrgImg, out HTuple wb, out HTuple hb);

    ValueRotate += Math.PI / 4;     //360度 - 45度[PI = 180度]
    ValueRotate %= 2 * Math.PI;     //360度で割った時の余りの数値にする(360°= 0°)

    //画像回転
    HOperatorSet.HomMat2dIdentity(out HTuple HTmpIdentity);
    HOperatorSet.HomMat2dRotate(HTmpIdentity, ValueRotate, hb / 2, wb / 2, out HTuple hTmp);
    HOperatorSet.AffineTransImage(DispOrgImg, out HObject tmpImg, hTmp, "constant", "true");

    //Zoom方式で表示
    HTuple hwndOrg = hWindowControl1.HalconWindow;
    HOperatorSet.ClearWindow(hwndOrg);
    DispZoom(hwndOrg, tmpImg);
}

実行結果(出力画像サイズを適用しない場合)

今回の紹介したプログラムでは、次の実行結果になりますが、AffineTransImage()の第5引数の内容を『出力画像のサイズ適用をしない”false”』でしてみました。
回転させたときに入力画像のサイズのまま回している為、見切れてしまいます。

【右回転:時計回り】

【左回転:反時計回り】

実行結果(出力画像サイズを適用した場合)

今回の紹介したプログラムでは、AffineTransImage()の第5引数の内容を『出力画像のサイズ適用をする』でしてみました。
少し表示位置の計算に不具合が発生してしまいましたが、画像が見切れることはなくなりそうです。

【右回転:時計回り】

【左回り:反時計回り】

まとめ

『回転中心を指定して、画像を回転させる』という事を実施しました。
正直な話、最初は何しているか全く分かりませんでした。笑
ただ理解は後からでもいいと思っています。まずは結果を出して、自分なりにアレンジしていければいいと思います。
個人的な感想ですが、この方法は『融通が利く』ので使うならこっちの方がいいと思います。

コメント

タイトルとURLをコピーしました