AI图像标注软件:WPF-LabelImg


WPF-ROI控件设计


一 AI图像标注软件:WPF-LabelImg使用教程

项目方案

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

WPF-LabelImg 项目掌握教程

一、项目概述

WPF-LabelImg 是一个基于 WPF(Windows Presentation Foundation) 开发的图像标签标记工具,主要用于机器学习训练数据的标注工作。该项目提供了直观的图形界面,支持绘制矩形标注框、导入/导出 YOLO 格式标签文件等功能。

二、项目结构解析

2.1 整体架构

WPF-LabelImg-发布/
├── Solution/                    # 解决方案文件
│   └── WPF-LabelImg.sln         # Visual Studio 解决方案
├── Source/                      # 源代码目录
│   ├── Apps/                    # 应用程序层
│   │   └── H.App.LabelImg/      # 主应用(核心业务)
│   ├── Controls/                # 自定义控件
│   │   └── H.LabelImg.ShapeBox/ # 形状绘制控件
│   └── WPF-Control/             # 通用WPF控件库(基础框架)
└── Document/                    # 文档资源

2.2 核心模块说明

模块 职责 关键文件
H.App.LabelImg 主应用程序,包含业务逻辑和界面 MainWindow.xaml, App.xaml.cs
H.LabelImg.ShapeBox 形状绘制控件,处理标注框的渲染和交互 ShapeBox.xaml.cs, RectShape.cs
WPF-Control 通用控件库,提供基础 UI 组件 各种 Controls 和 Modules

三、快速上手:运行项目

3.1 环境要求

  • IDE: Visual Studio 2022 或更高版本
  • 框架: .NET 8.0 (Windows)
  • 数据库: SQLite(嵌入式,无需额外安装)

3.2 运行步骤

  1. 打开解决方案

    双击 Solution/WPF-LabelImg.sln
    
  2. 设置启动项目

    • 在解决方案资源管理器中右键点击 H.App.LabelImg
    • 选择 设为启动项目
  3. 编译运行

    • F5 或点击工具栏的 开始调试 按钮
    • 首次运行会自动创建 SQLite 数据库文件

3.3 验证运行

成功启动后,你将看到如下界面:

  • 左侧:项目管理、收藏夹、过滤器面板
  • 中间:图像预览和标注区域
  • 右侧:详情、编辑、标签列表面板

四、核心组件深度剖析

4.1 主窗口架构(MainWindow.xaml)

主窗口采用 OutlookBar 布局模式,分为三个主要区域:

<!-- 左侧面板:项目管理和过滤器 -->
<h:OutlookBar DockPanel.Dock="Left">
    <h:OutlookSection Header="项目管理">...</h:OutlookSection>
    <h:OutlookSection Header="收藏夹">...</h:OutlookSection>
    <h:OutlookSection Header="过滤器">...</h:OutlookSection>
    <h:OutlookSection Header="排序器">...</h:OutlookSection>
</h:OutlookBar>

<!-- 中间区域:图像展示和标注 -->
<ContentPresenter Content="{Binding}" />

<!-- 右侧面板:详情和编辑 -->
<h:OutlookBar DockPanel.Dock="Right">
    <h:OutlookSection Header="详情">...</h:OutlookSection>
    <h:OutlookSection Header="标签列表">...</h:OutlookSection>
</h:OutlookBar>

关键绑定说明

  • DataContext="{Binding Source={x:Static h:IocProject.Instance}, Path=Current.File}"
    • 使用静态 IOC 容器获取当前项目的文件数据
  • ItemsSource="{Binding Collection}"
    • 绑定文件集合到列表控件

4.2 形状绘制控件(ShapeBox)

ShapeBox 是项目的核心标注控件,负责图像渲染和形状绘制:

public class ShapeBox : FrameworkElement, IShapeView
{
    // 视觉层:图像层 + 形状层
    private ImageDrawingVisual _imageDrawingVisual;
    private ShapeDrawingVisual _shapeDrawingVisual;
    
    // 依赖属性
    public ImageSource ImageSource { get; set; }  // 绑定图像源
    public ObservableCollection<IShape> Shapes { get; set; }  // 形状集合
    
    // 绘制方法
    public void DrawShapes()
    {
        using var drawingContext = _shapeDrawingVisual.RenderOpen();
        foreach (var shape in shapes)
        {
            shape.Draw(this, drawingContext, Stroke, strokeThickness, Fill);
        }
    }
}

