机器视觉与图像处理
多功能和易用运动控制框架
支持图像模板深度学习

第六部分 高级功能类(专业版)

RVB提供机器视觉相关类为用户提供更高阶的应用。 目前这些类为c++类,适合visual c++开发环境。 高阶功能类三种。1. 视场图像显示和用户交互的类,显示相机采集的图像和有关的功能类,并提供交互功能如鼠标点击,键盘按键响应等; 2. 检测相关的类,; 3. 信息呈现相关的类。 检测相关的类和信息呈现相关的类都属于用户控件,有共同的基类CUCObj。

6.1视场相关类

视场相关的类有两个CWindowDelegate和CRealView。 前者主要对xgui的功能接口进行了封装,后者继承了前者,增加了消息处理功能。这两个类都是从CDelegate继承。它们的继承关系如下:

在一般的应用程序中,一般使用CRealView类,其它两个类很少被独立使用。

6.1.1 CWindowDelegate

CWindowDelegate主要封装xgui模块的功能,将绘制函数与具体的窗口中的绘制对象关联起来,实现和控制窗口的显示内容,显示方式如显示比例,背景颜色等等。该类通常的用法是作为窗口类的成员变量,在窗口初始化如PreSubclassWindow重载函数的时候,如要调用:

CWindowDelegate m_dgt;

m_dgt.Initialize(m_hWnd);

在初始化完成以后,可以设置显示模式,显示比例,如:

m_dgt.SetViewMode(CWindowDelegate:: VM_STRETCH);

然后设置其它显示内容输出:

m_dgt. SetBlankColor(GRGB(0,0,0));

m_dgt. SetRvbLogoVisible(FALSE);

使用完成以后,进行销毁:

m_dgt.Finalize();

当窗口进行显示的时候,如WM_PAINT消息里面,按照下面方式进行绘制:

m_dgt.Refresh(CWindowDelegate::RT_REALIZE);

如果要显示用户控件:

m_dgt.AddUC(pObj);

该用户控件就会被显示到窗口上。如果需要移除用户控件,直接调用RemoveUC或RemoveAll函数进行移除。当然别忘了直接或间接地使用Refresh(CDelegate::RT_REDRAW)对窗口显示进行刷新。

如果作为相机图像显示的类,应用程序可以一般需要使用下面的方式进行:

m_dgt.SetSightFormat(RIT_RGB, 320,240);

m_dgt. FeedFrame(image, TRUE);

前一条语句设置视场的格式,参数包括图像类型,图像宽度,图像高度。图像类型支持RIT_BIN,RIT_GRAY,RIT_RGB,RIT_RGBA。设置完成后,后一个函数可以将实时采集的图像不断地输入给该类进行显示。(注意 : FeedFrame的输入的图像格式必须与视场支持的格式严格相同,如宽度,高度等)。

同样,用户程序可以使用GetCurFrame来获得当前的帧图像。

CWindowDelegate提供函数可以将绘制结果直接输出到图像对象,类似WINDOWS系统的窗口拷贝。如:

m_dgt.SaveCanvas(image);

如果image可以为RIT_RGB或RIT_RGBA.

在不同的显示模式下面,可能视场的显示边界超出了窗口本身的显示区域,这样需要移动视场,来进行部分显示。方法如下:

GSize sze =m_dgt. GetScrollBarRange();

m_dgt. SetScrollBarPos(12, FALSE);

第1条语句获得水品和垂直方向的移动范围,后面的语句设置水平方向显示的当前左上角的显示位置。注意,该位置不能超出前一条语句返回的大小。

6.1.2 CRealView

CRealView类增强了窗口代理类,主要添加对WINDOWS消息的响应,提供强大的用户交互功能。该类从CWindowDelegate继承,所有CWindowDelegate的显示控制方法和函数通用使用该类。 在使用该类的实例之前,必须首先要创建窗口:

CRealView m_editor;

//执行模块里面

CRect rect;

GetDlgItem(IDC_STATIC_PREVIEW)->GetWindowRect(&rect);

ScreenToClient(&rect);

BOOL ret= m_editor.Create(m_hWnd, "my_ real_view", -1,-1, GRECT(rect.left, rect.top, rect.right, rect.bottom));

然后进行相关显示内容的调整,如调整RVB标识的显示位置,背景的风格,像素信息栏的颜色,用户鼠标的颜色等等:

