机器视觉运动控制一体机应用例程(三) 基于BLOB分析的多圆定位

供稿:深圳市正运动技术有限公司

  • 关键词:正运动技术,机器视觉,运动控制一体机
  • 摘要:​我们在《VPLC系列机器视觉运动控制一体机快速入门(三)》的推文中,讲述了基于形状匹配的视觉定位功能,而BLOB斑点分析也可以实现定位功能。

image.png


我们在《VPLC系列机器视觉运动控制一体机快速入门(三)》的推文中,讲述了基于形状匹配的视觉定位功能,而BLOB斑点分析也可以实现定位功能。


本期课程我们将在BLOB斑点分析定位的基础上进行检测圆形,输出圆心的坐标数据。


一检测原理


(一)BLOB斑点定位


BLOB斑点分析功能可以输出BLOB区域的重心位置XY,BLOB斑点区域还可以拟合成特定形状如外接矩形,输出矩形的角度,从而实现定位的功能。


(二)BLOB分析的圆形检测+示意图


圆形测量器不具有定位功能,因此当检测目标在视野的位置是随机时,我们需要配合定位功能将测量器跟随目标移动。本节程序示例将检测到的BLOB重心XY数据作为圆形测量器的中心XY值,即可实现位置跟随功能。


image.png


二软件演示


(一)检测要求


使用ZDevelop软件的ZBASIC编程语言编写程序,用于检测以下路径中图片的圆环零件的圆心位置XY以及半径。 


使用到的视觉功能:BLOB斑点分析+检测圆形+九点标定。


image.png


(二)实例演示


1.打开ZDevelop软件:新建项目→新建HMI文件→新建main.bas文件,用于编写界面响应函数→新建global_variable.bas文件用于定义全局变量并开启HMI自动运行任务→新建detectParam.bas文件,用于初始化测量参数→新建camera.bas文件用于实现相机采集功能→文件添加到项目。


image.png


2.设计HMI界面。


image.png


3.在global_variable.bas文件中添加全局变量。


'''''全局变量大部分使用数组结构'''''

''注:basic编程中很多函数会以TABLE(系统的数据结构)做为参数

''table        说明                 table            说明

''0  '    自动二值化阈值            11~12   鼠标操作时获取的坐标

''2       亮区域的面积            20~24   图像信息

''4       暗区域的面积            6       连通区域的数量   

''40~42  小圆斑点的面积和位置X,Y数据  81~98  标定图像坐标xy       

''46~48  小圆圆心X,Y和半径          131~148  标定世界坐标xy

''39     提取mark点成功标志          56~57  圆点矩阵行列数

''49~50  圆上的点坐标

'主任务状态

'0 - 未初始化

'1 - 停止

'2 - 运行中

'3 - 正在停止

GLOBAL DIM main_task_state

main_task_state = 1


'采集开关

'0 - 停止采集

'1 - 请求采集

GLOBAL DIM grab_switch

grab_switch = 0


'相机个数

GLOBAL cam_num

cam_num = 0


'相机种类,"zmotion;mvision;basler;mindvision;huaray"

GLOBAL DIM CAMERA_TYPE(16)

CAMERA_TYPE = "mvision"


' 定义主任务id - 10

GLOBAL DIM main_task_id

main_task_id = 10


'定义连续采集任务id - 9

GLOBAL DIM grab_task_id

grab_task_id = 9


'定义全局图像变量

GLOBAL ZVOBJECT grabImg '采集图像

GLOBAL ZVOBJECT binImg '二值化图像

GLOBAL ZVOBJECT disImg '显示图像


'定义常用颜色变量

GLOBAL C_RED, C_GREEN, C_BLUE, C_YELLOW

C_RED   = RGB(255,  0,  0)

C_GREEN = RGB(  0,255,  0)

C_BLUE  = RGB(  0,  0,255)

C_YELLOW= RGB(255,255,  0)


'检测参数:阈值模式(自动阈值或手动阈值)、低阈值、高阈值、最小面积、最大面积

GLOBAL DIM d_detect_param(5) 'd开头表示数据结构


'开/闭运算参数

GLOBal DIM d_deal_value(2)


'检测消耗时间

GLOBal DIM d_detect_time


'小圆的位置x/y结果

GLOBal DIM d_circle_rst(18)


'显示打印的字符

GLOBAL ShowString(64)


'***********定义坐标标定相关变量*********************

