11.MIL中测量模块(Measurement)

上节说过灰度匹配的鲁棒性太差,在定位一些特殊的简单特征时,使用单方向的灰度跳变特征(和边缘检测类似)来定位的鲁棒性较好,速度快。你可以定位指定的点、边、条纹三种特征,定位的两个特征的间距即为长度、宽度等特征,所以这个模块叫做测量模块。


1.测量流程


(1).分配指定的特征Marker

使用MmeasAllocMarker函数来设置指定的特征,MIL支持三种特征:点(M_POINT),边(M_EDGE),条纹(M_STRIPE)

后两种特征如下:

11.MIL中测量模块(Measurement)_第1张图片          11.MIL中测量模块(Measurement)_第2张图片

(2).选取Marker

选取Marker的过程实际上是指定包含Marker一个矩形范围及包含的Marker个数(M_NUMBER)。可以看到这几种特征都是单方向的灰度跳变,所以在设置Marker位置的时候必须包含有跳变。

矩形范围包括起始点(M_BOX_ORIGIN)、大小(M_BOX_SIZE)、角度(M_BOX_ANGLE)。

角度和前面讲的灰度匹配、几何匹配一样可以开启范围匹配(M_BOX_ANGLE_MODE),设置角度范围(M_BOX_ANGLE_DELTA_POS、M_BOX_ANGLE_DELTA_NEG,0~180),设置角度误差允许值(M_BOX_ANGLE_TOLERANCE),设置多角度插补模式(M_BOX_ANGLE_INTERPOLATION_MODE)和角度精度(M_BOX_ANGLE_ACCURANCY)。

(3).设置Marker参数

使用MmeasSetMarker设置相关参数

设置搜索方向

使用参数M_ORIENTATION,可为水平或竖直或任意

设置其他值

不同的Marker对象特征需要设置的值不同,主要有宽度、高度、位置、角度等,具体参见手册

(4).测量得到各种测量值

使用MmeasFindMarker开启测量,使用MmeasGetResult得到各种测量结果。

可使用MmeasDraw绘制测量结果


2.测量实例


还是采用MIL自带的例程修改而来,包括简单测量和多目标测量。前者指定的匹配范围内有一个旋转后的Stripe,获得它的位置、宽度和角度,后者指定的匹配范围内有若干个Stripe(电路板引脚),获得他们的平均位置、平均宽度和平均角度。

(1).简单测量

测量图像如下
11.MIL中测量模块(Measurement)_第3张图片

void CMeasureDlg::OnReadSingle() 
{
	// TODO: Add your control notification handler code here
	if (M_NULL != m_milSingleBuf)
	{
		MbufFree(m_milSingleBuf);
		m_milSingleBuf = M_NULL;
	}

	//导入图像
	MbufRestore(TEXT(".\\Image\\Lead.mim"), m_milSystem, &m_milSingleBuf);
	
	//显示图像
	MdispZoom(m_milDisplay, 0.8, 0.8);
	MdispControl(m_milDisplay,  M_CENTER_DISPLAY , M_ENABLE);
	MdispSelectWindow(m_milDisplay, m_milSingleBuf, GetDlgItem(IDP_DISP_IMAGE)->GetSafeHwnd());

	MdispControl(m_milDisplay, M_OVERLAY_CLEAR, M_DEFAULT);
}

