今回も画像を回転させる内容を紹介しようと思います。
前回は回転中心を画像中心としていましたが、今回は【回転中心を指定して画像を回転】します。
今回使用する関数
使う関数としては下記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引数の内容を『出力画像のサイズ適用をする』でしてみました。
少し表示位置の計算に不具合が発生してしまいましたが、画像が見切れることはなくなりそうです。
【右回転:時計回り】
【左回り:反時計回り】
まとめ
『回転中心を指定して、画像を回転させる』という事を実施しました。
正直な話、最初は何しているか全く分かりませんでした。笑
ただ理解は後からでもいいと思っています。まずは結果を出して、自分なりにアレンジしていければいいと思います。
個人的な感想ですが、この方法は『融通が利く』ので使うならこっちの方がいいと思います。
業務でプログラミング(C#/VB/Python)を作っている。
挫折を何回も繰り返し、幾度の壁を乗り越えてきた。
乗り越えてきた事を忘れないように記録に残す。
同じ思いをしている人への情報提供になれたらと思う。
基本は初心者に向けたプログラムの情報を提供する。
コメント