'是否标定

GLOBAL DIM is_ca_success


'定义标定成功标志,0-标定未成功,1-标定成功

GLOBAL DIM d_calib_success

d_calib_success = 0


'定义标定系数即矩阵转换系数

GLOBAL ZVOBJECT ca_param


'定义标定参数数组,依次为:标定类型、对比度、极性、最小面积、最大面积、世界坐标点间距

GLOBAL DIM d_ca_param(6) 'd开头表示数据结构


'定义是否使用标定功能

GLOBAL DIM d_use_calib

d_use_calib=0


'定义标定误差,依次为最小误差、最大误差、平均误差

GLOBAL DIM ca_min_err,ca_max_err,ca_avg_err

ca_min_err = 0

ca_max_err = 0

ca_avg_err = 0


'***********定义读取本地文件功能相关变量**************

''注意,该功能只在使用仿真器时有效

'定义是否使用本地图片标志

GLOBAL DIM d_use_imgfile


'定义本地图片索引

GLOBAL DIM d_index


'定义读取图片的路径

GLOBAL DIM File_Name(100)   


'***********结束定义读取本地文件功能相关变量**********


'运行HMI文件

RUN "Hmi.hmi",1

4.关联HMI界面控件变量。


image.png


5.在detectParam.bas文件中初始化测量参数。


end


GLOBAL SUB init_detect_param()    '初始化测量参数

  

    d_deal_value(0)=1          '初始化开/闭运算参数

    d_deal_value(1)=1

    

    '初始化检测参数:阈值模式(自动阈值 = 1 或 手动阈值 = 0)、低阈值、高阈值、极性(黑或白)、最大、最小、反向(即结果取反,成功变成失败、失败变成成功)

    d_detect_param(0) = 0      '手动阈值

    d_detect_param(1) = 140    '低阈值

    d_detect_param(2) = 255     '高阈值

    d_detect_param(3) = 11000    '最小面积即像素个数

    d_detect_param(4) = 12000    '最大面积

  

    d_use_imgfile = 1           '默认使用本地图片

    d_index      = 0

    

    TABLE(6)=0   '将小圆数量初始化为0

    for i=0 to 17

        d_circle_rst(i)=0

    next

    '初始化坐标标定相关的变量

    d_ca_param(0) = 0    '标定类型

    d_ca_param(1) = 120    '对比度

    d_ca_param(2) = 0    '极性

    d_ca_param(3) = 80    '最小面积

    d_ca_param(4) = 20000  '最大面积

    d_ca_param(5) = 9       '世界坐标点间距

    ca_min_err = 0      '最小误差

    ca_max_err = 0      '最大误差

    ca_avg_err = 0      '平均误差

    

    for i=0 to 17           '初始化圆点矩阵像素坐标    

        TABLE(81+i)=0

    next

    

    for i=0 to 17           '初始化圆点矩阵世界坐标    

        TABLE(131+i)=0

    next

    TABLE(39)=0             '提取mark点状态默认为失败 

    

END SUB

6.在main.bas文件中添加界面初始化函数,并在hmi系统设置中关联初始化函数名。


end


'注:

'凡是要使用Region有关的算子在系统初始化时都要调用ZV_RESETCLIPSIZE(width, height)这个算子设置下图像尺寸,以满足相机分辨率,因为默认的是640*480尺寸


'HMI界面初始化函数

GLOBAL SUB hmi_init()

    grab_switch = 0              '停止采集

    main_task_state = 1          '主任务停止运行

    ZV_RESETCLIPSIZE(1280, 960) '依据图像分辨率设置区域的裁剪尺寸,此处图像分辨率为1280x960

    ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(10, 7), HMI_CONTROLSIZEY(10, 7)) '设置锁存的大小

    init_detect_param()        '初始化测量参数

    ZV_SETSYSDBL("CamGetTimeout", 1000) '设置采集超时

    ZV_SETSYSINT("LineWidth",6)

    ZV_LATCHCLEAR(0)           '清空锁存通道0

    

END SUB

image.png


7.在camera.bas文件中添加HMI运行界面中采集相关按钮响应的函数并关联动作函数。


图片


相机操作相关按钮


end


'主界面按下扫描相机按钮时响应的函数

