方法
Halcon有分別提供鏡射(mirror_image)及旋轉(rotate_image)的方法,但如果考慮效能及時間,透過齊次座標(Homogeneous Coordinate)一次將影像轉換是最有效率的。
當然Halcon也有提供很完整的齊次座標的相關功能,1D~3D都有,只要了解中間的數學公式想怎麼轉都可以。
本次整個過程很簡單,會先經過鏡射再旋轉。生成的步驟如下:
1.產生空的轉換矩陣
HOperatorSet.HomMat2dIdentity(out homMat);
2.鏡射矩陣
flip定義None、X、Y,表示沿影像的半高或半寬的位置翻轉。
switch (flip)
{
case ImageFlip.X:
HOperatorSet.HomMat2dReflect(hotMat, 0, w /2, h, w / 2, out homMat);
break;
case ImageFlip.Y:
HOperatorSet.HomMat2dReflect(hotMat, h /2, 0, h / 2, w, out homMat);
break;
}
3.乘上旋轉矩陣
rotate定義0、1、2、3分別代表0、90、180、270度,並以影像中心(半高半寬)旋轉。
有個重點是當角度是90、270度時,因為影像的原點(0,0)是在左上角,需要將影像偏移一半的長寬差。
不了解的話可以拿張名片在手裡轉轉看。
HTuple phi = (int)rotate * Math.PI / 2;
HTuple min, max;
if ((int)rotate % 2 == 0)
{
HOperatorSet.HomMat2dRotate(hotMat, phi, h /2, w / 2, out homMat);
}
else
{
HOperatorSet.HomMat2dRotate(hotMat, phi, h /2, w / 2, out homMat);
HOperatorSet.TupleMax2(h, w, out max);
HOperatorSet.TupleMin2(h, w, out min);
HTuple shift = (max - min) / 2.0;
if (max.TupleEqual(h))
{
//長影像轉寬影像,往"右上"偏移
HOperatorSet.HomMat2dTranslate(homMat, -shift, shift, out homMat);
}
else
{
//反之,往"左下"偏移
HOperatorSet.HomMat2dTranslate(homMat, shift, -shift, out homMat);
}
}
4.將影像透過AffineTransImageSize計算影像,並給影像新的長寬值
一樣當旋轉90、270度時,需要將長寬對調。
public static void ImgMirrorRotate(HObject hImage, out HObject hAffine, ImageFlip flip, ImageRotate rotate)
{
HTuple homMat, w, h;
HOperatorSet,GenEmptyObj(out hAffine);
try
{
HOperatorSet.GetImageSize(hImage, out w, out h);
//上面程式組合出來的轉換矩陣
GenHomMat2D(flip, rotate, w, h, out homMat);
hAffine.Dispose();
if ((int)rotate % 2 == 0)
{
HOperatorSet.AffineTransImageSize(hImage, out hAffine, homMat, "constant", w, h);
}
else
{
//如果轉90、270度,長寬對調
HOperatorSet.AffineTransImageSize(hImage, out hAffine, homMat, "constant", h, w);
}
}
}
以上為學習過程的問題紀錄
如果文章有誤,歡迎前輩留言請不吝指教。
發佈留言