halcon窗体无响应和占用cpu时间长的问题

halcon窗体连续拍照并处理结果,几分钟后整个程序界面失去响应。

在任务管理器中会提示程序已经失去响应。


image.png


这种问题多半跟跨线程调用有关系。也就是说,处理图像的线程想在halcon窗体内显示结果,但是halcon控件是另一个界面线程中的控件。

例如下面一段程序就是halcon进行图片处理并且显示结果。
其中 m_HWCtrl.InvokeRequired 这个如果为true,则表示调用控件m_HWCtrl的线程是另一个线程在调用,而非拥控件所在的界面线程在调用。

你只需要把实现代码写在else部分即可。

  if (m_HWCtrl.InvokeRequired)
   {
        Func<bool> fun = weldCheckTopMethod;
        return (bool)m_HWCtrl.Invoke(fun, new object[] { });
   }
   else
   {
       //这里写m_HWCtrl控件的功能代码。
   }


private bool weldCheckTopMethod()
{
    int x = 1200, y = 200;
    var halcon = new visionFunClass(); var winHandle = m_HWCtrl.HalconWindow;
    try
    {
        if (m_HWCtrl == null) return false;
        if (!m_HWCtrl.CurrentImage.IsInitialized()) return false;
        if (m_HWCtrl.InvokeRequired)
        {
            Func<bool> fun = weldCheckTopMethod;
            return (bool)m_HWCtrl.Invoke(fun, new object[] { });
        }
        else
        {
            //return true;
            var hwinObj = m_HWCtrl; weldCheckTopResult = false;
            var list1 = work.gConfig.visionUpROI.explainCSVRow().ConvertAll(s => double.Parse(s));
            weldCheck.work.weldCheckParam param = new weldCheck.work.weldCheckParam()
            {
        hwin = hwinObj,
        ptNums = work.gConfig.visionUpPtnums,
        radDnLimit = work.gConfig.visionUpPtRadLimitDn,
        radUpLimit = work.gConfig.visionUpPtRadLimitUp,
        threshold = work.gConfig.visionUpThreshold,
        roiX1 = list1[0],
        roiY1 = list1[1],
        roiX2 = list1[2],
        roiY2 = list1[3],
        selectShapeMin=work.gConfig.visionSelectShapeMinTop,
        selectShapeMax=work.gConfig.visionSelectShapeMaxTop
        };
   
    
    var lineAryTmp = new List<Linef>();
    int ptnum = 0; bool okng = false;
    try
    {
        okng =  halcon.checkTop(param, out lineAryTmp, out ptnum);
    }
    catch(Exception ex)
    {
        halcon.writeMsg(winHandle, string.Format("错误: {0}", ex.Message), x + 370, y, 9, vFunBaseMethod.setColorEnum.red);
    }
    double distanceA = 0, distanceB = 0;

   
    if (lineAryTmp!=null && lineAryTmp.Count >= 2)
    {
        halcon.dispLines(winHandle, lineAryTmp[0]);
        halcon.dispLines(winHandle, lineAryTmp[1]);
    }

    lineAry[work.lineNameEnum.焊点位置A].FindTargetObj();
    lineAry[work.lineNameEnum.焊点位置B].FindTargetObj();

    if (lineAryTmp!=null && lineAryTmp.Count >= 2)
    {
        distanceA = DistanceLineToLine(
            lineAry[work.lineNameEnum.焊点位置A].TargetObj,
            lineAryTmp[0]);

        distanceA = VxTransTableToWorld(new Pointf(0, distanceA)).y;

        distanceB = DistanceLineToLine(
                lineAry[work.lineNameEnum.焊点位置B].TargetObj,
                lineAryTmp[1]);

        distanceB = VxTransTableToWorld(new Pointf(0, distanceB)).y;
    }

    bool r1 = distanceA < work.gWorkSetting.weldPtPosADnlimit ||
 distanceA > work.gWorkSetting.weldPtPosAUplimit;
    bool r2=  distanceB < work.gWorkSetting.weldPtPosBDnlimit ||
 distanceB > work.gWorkSetting.weldPtPosBUplimit;
    if (work.gConfig.visionIgnoreSizeAB) r1 = true;
    bool r3 = ptnum>=work.gConfig.visionUpPtnums;
    if ((okng && !r1 && !r2 && r3) || work.gConfig.isPassWeldCheckRes)
    {
        halcon.writeMsg(winHandle, "OK", x - 230, y , 24, vFunBaseMethod.setColorEnum.green);
        halcon.writeMsg(winHandle, string.Format("焊点数量: {0}", ptnum), x, y, 12, vFunBaseMethod.setColorEnum.green);
        halcon.writeMsg(winHandle, string.Format("焊点位置A: {0}", distanceA), x + 130, y, 12, vFunBaseMethod.setColorEnum.green);
        halcon.writeMsg(winHandle, string.Format("焊点位置B: {0}", distanceB), x + 250, y, 12, vFunBaseMethod.setColorEnum.green);
        weldCheckTopResult = true;
    }
    else
    {
        halcon.writeMsg(winHandle, "NG", x - 230, y, 24, vFunBaseMethod.setColorEnum.red);
        if (!r3)
            halcon.writeMsg(winHandle, string.Format("焊点数量: {0}", ptnum), x, y, 12, vFunBaseMethod.setColorEnum.red);
        else
            halcon.writeMsg(winHandle, string.Format("焊点数量: {0}", ptnum), x, y, 12, vFunBaseMethod.setColorEnum.green);

        if (!r1)
             halcon.writeMsg(winHandle, string.Format("焊点位置A: {0}", distanceA), x+130, y, 12, vFunBaseMethod.setColorEnum.red);
        else
            halcon.writeMsg(winHandle, string.Format("焊点位置A: {0}", distanceA), x+130, y, 12, vFunBaseMethod.setColorEnum.green);

        if (!r2)
            halcon.writeMsg(winHandle, string.Format("焊点位置B: {0}", distanceB), x + 250, y, 12, vFunBaseMethod.setColorEnum.red);
        else
            halcon.writeMsg(winHandle, string.Format("焊点位置B: {0}", distanceB), x + 250, y, 12, vFunBaseMethod.setColorEnum.green);
        weldCheckTopResult = false;
    }
    return true;
    }
    }
    catch (Exception ex)
    {
        halcon.writeMsg(winHandle, "NG", x - 230, y, 24, vFunBaseMethod.setColorEnum.red);
        halcon.writeMsg(winHandle, string.Format("焊点数量: {0}", 0), x, y, 12, vFunBaseMethod.setColorEnum.red);
        halcon.writeMsg(winHandle, string.Format("焊点位置A: {0}", 0), x + 130, y, 12, vFunBaseMethod.setColorEnum.red);
        halcon.writeMsg(winHandle, string.Format("焊点位置B: {0}", 0), x + 250, y, 12, vFunBaseMethod.setColorEnum.red);
        halcon.writeMsg(winHandle, string.Format("错误: {0}", ex.Message), x + 370, y, 9, vFunBaseMethod.setColorEnum.red);
        weldCheckTopResult = false;
        throw ex;
    }
}