GLOBAL SUB cam_scan_all()


    if(d_use_imgfile=1)then 

        ?"请先按下使用本地图片按钮关闭该功能"

    return 

    endif 

  

    ZV_SETSYSINT("LogLevel", 7)     '设置控制器信息

    ZV_SETSYSSTR("DataDir","")

      

    CAM_SCAN(CAMERA_TYPE)           '扫描相机,CAMERA_TYPE="mvision"

    cam_num = CAM_COUNT()           '获取扫描到的相机数量

    if (0 = cam_num) then           '如果相机数量=0,打印提示信息

         ? "未找到相机" 

        

    return                       '退出子函数,不往下执行

    endif

    ?"cam_num = " cam_num            '如果扫描到相机,打印相机数量

  

    CAM_SEL(0)                       '选择扫描到的第一个相机进行操作

    CAM_SETEXPOSURE(5000)           '设置相机曝光时间为5000us      

    CAM_SETMODE(0)                   '设置软件触发模式

    CAM_START(0)                     '开启相机  

  

END SUB


'主界面按下单次采集按钮执行的函数

GLOBAL SUB btn_grab()


    ''如果d_use_imgfile=1时使用读取本地图片功能,该功能只在使用仿真器时有效,使用控制器时请将此部分代码注释掉

    if (d_use_imgfile=1) then 

        if(d_index=3) then 

             d_index=0

        endif

        File_Name="\圆定位\"+TOSTR(d_index,1,0)+".bmp"   '.../flash/圆定位/目录下的图片所在的路径名称

        ZV_IMGREAD(grabImg,File_Name,0)

        ZV_LATCH(grabImg, 0) 

        d_index=d_index+1

    return   

    endif

    ''读取本地图片功能结束

  

    if cam_num = 0   then 

        ?"请先扫描相机!"

    return 

    endif

  

    CAM_SETPARAM("TriggerSoftware", 0)  '发送触发指令

    CAM_GET(grabImg, 0)                 '获取一帧图像存放到grabImg变量中

    ZV_LATCH(grabImg, 0)                '将图像显示到锁存通道0中

    

END SUB


'主界面按下连续采集按钮响应的函数

GLOBAL SUB btn_cgrab()

    if grab_switch =1 then                 '如果已经处于连续执行状态,打印提示信息并退出函数

       ?"正在连续运行中,请勿重复操作!"

     return 

    endif

  

    if( d_use_imgfile =0) then 

        if cam_num = 0   then                  '如果相机数量=0,打印提示信息并退出函数        

             ?"请先扫描相机!"

        return 

        endif

    endif

  

    grab_switch = 1                         '采集任务开关置1

       if (1 = grab_switch) then

            if (0 = PROC_STATUS(grab_task_id)) then

                 RUNTASK  grab_task_id, grab_task    '开启连续采集任务

            endif

       endif

  

END SUB


'采集任务实现函数

grab_task:

    while(1)

        if (0 = grab_switch) then        '如果采集任务开关=0即停止采集按钮按下时

            exit while                   '退出循环

        endif

          

        '重复执行以下操作

        btn_grab()

    wend

END


'主界面按下停止采集按钮响应的函数

GLOBAL SUB btn_stopCgrab()

    if grab_switch =0 then               '如果已经处于停止采集状态,打印提示信息并退出函数

       ?"未开启连续采集!"

    return 

    endif

  

    grab_switch = 0                       '将采集任务开关置0

    

END SUB

8.点击“元件”→“新建窗口”,新建标定界面窗口,并将《VPLC系列机器视觉运动控制一体机快速入门(六)》中的标定程序的界面拷贝到新建的窗口界面。


image.png


9.在main.bas文件中添加运行界面按下【标定】按钮时的响应函数,以及标定窗口界面按下【提取mark点】按钮、【标定】按钮以及【返回】按钮时响应的函数,可参考《VPLC系列机器视觉运动控制一体机快速入门(六)》中的标定程序。


'点击运行界面按下标定按钮时响应的函数

GLOBAL SUB btn_calib()

    '设置坐标标定窗口锁存通道0的锁存大小

    ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(11, 91), HMI_CONTROLSIZEY(11, 91)) 

    if (d_use_imgfile=1) then   '如果使用本地图片功能

    ZV_IMGREAD(grabImg,"\圆定位\calib.bmp",0)  '加载标定图片

    endif

    ZV_LATCHCLEAR(0)           '将锁存通道0清空

    ZV_LATCH(grabImg, 0)       '显示采集图像显示到锁存通道0中

    HMI_SHOWWINDOW(11)         '弹出窗口号为11的坐标标定窗口界面

   