void CMeasureDlg::OnSetSingle() 
{
	// TODO: Add your control notification handler code here
	if (M_NULL != m_milSingleMarker)
	{
		MmeasFree(m_milSingleMarker);
		m_milSingleMarker = M_NULL;
	}

	//分配Stripe Maker
	MmeasAllocMarker(m_milSystem, M_STRIPE, M_DEFAULT, &m_milSingleMarker);

	//设置Maker Box
	MmeasSetMarker(m_milSingleMarker, M_BOX_ORIGIN, MEAS_BOX_POS_X, MEAS_BOX_POS_Y);
    MmeasSetMarker(m_milSingleMarker, M_BOX_SIZE,   MEAS_BOX_WIDTH, MEAS_BOX_HEIGHT);

	//设置Maker Characteristics
	MmeasSetMarker(m_milSingleMarker, M_POLARITY, STRIPE_POLARITY_LEFT, STRIPE_POLARITY_RIGHT);//第一边缘为上升沿,第二边缘为下降沿
	MmeasSetMarker(m_milSingleMarker, M_WIDTH, STRIPE_WIDTH, M_NULL);//宽度
	MmeasSetMarker(m_milSingleMarker, M_WIDTH_VARIATION, STRIPE_WIDTH_VARIATION, M_NULL);//宽度偏差
	MmeasSetMarker(m_milSingleMarker, M_BOX_ANGLE_MODE, M_ENABLE, M_NULL);//角度可变(360)

	//在图像的Overlay层上绘制Maker Box
	MdispControl(m_milDisplay, M_OVERLAY, M_ENABLE);
	MdispInquire(m_milDisplay, M_OVERLAY_ID, &m_milSingleOverlayBuf);
	MdispControl(m_milDisplay, M_OVERLAY_CLEAR, M_DEFAULT);

	MgraColor(M_DEFAULT, M_COLOR_RED);
	MmeasDraw(M_DEFAULT, m_milSingleMarker, m_milSingleOverlayBuf, M_DRAW_BOX, M_DEFAULT, M_MARKER);
}

void CMeasureDlg::OnGetSingle() 
{
	// TODO: Add your control notification handler code here
	
	//目标图像中寻找Maker,测量结果保存在Maker中
	MmeasFindMarker(M_DEFAULT, m_milSingleBuf, m_milSingleMarker, M_DEFAULT);
	
	//获得测量结果(位置、宽度、角度)
	double  StripeCenterX,                /* Stripe X center position.*/
			StripeCenterY,                /* Stripe Y center position.*/
			StripeWidth,                  /* Stripe width.            */
			StripeAngle;                  /* Stripe angle.            */
	MmeasGetResult(m_milSingleMarker, M_POSITION, &StripeCenterX, &StripeCenterY);
	MmeasGetResult(m_milSingleMarker, M_WIDTH,    &StripeWidth, M_NULL);
	MmeasGetResult(m_milSingleMarker, M_ANGLE,    &StripeAngle, M_NULL);
	
	//绘制 Maker Box
	MgraColor(M_DEFAULT, M_COLOR_BLACK);
	MdispControl(m_milDisplay, M_OVERLAY_CLEAR, M_DEFAULT);//清除显示OverLay层
	MmeasDraw(M_DEFAULT, m_milSingleMarker, m_milSingleOverlayBuf, M_DRAW_BOX, M_DEFAULT, M_RESULT);
	
	//绘制测量结果
	MgraColor(M_DEFAULT, M_COLOR_YELLOW);
	MmeasDraw(M_DEFAULT, m_milSingleMarker, m_milSingleOverlayBuf, M_DRAW_POSITION, M_DEFAULT, M_RESULT);//绘制中间点
	MmeasDraw(M_DEFAULT, m_milSingleMarker, m_milSingleOverlayBuf, 
			  M_DRAW_POSITION+M_EDGE_FIRST+M_EDGE_SECOND, M_DEFAULT, M_RESULT);//绘制第一边缘和第二边缘点

	CString csResult;
	csResult.Format(TEXT("目标图像中Stripe的位置为(%.2f,%.2f)\n宽度为%.2f\n角度为%.2f\n"),
					StripeCenterX, StripeCenterY,
					StripeWidth,
					StripeAngle);
	MessageBox(csResult, TEXT("测量结果"));
}

(2).多角度测量

测量图像如下


void CMeasureDlg::OnReadMulti() 
{
	// TODO: Add your control notification handler code here
	if (M_NULL != m_milMultiBuf)
	{
		MbufFree(m_milMultiBuf);
		m_milMultiBuf = M_NULL;
	}
	
	//导入图像
	MbufRestore(TEXT(".\\Image\\chip.mim"), m_milSystem, &m_milMultiBuf);
	
	//显示图像
	MdispZoom(m_milDisplay, 0.8, 0.8);
	MdispControl(m_milDisplay,  M_CENTER_DISPLAY , M_ENABLE);
	MdispSelectWindow(m_milDisplay, m_milMultiBuf, GetDlgItem(IDP_DISP_IMAGE)->GetSafeHwnd());
	
	MdispControl(m_milDisplay, M_OVERLAY_CLEAR, M_DEFAULT);
}