跨线程调用一般VS会在运行期弹出错误提示。有些情况下没有,而且如果你单步拍照、处理图片好像是没什么问题。

但是当你循环处理,并且不sleep的情况下全速来跑,就会发现问题,界面会卡死。


另一个问题是CPU时间过高。

如果在运动控制的程序中,如果CPU占用过高会引发运动异常,搞不好每百次或千次给你来个撞机之类的Bug。或者也可能让机器的运动越来越慢,由原来正常每分钟走6个来回,变成每分钟走2个来回这么奇魄的问题。

但是在halcon视觉处理中,连续处理sleep短暂的话,占用时间高很常见,也没什么好办法处理。

通常,视觉处理时,当前工件和一下个工件有秒级的时间间隙,因此这个问题显得不是那么严重。

我们不可能做到像记事本程序那样,运行几个小时,才占用CPU时间几秒钟。


image.png


--------------------- 

作者:hackpig
来源:www.skcircle.com
版权声明:本文为博主原创文章,转载请附上博文链接!


本文出自勇哥的网站《少有人走的路》wwww.skcircle.com,转载请注明出处!讨论可扫码加群:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

会员中心
搜索
«    2024年5月    »
12345
6789101112
13141516171819
20212223242526
2728293031
网站分类
标签列表
最新留言
    热门文章 | 热评文章 | 随机文章
文章归档
友情链接
  • 订阅本站的 RSS 2.0 新闻聚合
  • 扫描加本站机器视觉QQ群,验证答案为:halcon勇哥的机器视觉
  • 点击查阅微信群二维码
  • 扫描加勇哥的非标自动化群,验证答案:C#/C++/VB勇哥的非标自动化群
  • 扫描加站长微信:站长微信:abc496103864
  • 扫描加站长QQ:
  • 扫描赞赏本站:
  • 留言板:

Powered By Z-BlogPHP 1.7.2

Copyright Your skcircle.com Rights Reserved.

鄂ICP备18008319号


站长QQ:496103864 微信:abc496103864