HALCON error #4056: Image data management: object-ID is NULL (0) in operator disp_obj

项目场景:

提示:这里简述项目相关背景:

该项目是利用Halcon算子进行图像处理,C#搭建界面框架,实现的是一个循环读取图片后,对图片中的圆形半径进行获取,并且显示在窗口上。
在这里插入图片描述


问题描述

提示:这里描述项目中遇到的问题:

HalconDotNet.HOperatorException
HResult=0x80131600
Message=HALCON error #4056: Image data management: object-ID is NULL (0) in operator disp_obj
Source=halcondotnet
StackTrace:
在 HalconDotNet.HOperatorException.throwOperator(Int32 err, Int32 procIndex)
在 HalconDotNet.HalconAPI.PostCall(IntPtr proc, Int32 procResult)
在 HalconDotNet.HOperatorSet.DispObj(HObject objectVal, HTuple windowHandle)
在 Demo.Form1.PlayThread() 在 D:\Project\text\C#andHalcon\Demo\Form1.cs 中: 第 50 行
在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
在 System.Threading.ThreadHelper.ThreadStart()


原因分析:

提示:这里填写问题的分析:

HalconDotNet.HOperatorException 是 HALCON 图像处理库在 .NET 环境(如 C#)中抛出的一个异常类型。此异常通常表示在使用 HALCON 的某个操作符时发生了错误。
错误编号是 #4056,错误消息是“Image data management: object-ID is NULL (0) in operator disp_obj”,这意味着在调用 disp_obj 操作符时,传递给它的图像对象(HObject)的 ID 是 NULL(0),即没有有效的图像对象被传递。

为了解决这个问题,你需要检查以下几点:

  1. 图像对象是否已正确创建:确保在调用 disp_obj 之前,你有一个有效的 HObject 对象,并且它已经被正确地初始化和赋值。
  2. 线程安全:如果你在多线程环境中使用 HALCON,请确保你的图像对象在跨线程传递时是线程安全的。HALCON 的某些部分可能不是线程安全的,因此你需要确保在多个线程之间正确地同步对这些对象的访问。
  3. 异常处理:在调用 HALCON 操作符之前和之后添加适当的异常处理逻辑,以便在发生错误时能够捕获并处理这些错误。
  4. 资源释放:确保在不再需要图像对象时释放它们,以避免内存泄漏和其他问题。
    更新 HALCON 和 .NET 绑定:确保你正在使用的 HALCON 版本和 .NET 绑定是最新的,并且它们之间是相互兼容的。

具体情况分析

我的项目代码需要查看 Form1.cs 文件的第 50 行,并检查 PlayThread 方法中 disp_obj 的调用。确保在调用 disp_obj 之前,你有一个有效的 HObject 对象,并且它已经被正确地传递到该方法中。

  • LoadBatchImage();函数是用来批量加载图像,然后下面ThreadObject = new Thread(new ThreadStart(PlayThread));这个是线程执行,问题就在于,我加载完成图像后,就直接进行下面的线程,不会再次加载图像了,而我的线程中的图像处理函数中,有图像释放资源函数,结果释放了,这就会导致这个线程在开始按钮点击触发时候,只能循环一次,不能一直执行。
public Form1()
{
    InitializeComponent();

    this.Print_label.Text = "工控界面";

    CreateHalconWindow();

    LoadBatchImage();

    ThreadObject = new Thread(new ThreadStart(PlayThread));

}
  • 这个就是批量加载图像
//循环加载图像
 public void LoadBatchImage()
 {
     for (int i = 0; i < 8; i++)
     {
         HOperatorSet.ReadImage(out ImageArray[i], i.ToString() + ".bmp");
     }
 }
  • ImageAlgorithm(ImageArray[i]);就是图像处理函数,ImageArray[i]就是加载的图像。
public void PlayThread()
{
    int i = 0;
    Thread_Stop = false;
    HTuple width = null, height = null;



    while (!Thread_Stop)
    {
        HOperatorSet.DispObj(ImageArray[i], WindowID);

        HOperatorSet.GetImageSize(ImageArray[i], out width, out height);

        HOperatorSet.SetPart(WindowID, 0, 0, height, width);

        //自定义图像处理函数
        ImageAlgorithm(ImageArray[i]);

        Thread.Sleep(300);

        i++;

        if (i >= 8)
        {
            i = 0;
        }

    }
}

ImageArray[i]加载图像,在private void ImageAlgorithm(HObject ho_ResultImage)函数中对应的形参是HObject ho_ResultImage,因此只需要将HObject ho_ResultImage关于它释放的信息都注释掉就可以了。

private void ImageAlgorithm(HObject ho_ResultImage)
{
    HObject ho_ResultRegion = null;
    HObject ho_ResultConnectedRegions = null, ho_ResultSelectedRegions = null;
    HObject ho_ResultCircle = null, ho_ResultContour = null;

    HTuple hv_Width = null, hv_Height = null;
    HTuple hv_MetrologyHandle = null, hv_CircleRadiusTolerance = null;
    HTuple hv_NewRadius = null;
    HTuple hv_ResultArea = new HTuple(), hv_ResultRow = new HTuple();
    HTuple hv_ResultColumn = new HTuple(), hv_MetrologyCircleIndice = new HTuple();
    HTuple hv_CircleRadiusResult = new HTuple();

    HOperatorSet.GenEmptyObj(out ho_ResultRegion);
    HOperatorSet.GenEmptyObj(out ho_ResultConnectedRegions);
    HOperatorSet.GenEmptyObj(out ho_ResultSelectedRegions);
    HOperatorSet.GenEmptyObj(out ho_ResultCircle);
    HOperatorSet.GenEmptyObj(out ho_ResultContour);

    HOperatorSet.GetImageSize(ho_ResultImage, out hv_Width, out hv_Height);

    HOperatorSet.CreateMetrologyModel(out hv_MetrologyHandle);

    HOperatorSet.SetMetrologyModelImageSize(hv_MetrologyHandle, hv_Width, hv_Height);

    hv_CircleRadiusTolerance = 100;

    hv_NewRadius = 324;

    ho_ResultConnectedRegions.Dispose();
    HOperatorSet.Threshold(ho_ResultImage, out ho_ResultRegion, 0, 60);

    ho_ResultConnectedRegions.Dispose();
    HOperatorSet.Connection(ho_ResultRegion, out ho_ResultConnectedRegions);

    ho_ResultSelectedRegions.Dispose();
    HOperatorSet.SelectShape(ho_ResultConnectedRegions, out ho_ResultSelectedRegions,
    (new HTuple("area")).TupleConcat("roundness"), "and", (new HTuple(250000)).TupleConcat(
        0.9), (new HTuple(320000)).TupleConcat(1));

    HOperatorSet.AreaCenter(ho_ResultSelectedRegions, out hv_ResultArea, out hv_ResultRow, out hv_ResultColumn);


    HOperatorSet.SetColor(WindowID, "green");

    HOperatorSet.SetDraw(WindowID, "margin");

    HOperatorSet.DispObj(ho_ResultImage, WindowID);

    ho_ResultCircle.Dispose();

    HOperatorSet.GenCircle(out ho_ResultCircle, hv_ResultRow, hv_ResultColumn, hv_NewRadius);

    HOperatorSet.AddMetrologyObjectCircleMeasure(hv_MetrologyHandle, hv_ResultRow,
        hv_ResultColumn, hv_NewRadius, hv_CircleRadiusTolerance, 5, 1.5, 30, (new HTuple("measure_transition")).TupleConcat(
            "min_score"), (new HTuple("all")).TupleConcat(0.4), out hv_MetrologyCircleIndice);

    HOperatorSet.ApplyMetrologyModel(ho_ResultImage, hv_MetrologyHandle);

    //ho_ResultImage.Dispose();
    HOperatorSet.GetMetrologyObjectResultContour(out ho_ResultContour, hv_MetrologyHandle, "all", "all", 1.5);

    HOperatorSet.GetMetrologyObjectResult(hv_MetrologyHandle, hv_MetrologyCircleIndice, "all", "result_type", "radius", out hv_CircleRadiusResult);

    HOperatorSet.DispObj(ho_ResultContour, WindowID);

    HOperatorSet.SetTposition(WindowID, 0, 0);

    HOperatorSet.WriteString(WindowID, "圆外径:" + hv_CircleRadiusResult);

    HOperatorSet.ClearMetrologyModel(hv_MetrologyHandle);


    //ho_ResultImage.Dispose();
    ho_ResultRegion.Dispose();
    ho_ResultConnectedRegions.Dispose();
    ho_ResultSelectedRegions.Dispose();
    ho_ResultCircle.Dispose();
    ho_ResultContour.Dispose();






}

解决方案:

提示:这里填写该问题的具体解决方案:

其实需要做的就这么简单,注释掉这一行代码,希望给大家提供这样的一个思路。

ho_ResultImage.Dispose();
  • 7
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值