m_editor.SetRvbLogoAlignment(CWindowDelegate::LA_RIGHTTOP);

m_editor.SetBackgroundStyle(CWindowDelegate::BS_WHITE);

m_editor.SetPixelBarColor(GRGB(255,0,0));

m_editor.SetUserCursorColor(GRGB(0,0,255));

如果需要隐藏RVB标识, 添加下的语句:

m_editor.SetRvbLogoVisible(FALSE);

上面的函数全部运行以后,调用下面的语句将绘制结果显示出来

m_editor.Refresh(CDelegate::RT_REDRAW);

注意:有些显示内容无法在设计状态下显示。

当使用完成以后,需要进行销毁

m_editor.Destroy();

CRealView有两种模式:设计模式和运行模式。两种模式的消息相应是不一样的。设计模式下,用户可以添加各种用户控件。可以拖动控件,改变位置或控件的大小。运行模式下,控件是锁定的。无法改变大小或位置。

下面的语句将编辑窗口的模式变为设计状态:

m_editor.SetDesignMode(CDelegate::DM_DESIGN);

CRealView提供了多种非标准鼠标,如目标指定鼠标,十字鼠标,甚至有支持窗口十字刻度。这些功能通过一个函数即可实现,如下:

m_editor.SetUserCursorType(CRealView::UC_PENTIP);

该语句将当前的用户鼠标设置成笔尖状鼠标。其它形状的鼠标对应的参数如下:

形状 参数 说明
忽略 UC_IGNORE 使用用户默认鼠标
笔尖 UC_PENTIP
圆形目标 UC_TAR_S
方形目标 UC_TAR_R
十字线 UC_CROSS
水平刻度 UC_RULER_H 固定将刻度线显示在窗口,鼠标为系统默认鼠标
垂直刻度 UC_RULER_V 固定将刻度线显示在窗口,鼠标为系统默认鼠标
十字刻度 UC_RULER_HV 固定将刻度线显示在窗口,鼠标为系统默认鼠标
用户自定义图像 UC_IMAGE

如果要改变默认的显示方式,用户可以重载Refresh函数,该函数在CWindowDelegate里面就存在。如下面的一段代码就改变了CRealView的默认显示方式:

if (IE_REPAIR == m_nType)

{

ClearCanvas();

if (m_bFeeded){

rvgPaintImage(m_dc, m_imCurFrame);

}

ASSERT(m_imRepair);

rvgDrawImage(m_dc, m_imRepair);

CWindowDelegate::Refresh(RT_REALIZE);

}

else{

CRealView::Refresh(type);

}

默认情况下,CRealView可以支持部分系统消息,支持内部功能的实现。为了响应不同的WINDOWS消息,提供灵活的控制手段,用户可以重载MsgProc函数。很多情况下,用户会从CRealView继承一个新类,然后重载MsgProc函数,实现灵活的消息响应。

除了WINDOWS消息,CRealView本身也会提供一些自定义的事件,用户可以重载EventProc来进行响应。

6.2检测相关类

检测相关类实现BLOB提取,模版匹配,条码识别等功能。检测相关类从CCaliber继承,一般情况下,一个类仅实现一个特定的视觉检测功能。检测相关类遵循创建和销毁模式,检测的时候一般调用通用接口Inspect函数,实现检测功能的运算。 更多信息请见附表4。

CAreaCal

面量规类为通用的一个类,该类不提供具体的视觉分析功能,仅仅表示一个ROI形状,如圆形,方形,半环形,通常作为基类存在。如改变一个实例的形状代码如下:

CAreaCal myCal ;

myCal .SetShape(CAreaCal:: CS_EX_CIRCLE);

需要获得实例对应的图象,如下:

RvImage im = myCal.GetImage();

注意该图象仅为一个指针,由类本身进行销毁。

作为辅助,面量规类提供了两个图象转换函数,即将图象从RVB转成灰度图或将灰度图转成二元图。这些转换分别有不同的转换方法。

CCurveCal

线量规为线状ROI,沿不同的曲线路径获取其像素,通常用于图象属性或特征分析。与面量规不同的是,线量规不提供格式转换或图象预处理。线量规根据曲线不同分为圆,弧,星状,同心圆等。

