qq_45243945 2025-07-18 16:33 采纳率: 0%
浏览 24

在c#插入halcon字典后,读取数据和插入数据不一致

img

img


我想将现成YOLO数据集转换成halcon的dict数据集,在存入区域点位的时候,如第一张图所示我应该存入十个位置,但是保存本地之后再用halcon读出来的时候发现只存了5个,其他的全部置0了,有没有帮忙看下谢谢

  • 写回答

6条回答 默认 最新

  • 檀越@新空间 2025-07-18 16:39
    关注

    下午好🌅🌅🌅
    本答案参考通义千问

    在使用 C# 将 YOLO 数据集转换为 Halcon 的 dict 数据结构 时,如果发现插入数据后读取不一致(例如应该存入 10 个位置,但只读到了 5 个,其余被置 0),可能是以下几个原因导致的。以下是详细分析和解决方案。


    问题分析

    1. 数据类型或格式错误

    • Halcon 的 dict 是一个键值对结构,通常用于存储图像、区域、坐标等信息。
    • 如果你将 YOLO 格式的坐标数据(如 [x, y, w, h] 转换为 dict 时,可能没有正确地将每个目标的数据以独立键存储,导致部分数据被覆盖或丢失。

    2. 键名重复或覆盖

    • 如果你使用相同的键名多次插入数据(比如 "obj_0", "obj_1" 等),可能会导致后续数据覆盖前面的数据,从而造成数据丢失。

    3. Halcon 读取方式不当

    • 在从 .hobj.xml 文件中读取 dict 时,如果没有正确解析所有键值对,也可能导致部分数据未被读取。

    解决方案

    1. 确保每个目标都有唯一的键名

    在插入到 dict 时,为每个目标分配唯一的键名,例如:

    for (int i = 0; i < numObjects; i++)
    {
        string key = "obj_" + i.ToString();
        dict.SetTuple(key, new HTuple(x[i], y[i], width[i], height[i]));
    }
    

    重点:确保每个对象都有唯一且不同的键名,避免覆盖。


    2. 使用 HTuple 存储多个坐标

    Halcon 的 HTuple 支持多维数组,可以将多个目标的坐标存储在一个 HTuple 中,而不是每个目标单独存入 dict

    HTuple objData = new HTuple();
    for (int i = 0; i < numObjects; i++)
    {
        objData.Append(new HTuple(x[i], y[i], width[i], height[i]));
    }
    dict.SetTuple("objects", objData);
    

    重点:使用 HTuple 来存储多个目标数据,避免键名冲突和覆盖问题。


    3. 正确读取 dict 数据

    在读取时,确保你访问的是完整的 HTuple,而不是逐个键读取:

    HTuple objData;
    if (dict.GetTuple("objects", out objData))
    {
        for (int i = 0; i < objData.Length; i++)
        {
            HTuple coords = objData[i];
            double x = coords[0].D;
            double y = coords[1].D;
            double w = coords[2].D;
            double h = coords[3].D;
            // 处理坐标
        }
    }
    else
    {
        Console.WriteLine("无法读取 objects 键");
    }
    

    重点:使用 HTuple 读取,避免逐个键读取导致遗漏。


    4. 检查文件保存与加载方式

    确保你保存和加载的方式是正确的。例如:

    保存到 XML 文件(C#):

    dict.WriteObject("data.xml");
    

    读取 XML 文件(Halcon):

    read_dict ('data.xml', 'dict')
    

    重点:使用 Halcon 的 read_dict 命令读取,确保文件路径正确。


    完整示例代码(C#)

    using HalconDotNet;
    
    public class YoloToHalconDict
    {
        public static void ConvertAndSave(string[] yoloData, string outputPath)
        {
            HDict dict = new HDict();
    
            HTuple objData = new HTuple();
            foreach (string line in yoloData)
            {
                string[] parts = line.Split(' ');
                double x = double.Parse(parts[1]);
                double y = double.Parse(parts[2]);
                double w = double.Parse(parts[3]);
                double h = double.Parse(parts[4]);
    
                objData.Append(new HTuple(x, y, w, h));
            }
    
            dict.SetTuple("objects", objData);
            dict.WriteObject(outputPath);
        }
    }
    

    Halcon 读取示例(HDevelop)

    read_dict ('data.xml', 'dict')
    
    get_dict_tuple(dict, 'objects', Objects)
    count_obj := |Objects|
    for I := 0 to count_obj - 1 by 1
        get_dict_tuple(dict, 'objects[' + I + ']', Obj)
        X := Obj[0]
        Y := Obj[1]
        Width := Obj[2]
        Height := Obj[3]
        * 使用这些坐标...
    endfor
    

    总结

    | 问题 | 解决方案 | |------|----------| | 数据丢失 | 使用唯一键名或 HTuple 存储多个对象 | | 键名覆盖 | 避免重复键名,使用动态生成键 | | 读取错误 | 使用 HTuple 读取,避免逐个键读取 | | 文件保存/加载 | 确保使用 Halcon 的 read_dict 正确读取 |


    如果你能提供具体的代码片段或 YOLO 数据格式,我可以进一步帮你调试。希望以上内容对你有帮助!

    评论

报告相同问题?

问题事件

  • 创建了问题 7月18日