设计亮点

  • 使用 VisualCollection 实现分层渲染(图像层在底层,形状层在顶层)
  • 支持缩放自适应(ToViewThickness 方法处理缩放时的边框粗细)

4.3 矩形形状(RectShape)

RectShape 实现了标注框的核心逻辑:

public class RectShape : TitleShapeBase, IRectShape, IBoundingBoxable, IThumbShape
{
    public Rect Rect { get; set; }  // 标注框的矩形区域
    
    public override void Drawing(IView view, DrawingContext dc, Pen pen, Brush fill)
    {
        if (this.Rect.IsZoreOrEmpty()) return;
        
        // 绘制矩形
        dc.DrawRectangle(fill, pen, Rect);
        
        // 绘制标题(标签名称)
        DrawTitle(view, dc, Rect.TopLeft, pen.Brush, 10 / view.Scale, 10 / view.Scale);
        
        // 可选:绘制交线和尺寸
        if (UseCross) { ... }
        if (UseText) { ... }
    }
    
    // 创建控制点(用于拖拽调整)
    protected override IEnumerable<IHandle> CreateHandles()
    {
        yield return new ActionHandle(x => this.Rect = new Rect(x, this.Rect.BottomRight), 
                                      this.Rect.TopLeft, this);
        yield return new ActionHandle(x => this.Rect = new Rect(this.Rect.TopLeft, x), 
                                      this.Rect.BottomRight, this);
    }
}

4.4 项目管理(FileProjectItem)

项目数据管理采用 Repository 模式

public class FileProjectItem : ProjectItemBase
{
    public string BaseFolder { get; set; }  // 图像文件目录
    public ObservableCollection<LabelItem> Labels { get; set; }  // 标签类别
    
    // 数据库绑定的文件仓储
    public IRepositoryBindable<fm_dd_image> File { get; set; }
    
    public override bool Load(out string message)
    {
        // 配置数据库连接
        DbIoc.ConfigureServices(dx =>
        {
            dx.AddDbContext<DataContext>(x =>
            {
                string con = $"Data Source={this.GetFilePath()}";
                x.UseLazyLoadingProxies().UseSqlite(con);
            });
        });
        
        // 迁移数据库并加载数据
        DataContext context = DbIoc.Services.GetService<DataContext>();
        context.Database.Migrate();
        this.File = DbIoc.GetService<IRepositoryBindable<fm_dd_image>>();
        this.File.RefreshData();
        
        return true;
    }
}

4.5 YOLO 格式解析器(YoloTxtParser)

支持导入/导出 YOLO 格式的标签文件:

public class YoloTxtParser
{
    public List<fm_dd_label> ParseYoloFile(fm_dd_image imageInfo, Dictionary<int, string> classMapping)
    {
        string txtFilePath = Path.ChangeExtension(imageInfo.Url, ".txt");
        if (!File.Exists(txtFilePath)) return new List<fm_dd_label>();
        
        string[] lines = File.ReadAllLines(txtFilePath);
        foreach (string line in lines)
        {
            // YOLO格式: <class_id> <center_x> <center_y> <width> <height>
            var label = ParseYoloLine(line, imageInfo, classMapping);
            labels.Add(label);
        }
        return labels;
    }
    
    // 转换归一化坐标到像素坐标
    private Rect ConvertToPixelBoundingBox(double centerX, double centerY, 
                                          double width, double height,
                                          int imageWidth, int imageHeight)
    {
        double x = centerX * imageWidth - (width * imageWidth / 2);
        double y = centerY * imageHeight - (height * imageHeight / 2);
        return new Rect(x, y, width * imageWidth, height * imageHeight);
    }
}

五、数据模型设计

5.1 数据库模型

项目使用 Entity Framework Core + SQLite 存储数据:

表名 说明 关键字段
fm_dd_images 图像文件信息 Url, PixelWidth, PixelHeight
fm_dd_labels 标签标注信息 LabelName, BoundingBox, LabelColor

5.2 实体类结构

// 图像实体
public class fm_dd_image : ObservableObject
{
    public int Id { get; set; }
    public string Url { get; set; }           // 文件路径
    public int PixelWidth { get; set; }       // 像素宽度
    public int PixelHeight { get; set; }      // 像素高度
    public string Tags { get; set; }          // 分类标签(JSON)
    public int Score { get; set; }            // 评分
    public bool IsFavorite { get; set; }      // 是否收藏
}

