一.确定模型轮廓点的基准点
海康算子库的模型匹配例子中,随便绘制几个图形,点击generate pattern,在确认模型生成成功后点击display pattern会得到如下图所示的模型区域,在红笔圈中的区域中,黑色为mask区域,白色为绘制的ROI图形

在经过几次验证后,模型轮廓点的基准点既不是图像的原点,也不是该外切矩形的中心点,二十该外切矩形的左上角点(屏幕坐标系的原点在左上角)。
二.扇环外切矩形求解
矩形与多边形的外切矩形的求解并不复杂,在此不多赘述。
1.求解原理
扇环有四个角点,如下图所示

当扇环不跨象限时(扇环的起止角度均在同一象限内),扇环的外切矩形显然由这四个点确定。但当扇环跨象限时,四个角点并不能决定外切矩形,需要在四个角点及四个与扇环中心点同x(y)的点中确定外切矩形,如下图所示

2.C++实现
其中若干结构体和函数定义见文章“启智杯”模板匹配控件的扇形掩膜实现方式交流
void getPieBorderPoint(S_PIEINFO* pie, int& minx, int& maxx, int& miny, int& maxy) {
CPoint startVector(pie->data->anglePoint[0].x - pie->data->center.x, pie->data->anglePoint[0].y - pie->data->center.y);
double startAngle = getAngleToXPositive(startVector) * 180 / PI;
CPoint endVector(pie->data->anglePoint[2].x - pie->data->center.x, pie->data->anglePoint[2].y - pie->data->center.y);
double endAngle = getAngleToXPositive(endVector) * 180 / PI;
double angleRange = 0;
if (startAngle < endAngle) {
angleRange = 360 - (endAngle - startAngle);
}
else
angleRange = startAngle - endAngle;
double tempangle = endAngle + angleRange;
CPoint t_0_90_180_270[4] = { 0 };
for (int i = 0; i < 4; i++) {
t_0_90_180_270[i].SetPoint(pie->data->anglePoint[0].x, pie->data->anglePoint[0].y);
}
if (0 >= endAngle && 0 < tempangle || 360 >= endAngle && 360 < tempangle) {
t_0_90_180_270[0].SetPoint(pie->data->maxRectBoundary.right, pie->data->center.y);
}
if (90 >= endAngle && 90 < tempangle || 450 >= endAngle && 450 < tempangle) {
t_0_90_180_270[1].SetPoint(pie->data->center.x, pie->data->maxRectBoundary.bottom);
}
if (180 >= endAngle && 180 < tempangle || 540 >= endAngle && 540 < tempangle) {
t_0_90_180_270[2].SetPoint(pie->data->maxRectBoundary.left, pie->data->center.y);
}
if (270 >= endAngle && 270 < tempangle || 630 >= endAngle && 630 < tempangle) {
t_0_90_180_270[3].SetPoint(pie->data->center.x, pie->data->maxRectBoundary.top);
}
int tminx = 9999, tmaxx = -1, tminy = 9999, tmaxy = -1;
for (int i = 0; i < 4; i++) {
if (pie->data->anglePoint[i].x < tminx)
tminx = pie->data->anglePoint[i].x;
else if (pie->data->anglePoint[i].x > tmaxx)
tmaxx = pie->data->anglePoint[i].x;
if (pie->data->anglePoint[i].y < tminy)
tminy = pie->data->anglePoint[i].y;
else if (pie->data->anglePoint[i].y > tmaxy)
tmaxy = pie->data->anglePoint[i].y;
if (t_0_90_180_270[i].x < tminx)
tminx = t_0_90_180_270[i].x;
else if (t_0_90_180_270[i].x > tmaxx)
tmaxx = t_0_90_180_270[i].x;
if (t_0_90_180_270[i].y < tminy)
tminy = t_0_90_180_270[i].y;
else if (t_0_90_180_270[i].y > tmaxy)
tmaxy = t_0_90_180_270[i].y;
}
minx = tminx;
miny = tminy;
maxx = tmaxx;
maxy = tmaxy;
}
3.验证



模型轮廓点均显示无误,且生成的模型文件能被visionmaster成功匹配
三.结语
感谢您抽出宝贵的时间阅读本篇文章。本文可能存在许多表述不明、表述有误的地方,欢迎大家批评指正。