END SUB


'坐标标定界面按下提取mark点按钮时响应的函数

GLOBAL SUB btn_ca_extract()

    for i=0 to 17           '初始化圆点矩阵像素坐标    

       TABLE(81+i)=0

    next

  

    for i=0 to 17           '初始化圆点矩阵世界坐标    

       TABLE(131+i)=0

    next

    TABLE(39)=0             '提取mark点状态默认为失败

    ZVOBJECT inppts, ppts, wpts

    

    '根据提取像素参数提取像素坐标,存放到inppts矩阵中

    ZV_CALGETSCAPTS(grabImg, inppts, d_ca_param(1), d_ca_param(2), d_ca_param(3), d_ca_param(4))

    '获取矩阵inppts中的数据信息,存放到table(56)中

    ZV_MATINFO (inppts, 56)

    

    DIM row,col

    row = TABLE(56)   '矩阵行数赋值给row变量

    col = TABLE(57)   '矩阵列数赋值给col变量

    if(row * col = 18) then '如果获取到9个圆点的圆心位置坐标x,y   

        TABLE(39) = 1 '窗口界面提示提取mark点成功

    else

        TABLE(39) = 0 '窗口界面提示提取mark点失败

    return         '返回子函数,不往下执行

    endif

    

    '根据mrak点间距和像素坐标计算世界坐标,存放到wpts矩阵

    ZV_CALGETPTSMAP(inppts,ppts,wpts,d_ca_param(5))

    '获取矩阵ppts中的数据信息,存放到table(56)中

    ZV_MATINFO (ppts, 56)

    

    row = TABLE(56)  '矩阵行数赋值给row变量

    col = TABLE(57)  '矩阵列数赋值给col变量

    if(row * col = 18) then'如果获取到9个圆点的圆心位置坐标x,y 

        TABLE(39) = 1 '窗口界面提示提取mark点成功

    else

      TABLE(39) = 0 '窗口界面提示提取mark点失败

    return         '返回子函数,不往下执行

    endif

     

    '像素坐标和世界坐标放入table中

    DIM i

    FOR i=0 TO row-1

        ZV_MATGETROW (ppts, i, col, 81 + i*col)'将像素坐标存放到table81~table98中

        ZV_MATGETROW (wpts, i, col, 131 + i*col)'将世界坐标存放到table131~table148中

    NEXT

    

    '将灰度图转成RGB图像,作为结果图像

    ZVOBJECT color

    ZV_GRAYTORGB(grabImg, color)

    

    '绘制mark点的十字架

    DIM j, pixNum 

    pixNum = 0

    FOR i=0 TO 2

        FOR j=0 TO 2

            '绘制mark标记点

          ZV_MARKER(color, TABLE(81 + 2 * pixNum), TABLE(81 + 2 * pixNum + 1), 0, 40, C_GREEN)

          pixNum = pixNum + 1

        NEXT

    NEXT

    

    '用文本绘制mark点的序号,显示在图像界面中

    FOR i=0 TO 8

        ZV_TEXT (color, TOSTR(i,1,0), TABLE(81+2*i)-20, TABLE(81+2*i +1)-40, 80, C_RED)

    NEXT

  

    ZV_LATCH(color, 0)'显示结果图像

  

END SUB


'坐标标定界面按下标定按钮时响应的函数

GLOBAL SUB btn_ca_calib()

    ZV_IMGINFO(grabImg,0)  '获取采集图像信息

    '根据像素坐标数据组和世界坐标数据组执行标定,获得标定系数ca_param

    ZV_CALCAM(ppts,wpts,ca_param,TABLE(0),TABLE(1),d_ca_param(0))

    is_ca_success=1 '标定成功标志置1

    

    ZV_CALERROR(ca_param, ppts, wpts, 0)'计算标定误差,并将结果存放在起始地址为0的数组中

    ca_min_err = TABLE(1) '将误差结果赋值给变量,用于在界面中实时显示误差结果

    ca_max_err = TABLE(2)

    ca_avg_err = TABLE(0)

  

END SUB


'坐标标定界面按下返回按钮时响应的函数