// 标签实体
public class fm_dd_label : ObservableObject
{
    public int Id { get; set; }
    public string LabelName { get; set; }     // 标签名称
    public Rect BoundingBox { get; set; }     // 边界框
    public Color LabelColor { get; set; }     // 标签颜色
    public int ImageId { get; set; }          // 关联图像ID
}

六、核心业务流程

6.1 创建新项目

用户点击"新建项目" → FileProjectService.Create() → 创建项目目录和数据库 → 加载空项目

关键代码(App.xaml.cs):

services.AddProject<FileProjectService>();

6.2 标注工作流

打开项目 → 选择图像 → 绘制标注框 → 设置标签名称 → 保存到数据库

6.3 导出 YOLO 格式

选择导出 → 遍历所有图像 → 生成 .txt 文件(归一化坐标)→ 生成 classes.txt

七、扩展开发指南

7.1 添加新的标注形状

  1. 实现 IShape 接口
public class CircleShape : ShapeBase, IShape
{
    public Point Center { get; set; }
    public double Radius { get; set; }
    
    public override void Draw(IView view, DrawingContext dc, Brush stroke, 
                             double strokeThickness, Brush fill)
    {
        dc.DrawEllipse(fill, new Pen(stroke, strokeThickness), Center, Radius, Radius);
    }
}
  1. 注册到 ShapeBox
    ShapeBox.DrawShapes() 方法中添加新形状的绘制逻辑。

7.2 添加新的过滤器

  1. 继承 FileFilter 基类
public class CustomFileFilter : FileFilter
{
    public override bool Filter(fm_dd_image item)
    {
        // 自定义过滤逻辑
        return item.Score >= 8;
    }
}
  1. 在 UI 中注册
<local:CustomFileFilter Name="高分图像" Value="True" />

7.3 添加新的排序器

public class FileOrderByCreateTime : OrderBase<fm_dd_image>
{
    public override string Name => "按创建时间排序";
    
    public override IOrderedEnumerable<fm_dd_image> Order(IEnumerable<fm_dd_image> source)
    {
        return source.OrderBy(x => x.CreateTime);
    }
}

八、调试技巧

8.1 查看数据库内容

数据库文件路径:项目目录/项目名称.db

使用工具:

  • DB Browser for SQLite(免费开源)
  • Visual Studio SQLite 扩展

8.2 调试形状绘制

ShapeBox.DrawShapes() 方法中添加断点,观察 Shapes 集合的内容。

8.3 日志查看

项目使用 Log4net 记录日志,日志文件位于:

%AppData%\H.App.LabelImg\Logs\

九、常见问题

Q1:如何导入已有标签?

A:使用菜单"编辑" → “导入YOLO TXT文件”,确保 .txt 文件与图像文件同名且在同一目录。

Q2:如何批量处理图像?

A:在项目设置中配置 BaseFolder,系统会自动扫描该目录下的所有图像文件。

Q3:标签颜色如何自定义?

A:在右侧"标签列表"面板中,点击标签项可以修改颜色属性。

Q4:如何导出标注数据?

A:使用菜单"编辑" → “导出YOLO TXT文件”,会在图像目录生成对应的 .txt 文件。

十、学习路径建议

第1周:熟悉项目结构和基本操作
  └─ 运行项目,体验标注流程
  └─ 阅读 MainWindow.xaml 和 App.xaml.cs

第2周:深入核心控件
  └─ 学习 ShapeBox 的渲染机制
  └─ 理解 RectShape 的交互逻辑

第3周:掌握数据层
  └─ 学习 DataContext 和实体模型
  └─ 理解 Repository 模式的应用

第4周:扩展开发
  └─ 尝试添加自定义过滤器或排序器
  └─ 实现新的标注形状

第5周:高级主题
  └─ 学习 IOC 容器的配置
  └─ 理解模块系统(Modules)的设计

十一、资源推荐

  • 官方文档: https://hebiangu.github.io/WPF-Control-Docs
  • WPF 学习: https://learn.microsoft.com/zh-cn/dotnet/desktop/wpf/
  • Entity Framework Core: https://learn.microsoft.com/zh-cn/ef/core/

通过以上内容,你应该已经对 WPF-LabelImg 项目有了全面的了解。建议从运行项目开始,逐步深入各个模块的源码,结合调试工具理解其工作机制。如果遇到具体问题,可以随时进一步探讨!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