一些基本的形状特被用于加工视觉引导系统里面。

CBlobExtractor

该类为BLOB提取类,主要对二元图象中的不连接的块图象进行分离,然后可以获取独立的BLOB对象,进行特性分析。该类可以用于记数或开发更具体要求的功能类。

下面的代码演示了,一个实例从获取ROI图象,设置各种分离参数,然后进行分离并筛选的过程。

m_blobExtractor.Shot(m_image);

m_blobExtractor.m_nThresLower = m_nLower;

m_blobExtractor.m_nThresUpper = m_nUpper;

m_blobExtractor.m_bReverseBin = m_bInvert;

m_blobExtractor.m_bCutEdge = m_bCutEdge;

m_blobExtractor.m_bFillHole =m_bFillHoles;

m_blobExtractor.m_nEdgeSense = 5.8f;

m_blobExtractor.m_nMakeReal = CBlobExtractor::BE_MR_DFEL

m_blobExtractor.m_nMinBlobWidth =6;

m_blobExtractor.m_nMinBlobHeight =6;

m_blobExtractor.Segment();

m_blobExtractor.Select(m_nMinSize);

CPatternLocater

该类为模板定位类,即将事先学习的模板与ROI的图进行匹配,找出最佳位置。类实例在使用的需要先学习,然后进行识别。

CPatternLocater m_pd;

m_pd.Shot(m_image);

if (m_pd.Learn())

{

m_pd.DumpPatterns("temp");

}

m_pd.SetInitScore(m_nInitScore);

m_pd.SetMinScore(m_nMinScore);

m_pd.m_nDirect = m_nDirectIndex;

int n= m_pd.Recognize(m_image);

上面的代码演示了学习模板,并将模板图输出到temp目录下面,然后按照指定的识别方向进行定位。

CPixelMatch

该类使用相关性分析的方法,将模板图象与场景图象进行相关性分析,找出一个或多个模板实例。该类为通用的图象匹配类,支持旋转,缩放。

m_pm.m_nStartAngle = m_startAngle;

m_pm.m_nEndAngle =m_endAngle;

m_pm.SetAngleResolution( m_nAngleRes);

m_pm.SetScaleResolutionn(m_nScaleReso);

m_pm.SetMinScale( m_nMinScale);

m_pm.SetMaxScale (m_nMaxScale);

m_pm.SetMinScaleX ( m_nMinScaleX);

m_pm.SetMaxScaleX (m_nMaxScaleX);

m_pm.SetMinScaleY (m_nMinScaleY);

m_pm.SetMaxScaleY (m_nMaxScaleY);

m_pm.m_bAnisoScale = m_bAnisoScale;

m_pm.Shot(m_image);

if (m_pm.Learn())

{

m_pm.DumpPatterns("temp");

}

m_pm.SetMaxInitInstances(m_nMaxInitPositions);

m_pm.SetMaxInstances( m_nMaxPosition);

m_pm.SetInitScore(m_nInitScore);

m_pm.SetMinScore(m_nMinScore);

m_pm.m_nDirect = m_nDirectIndex;

int n= m_pm.Recognize(m_image);

if (n > 0)

{

ASSERT(n == m_pm.GetResultCount());

CString str;

m_strOutput.Format("找¨°到Ì?的Ì?数ºy量¢?:êo%d\r\n", n);

for (int i=0 ; i< n; i++)

{

str.Format("scale_x=%f, scale_y=%f, angle=%f, cx = %f, cy=%f, score=%f\r\n", \ m_pm.GetMatchResult(i)->scaleX, \ m_pm.GetMatchResult(i)->scaleY, \ m_pm.GetMatchResult(i)->angle, \ m_pm.GetMatchResult(i)->cx, \ m_pm.GetMatchResult(i)->cy, \ m_pm.GetMatchResult(i)->score );

m_strOutput += str;

}

}

上面的代码演示了学习模板,和实例查找的所有过程。 CDualDetect 该类从cpixelmatch类继承,进行双态的识别,如正反,左右,黑白等。在使用过程中,需要进行两次模板学习。识别完成以后,给出正反或缺失情况的结果。

m_dd.m_nStartAngle = 0;

m_dd.m_nEndAngle = 360;

m_dd.SetAngleResolution(3) ;

m_dd.Shot(m_image);

if (m_dd.LearnOne())