GLOBAL SUB btn_ca_param_rtn()

    ZV_LATCHCLEAR(0)           '将锁存通道0清空

    ZV_LATCHSETSIZE(0, HMI_CONTROLSIZEX(10, 7), HMI_CONTROLSIZEY(10, 7)) '设置锁存的大小

    btn_grab()

    HMI_CLOSEWINDOW(11)   '关闭窗口号为13的坐标标定窗口界面

  

END SUB

10.在main.bas文件中添加HMI运行界面按下测试按钮响应的函数,并关联动作函数名。


'HMI界面按下测试按钮时响应的函数

GLOBAL SUB btn_test()

    TABLE(6)=0   '检测前先将结果数据清0

    d_detect_time=0

    for i=0 to 17

        d_circle_rst(i)=0

    next

  

    TICKS=0

    '定义变量,依次为白色像素连通区域,掩模区域,黑色像素连通区域,连通区域结果列表,小圆斑点区域,圆测量器,中间结果变量

    ZVOBJECT regionWhite, regionMask, regionBlack,re_connecte,circle_connect,mr,tmp

    

     '生成全图像区域

    ZV_REGENFULLIMG(grabImg,regionMask)

  

    '二值化处理

    if d_detect_param(0) = 0 then    '如果选择手动阈值模式

          '根据低阈值和高阈值参数生成白色像素图像regionWhite

        ZV_RETHRESH(grabImg, regionMask, regionWhite, d_detect_param(1), d_detect_param(2))

        '对白色像素区域进行一次1*1的开运算

        ZV_REOPENING(regionWhite,regionWhite,d_deal_value(0),d_deal_value(0))

        '对白色像素区域进行一次1*1的闭运算

        ZV_RECLOSING(regionWhite,regionWhite,d_deal_value(1),d_deal_value(1))

    

    else                             '如果选择自动阈值模式

    

        Dim autoThresh               '定义自动阈值模式下的二值化阈值

        '在grabImg图像中的指定区域内对图像进行自动二值化处理,输出二值化区域regionWhite 

        ZV_REAUTOTHRESH(grabImg, regionMask, regionWhite, 0)

        '对白色像素区域进行一次1*1的开运算

        ZV_REOPENING(regionWhite,regionWhite,d_deal_value(0),d_deal_value(0))

        '对白色像素区域进行一次1*1的闭运算

        ZV_RECLOSING(regionWhite,regionWhite,d_deal_value(1),d_deal_value(1))

        autoThresh = TABLE(0)

        ? "autoThresh = " autoThresh  '打印提示信息,当前二值化阈值

      

    endif

    

    '计算BLOB面积

    

    ZV_REAREA(regionWhite, 2)              '计算regionWhite亮区域的面积,存放到table(2)中

      

    if(TABLE(2)>0) then '如果获取到的白色像素数量大于0                 

         ZV_RECONNECT(regionWhite,re_connecte)     '计算区域的连通区域,存放到re_connecte列表中

         zv_refilter(re_connecte,0,d_detect_param(3),d_detect_param(4),0)'对区域列表中的区域进行过滤,保留面积在 d_detect_param(3) 到 d_detect_param(4) 的区域,面积不在此范围的区域将被过滤掉

         zv_refilter(re_connecte,20,0.8,1.3,0)'对区域列表中的区域进行过滤,保留最小外接矩形高宽比在0.9 到 1.1 的区域,面积不在此范围的区域将被过滤掉

         ZV_RESORT(re_connecte,1,1)          '对区域列表中的区域按照重心X的数据进行升序排序

         ZV_LISTCOUNT(re_connecte,6)     '获取列表中的连通区域的数量,存放到table(6)中 

    endif  

    

    '绘制效果图

    Dim width, height

    ZV_IMGINFO (grabImg, 20)'获取grabImg的图像信息

    width = TABLE(20)

    height = TABLE(21)

    

    ZV_GRAYTORGB(grabImg,disImg)'将灰度图转换到RGB图像,用于绘制检测结果图像

    

    ZV_REGION(disImg, regionMask, 0, ZV_COLOR(0,0,0))      '在disImg中绘制黑色的regionMask区域

    ZV_REGION(disImg, regionWhite, 0, ZV_COLOR(255,255,255))'在disImg中绘制白色的regionWhite区域

    

    for i=0 to TABLE(6)-1     '循环获取小圆斑点的位置XY信息生成圆测量器,检测圆心位置

          ZV_LISTGET(re_connecte,circle_connect,i)   '获取列表中序号为i的元素,即依次获取列表中小圆斑点的连通区域

          ZV_REAREACENTER(circle_connect,40)  '计算斑点区域的面积与中心位置,将位置放入TABLE(40)中

            ZV_MRGENCIRCLE(mr,TABLE(41),TABLE(42),70,50,0,360,1,10,8) '生成圆测量区域

            '设置测量参数,包括滤波尺寸、边缘阈值、边缘极性和边缘位置

          ZV_MRSETADV(mr,5, 50, 1,0)

          

          TABLE( 46, 0, 0, 0)'初始化结果数组

          '测量圆,并将结果赋值给起始地址为46的数组

          ZV_MRCIRCLE(mr, grabImg, tmp, 46)

           

          ZV_CIRCLE(disImg,TABLE(46),TABLE(47),TABLE(48),zv_color(0,255,0))'绘制小圆结果

          ShowString=TOSTR(i,1,0)   '将BLOB的数量转换成字符串变量

          ZV_TEXT(disImg,ShowString,TABLE(46),TABLE(47),55,ZV_COLOR(0,0,255)) '显示结果文本  

          ZV_MARKER(disImg,TABLE(46),TABLE(47),0,50,zv_color(0,255,0))   '在图像img中绘制十字

          

          if is_ca_success=1 AND d_use_calib=1 then 

              ZV_CALTRANSW(ca_param, TABLE(46)+TABLE(48),TABLE(47),49) '圆心加半径的坐标

              ZV_CALTRANSW(ca_param, TABLE(46),TABLE(47),46) '使用标定系数将图像坐标转换成世界坐标

              d_circle_rst(i*3+0)=TABLE(46)'将测量圆的结果赋值给圆心变量,显示到界面中

              d_circle_rst(i*3+1)=TABLE(47)

              d_circle_rst(i*3+2)=ZV_DISTPP(TABLE(46),TABLE(47),TABLE(49),TABLE(50))

          else 

              d_circle_rst(i*3+0)=TABLE(46)'将测量圆的结果赋值给圆心变量,显示到界面中

              d_circle_rst(i*3+1)=TABLE(47)

              d_circle_rst(i*3+2)=TABLE(48)

     endif      

     next

     ZV_LATCH(disImg, 0)     '在锁存通道0中显示结果图像

     d_detect_time=ABS(TICKS)'计算检测消耗时间

    

