Halcon和VisionMaster还有Opencv中旋转矩形的处理
一、Halcon中旋转矩形定义和画旋转矩形
Halcon中使用gen_rectangle2 (Rect5, 10, 10, 0, 2.1, 2.1)生成旋转矩形,
二、VisionMaster中旋转矩形和画旋转矩形
三、Opencv中旋转矩形与System.Drawing.Rectangle转换
四、用OpencvSharp,提取大图中的旋转矩形,并转为0度图像的函数
/// <summary>
/// 裁剪旋转ROI图像
/// 从原始的图像中,将旋转矩形区域裁剪后,反向旋转正后的图像。
/// </summary>
/// <param name="theSrcMat"></param>
/// <param name="theSrcRoiRotaRect"></param>
/// <param name="theDstMat"></param>
/// <returns></returns>
bool CutRotaRectImage(Mat theSrcMat, FHRotaRect theSrcRoiRotaRect, ref Mat theDstMat)
{
//参数检查
if (theSrcMat == null) {
return false;
}
//是否包含
System.Drawing.Rectangle bigRect = new System.Drawing.Rectangle(0,0, theSrcMat.Width, theSrcMat.Height);
if (false == theSrcRoiRotaRect.IsInBigRect(bigRect)) {
return false;
}
if (theSrcRoiRotaRect.Angle == 0 || theSrcRoiRotaRect.Angle == -360 || theSrcRoiRotaRect.Angle == 360) {
//0度处理
OpenCvSharp.Rect roiRect = new OpenCvSharp.Rect((int)Math.Floor(theSrcRoiRotaRect.CentX - (theSrcRoiRotaRect.W - 1) / 2.0),
(int)Math.Floor(theSrcRoiRotaRect.CentY - (theSrcRoiRotaRect.H - 1) / 2.0),
(int)Math.Ceiling(theSrcRoiRotaRect.W),
(int)Math.Ceiling(theSrcRoiRotaRect.H));
if (theDstMat == null ||
theDstMat.Size() != roiRect.Size ||
theDstMat.Type() != theDstMat.Type()) {
theDstMat = new Mat(roiRect.Size, theSrcMat.Type());
}
Mat tempRoiMat = new Mat(theSrcMat, roiRect);
tempRoiMat.CopyTo(theDstMat);
} else if (theSrcRoiRotaRect.Angle == -180 || theSrcRoiRotaRect.Angle == 180) {
//±180度处理
OpenCvSharp.Rect roiRect = new OpenCvSharp.Rect((int)Math.Floor(theSrcRoiRotaRect.CentX - (theSrcRoiRotaRect.W - 1) / 2.0),
(int)Math.Floor(theSrcRoiRotaRect.CentY - (theSrcRoiRotaRect.H - 1) / 2.0),
(int)Math.Ceiling(theSrcRoiRotaRect.W),
(int)Math.Ceiling(theSrcRoiRotaRect.H));
if (theDstMat == null ||
theDstMat.Size() != roiRect.Size ||
theDstMat.Type() != theDstMat.Type()) {
theDstMat = new Mat(roiRect.Size, theSrcMat.Type());
}
Mat tempRoiMat = new Mat(theSrcMat, roiRect);
theDstMat = tempRoiMat.Flip(FlipMode.X);
} else {
//其它角度处理
//a.外接正矩形
System.Drawing.Rectangle srcRoiRect = theSrcRoiRotaRect.BoundingRect();
srcRoiRect = System.Drawing.Rectangle.Intersect(srcRoiRect, new System.Drawing.Rectangle(0, 0, theSrcMat.Width, theSrcMat.Height));
Mat srcRoiMat = new Mat(theSrcMat, new OpenCvSharp.Rect(srcRoiRect.X, srcRoiRect.Y, srcRoiRect.Width, srcRoiRect.Height));
OpenCvSharp.Size dstSz = new OpenCvSharp.Size((int)Math.Ceiling(theSrcRoiRotaRect.W),
(int)Math.Ceiling(theSrcRoiRotaRect.H));
//b.求旋转矩阵
Mat rotaMat = Cv2.GetRotationMatrix2D(new Point2f((float)((srcRoiRect.Width-1) / 2.0),
(float)((srcRoiRect.Height-1) / 2.0)),
theSrcRoiRotaRect.Angle,
1);
//针对偏移,修改工A02,A12
double a02 = rotaMat.Get<double>(0, 2);
double a12 = rotaMat.Get<double>(1, 2);
double pianyiX = (dstSz.Width - 1) / 2.0 - (srcRoiRect.Width - 1) / 2.0;
double pianyiY = (dstSz.Height - 1) / 2.0 - (srcRoiRect.Height - 1) / 2.0;
rotaMat.Set(0, 2, a02 + pianyiX);
rotaMat.Set(1, 2, a12 + pianyiY);
//c.旋转图像
if (theDstMat == null ||
theDstMat.Size() != dstSz ||
theDstMat.Type() != theDstMat.Type()) {
theDstMat = new Mat(dstSz, theSrcMat.Type());
}
theDstMat.SetTo(new Scalar(0, 0, 0));
Cv2.WarpAffine(srcRoiMat, theDstMat, rotaMat, theDstMat.Size(), InterpolationFlags.Linear, BorderTypes.Replicate);
mBindPara.CombinShow2 = new FengHua.ShowCtrl2.ShowImgPara(srcRoiMat);
}
return true;
}