void CMeasureDlg::OnSetMulti() 
{
	// TODO: Add your control notification handler code here
	if (M_NULL != m_milMultiMarker)
	{
		MmeasFree(m_milMultiMarker);
		m_milMultiMarker = M_NULL;
	}

	//分配Stripe Maker
	MmeasAllocMarker(m_milSystem, M_STRIPE, M_DEFAULT, &m_milMultiMarker);
	
	//设置Maker Box
	MmeasSetMarker(m_milMultiMarker, M_BOX_ORIGIN, MULT_MEAS_BOX_POS_X, MULT_MEAS_BOX_POS_Y);
	MmeasSetMarker(m_milMultiMarker, M_BOX_SIZE,   MULT_MEAS_BOX_WIDTH, MULT_MEAS_BOX_HEIGHT);
	
	//设置Maker Characteristics
	MmeasSetMarker(m_milMultiMarker, M_NUMBER, MULT_STRIPES_NUMBER, M_NULL);//个数
	MmeasSetMarker(m_milMultiMarker, M_POLARITY, MULT_STRIPES_POLARITY_LEFT, 
				   MULT_STRIPES_POLARITY_RIGHT);//第一边缘为上升沿,第二边缘为下降沿
	MmeasSetMarker(m_milMultiMarker, M_ORIENTATION, MULT_STRIPES_ORIENTATION, M_NULL);//竖直方向
	
	//在图像的Overlay层上绘制Maker Box
	MdispControl(m_milDisplay, M_OVERLAY, M_ENABLE);
	MdispInquire(m_milDisplay, M_OVERLAY_ID, &m_milMultiOverlayBuf);
	MdispControl(m_milDisplay, M_OVERLAY_CLEAR, M_DEFAULT);
	
	MgraColor(M_DEFAULT, M_COLOR_RED);
	MmeasDraw(M_DEFAULT, m_milMultiMarker, m_milMultiOverlayBuf, M_DRAW_BOX, M_DEFAULT, M_MARKER);
}

void CMeasureDlg::OnGetMulti() 
{
	// TODO: Add your control notification handler code here
	//目标图像中寻找Maker,测量结果保存在Maker中
	MmeasFindMarker(M_DEFAULT, m_milMultiBuf, m_milMultiMarker, M_POSITION + M_ANGLE + M_WIDTH);
	
	//获得测量结果(位置、宽度、角度)
	double  MeanAngle,                   /* Stripe mean angle.        */
			MeanWidth,                   /* Stripe mean width.        */
			MeanSpacing;                 /* Stripe mean spacing.      */
	MmeasGetResult(m_milMultiMarker, M_ANGLE +   M_MEAN, &MeanAngle,   M_NULL);
	MmeasGetResult(m_milMultiMarker, M_WIDTH +   M_MEAN, &MeanWidth,   M_NULL);
	MmeasGetResult(m_milMultiMarker, M_SPACING + M_MEAN, &MeanSpacing, M_NULL);

	//绘制 Maker Box
	MgraColor(M_DEFAULT, M_COLOR_BLACK);
	MdispControl(m_milDisplay, M_OVERLAY_CLEAR, M_DEFAULT);//清除显示OverLay层
	MmeasDraw(M_DEFAULT, m_milMultiMarker, m_milMultiOverlayBuf, M_DRAW_BOX, M_DEFAULT, M_RESULT);
	
	//绘制测量结果
	MgraColor(M_DEFAULT, M_COLOR_YELLOW);
	MmeasDraw(M_DEFAULT, m_milMultiMarker, m_milMultiOverlayBuf, M_DRAW_POSITION, M_ALL, M_RESULT);//Stripe 位置

	CString csResult;
	csResult.Format(TEXT("目标图像中Stripe的平均角度为%5.2f\n平均宽度为%5.2f\n平均间隔为%5.2f\n"),
					MeanAngle,
					MeanWidth,
					MeanSpacing);
	MessageBox(csResult, TEXT("测量结果"));
}

完整测试程序 下载链接
原创,转载请注明来自 http://blog.csdn.net/wenzhou1219

你可能感兴趣的:(图像处理,MIL,Mmeas,测量模块)