END SUB

image.png


11.在main.bas文件中添加HMI运行界面按下运行按钮响应的函数,并关联动作函数名。


'HMI界面按下运行按钮时响应的函数

GLOBAL SUB btn_run()

    if(2 = main_task_state) then           '如果主任务处于运行状态,打印提示信息并退出函数

     ?"已经开启连续运行任务,请勿重复操作!"

    return 

    endif

   

    if (1 = main_task_state) then          '如果主任务处于停止状态

        if (0 = PROC_STATUS(main_task_id)) then '如果任务未开启

            main_task_state = 2            '主任务状态设置为2,表示正在执行连续任务

            RUNTASK  main_task_id, main_task  '开启主任务

        endif

    endif


END SUB


'主任务实现函数

main_task:

    while(1)

        if (3 = main_task_state) then      '如果主任务状态处于3即按下停止按钮时

            main_task_state = 1             '将主任务状态置为1

            exit while                     '退出循环

        endif

        

        '重复执行采集和检测函数

        btn_grab()

        btn_test()     

    wend

END

image.png


12.在main.bas文件中添加HMI运行界面按下停止按钮响应的函数,并关联动作函数名。


'HMI界面按下停止按钮时响应的函数

GLOBAL SUB btn_stop()

    if (2 = main_task_state) then   '如果主任务状态处于3即正在连续执行任务时

        main_task_state = 3           '将主任务状态置为3,退出循环

    endif  

END SUB

image.png


image.png


image.png


image.png


仿真演示效果4


本次,正运动技术机器视觉运动控制一体机应用例程(三) BLOB分析的多圆定位,就分享到这里。


更多精彩内容请关注“正运动小助手”公众号,需要相关开发环境与例程代码,请咨询正运动技术销售工程师:400-089-8936。


本文由正运动技术原创,欢迎大家转载,共同学习,一起提高中国智能制造水平。文章版权归正运动技术所有,如有转载请注明文章来源。

发布时间:2021年11月10日 13:44  人气:   审核编辑(王静 )
更多内容请访问(深圳市正运动技术有限公司
相关链接

我有需求