在常见的很多项目中,经常会使用手动绘制ROI的情况,但是实际产品的位置往往不是固定的,可能出现在视野上的各种地方和各种角度,所以就需要使用到旋转矫正。将产品放置在视野的中央,并且使得图像呈现出我们所需要的角度。
先预先定义一个固定的带角度的矩形ROI,角度为我们所需要修正的角度的方向,然后进行生成和创建模板,然后匹配模板,并将匹配成功的横纵坐标与角度进行图像旋转即可
#region // 模板匹配和旋转矫正(初始创建的ROI角度应该使用序列化参数进行保存)
///
/// 模板匹配和旋转矫正
///
/// 输入图像
/// 是否创建新模板
/// 输入矩形ROI的横坐标
/// 输入矩形ROI的列坐标
/// 输入矩形ROI的角度
/// 输入矩形ROI的一边长
/// 输入矩形ROI的一边宽
/// 输入模板存放的位置,文件后缀为.shm
/// 输出旋转后的图像
///
public static bool TemplateSpin(HObject image,bool NewTemplate,
HTuple Row,HTuple Column,HTuple Phi,HTuple Length1,HTuple Length2,string ModelAddress,
out HObject imageAffineTrans)
{
HOperatorSet.GenEmptyObj(out imageAffineTrans);
try
{
HTuple modelID = new HTuple();
if (NewTemplate)
{
Module.CreatTemplate(image, Row, Column, Phi, Length1,Length2, 0.8, 1.2, out modelID);
HOperatorSet.TupleLength(modelID, out HTuple length);
if (length==0)
{
return false;
}
HOperatorSet.WriteShapeModel(modelID, ModelAddress);
}
else
{
if (!System.IO.File.Exists(ModelAddress))
{
return false;
}
HOperatorSet.ReadShapeModel(ModelAddress, out modelID);
}
Module.FindTemplate(image, modelID, 0.3, out HTuple resultRow, out HTuple resultCloumn, out HTuple resultAngle, out HTuple resultScore);
HOperatorSet.TupleLength(resultRow, out HTuple length1);
if (length1==0)
{
return false;
}
HOperatorSet.GetImageSize(image, out HTuple width, out HTuple height);
HOperatorSet.VectorAngleToRigid(resultRow, resultCloumn, resultAngle+Phi, height/2, width/2 , 0, out HTuple homMat2D);
HOperatorSet.AffineTransImage(image, out imageAffineTrans, homMat2D, new HTuple("constant"), new HTuple("false"));
return true;
}
catch (Exception)
{
return false;
}
}
#endregion
#region // 模板匹配
///
/// 查找模板
///
/// 输入图像
/// 输入模板
/// 输入最小匹配分数
/// 输出匹配中心的横坐标
/// 输出匹配中心列坐标
/// 输出匹配模型角度
/// 输出匹配分数
/// 匹配成功返回true,匹配失败返回false
static public bool FindTemplate(HObject Image, HTuple ModelID, HTuple MinScore, out HTuple ResultRow, out HTuple ResultCloumn,
out HTuple ResultAngle, out HTuple ResultScore)
{
ResultRow = -1;
ResultCloumn = -1;
ResultAngle = -1;
ResultScore = -1;
try
{
HOperatorSet.GetShapeModelParams(ModelID, out HTuple numLevels, out HTuple angleStart, out HTuple angleExtent,
out HTuple angleStep, out HTuple scaleMin, out HTuple scaleMax, out HTuple scaleStep, out HTuple metric,
out HTuple minContrast);
HOperatorSet.FindScaledShapeModel(Image, ModelID, angleStart, angleExtent, scaleMin, scaleMax, MinScore, new HTuple(1),
new HTuple(0.5), new HTuple("least_squares"), numLevels, new HTuple(0.9), out ResultRow, out ResultCloumn,
out ResultAngle, out HTuple Scale, out ResultScore);
HOperatorSet.TupleLength(ResultScore,out HTuple length);
if (length > 0)
{
return true;
}
else { return false; }
}
catch (Exception ex)
{
return false;
}
}
///
/// 创建模板
///
/// 输入图像
/// 矩形中心横坐标
/// 矩形中心列坐标
/// 矩形ROI角度
/// 矩形一条边的长
/// 矩形另一条边的长
/// 模板最小缩放比例
/// 模板最大缩放比例
/// 输出模板
/// 创建成功返回true,创建失败返回false
static public bool CreatTemplate(HObject Image, HTuple Row, HTuple Column, HTuple Phi,
HTuple Length1, HTuple Length2, HTuple ScaledMin, HTuple SacledMax, out HTuple ModelID)
{
ModelID = -1;
try
{
HOperatorSet.GenRectangle2(out HObject ROI, Row, Column, Phi, Length1, Length2);
HOperatorSet.ReduceDomain(Image, ROI, out HObject imageReduced);
HOperatorSet.CreateScaledShapeModel(imageReduced, 8, (new HTuple(0)).TupleRad(), (new HTuple(360)).TupleRad(), new HTuple("auto"),
ScaledMin, SacledMax, new HTuple("auto"), new HTuple("none"), new HTuple("ignore_global_polarity"), new HTuple("auto"),
new HTuple("auto"), out ModelID);
HOperatorSet.TupleLength(ModelID, out HTuple length);
if (length==0)
{
return false;
}
return true;
}
catch (Exception ex)
{
return false;
}
}
#endregion
实际上模板匹配和旋转矫正时非常简单的事情。需要在旋转矫正时加上预先设定的ROI角度即可。