{

m_dd.DumpPatterns("temp");

}

CEasyOcr

该类提供一个简单的使用最近距离方法进行字符识别。与模板匹配一样,需要事先进行学习。该类可以识别多个字符。

在学习之前,需要将字符分隔出来。

m_easyOcr.SetPatternWidth( m_nPattWidth);

m_easyOcr.SetPatternHeight( m_nPattHeight);

m_easyOcr.m_nMaxCharWidth = m_nMaxWidth;

m_easyOcr.m_nMaxCharHeight = m_nMaxHeight;

m_easyOcr.m_nMinCharWidth = m_nMinWidth;

m_easyOcr.m_nMinCharHeight = m_nMinHeight;

m_easyOcr.m_nCharSpacing =m_nCharSpace;

m_easyOcr.m_bRemoveNarrowOrFlat = m_bRemoveSmall;

m_easyOcr.m_bKeepRawBlob = m_bUseRaw;

m_easyOcr.m_bCheckAnisoRatio = m_bCheckAnisoRatio;

if (m_nTextColorIndex == 0) m_easyOcr.m_nCharColor = CEasyOcr::EO_WHITE_ON_BLACK;

else m_easyOcr.m_nCharColor = CEasyOcr::EO_BLACK_ON_WHITE;

int n = m_easyOcr.Build();

然后,进行字符学习,每次学习一个字符,如:

m_easyOcr.Learn(m_nBlobIndex, -1, ‘A’);

学习完成以后,对新的视场图象里面的内容进行识别:

m_easyOcr.m_nMinScore =m_nScore;

m_easyOcr.Build();

int n = m_easyOcr.Recognize(-1);

char buff[2] ={0,0};

//CString tmp;

m_strResult.Empty();

for (int i=0; i< n; i++)

{

int ch = m_easyOcr.GetCharAt(i);

buff[0] =(char)ch;

m_strResult += buff;

}

CBarcode

条码读取类可以识别一维码和二维码。不需要事先学习,支持360度旋转,可以同时识别多个条码。 如:

m_barcode.Shot(m_image);

m_barcode.m_bRotation =TRUE;

m_barcode.m_nMinWidth = (RV_MIN( rviGetWidth(m_image), rviGetHeight(m_image))/ 8 -2);

m_barcode.m_nMinHeight = m_barcode.m_nMinWidth ;

m_barcode.Read2D();

m_strOutput = "";

for(int i=0; i< m_barcode.GetReadingCount(); i++)

{

const char* pTxtShow = m_barcode.GetReadingAt(i);

m_strOutput += pTxtShow;

m_strOutput +="\r\n";

}

上面的代码将图象中的二维条码识别出来。具体支持的条码类型请参考附表6。

检测相关的类目前大部分从CAreaCal类继承,该类也是从CCaliber继承。这个类主要实现产生不同形状的ROI,如果形状满足要求,新的功能类可以直接从该类继承产生,然后实现新的功能需求即可。

6.3信息呈现相关类

信息呈现类可以在视场窗口显示文字,图像等信息。信息呈现类从CIndicater继承,常用的类有CLabel, CPicture, CMark等。 在应用程序里面为用户提供更多的交互能力。使用方式与检测相关类一致,更多信息请见附表4。动态显示的信息呈现类需要调用Beat进行动态显示内容的切换。

下面的代码创建一个新的标签对象,并显示。

CLabel* pLabel = new CLabel;

ASSERT(pLabel);

ASSERT(pLabel);

int my_id = rand();

pLabel->Create((CDelegate*)&m_sight , "my_label", my_id,RV_UCS_ENABLE | RV_UCS_VISIBLE);

pLabel->SetURLText("www.kingpool.net");

pLabel->m_bActiveURL = TRUE;

m_sight.AddUC(pLabel);

m_sight.AddUC(pLabel);

m_sight.Refresh(CDelegate::RT_REDRAW);



抖音视频号: 第一感机器视觉
微信公众号: 精浦科技
深圳市软云动力科技有限公司
东莞办事处: 广东省东莞市松湖智谷B6栋225b
公司地址: 广东省深圳市南山区桃园路金桃园大厦2191

二维码1 二维码2 二维码3


深圳市软云动力科技有限公司 版权所有  鄂ICP备2022015826号-2   

统计显示 ▼