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

AI图像标注软件:WPF-LabelImg-教程 AI图像标注软件WPF-LabelImg-教程WPF-LabelImg-App.xamlWPF-LabelImg_MainWindow.xamlWPF-LabelImg_标题栏教程6个阶段基础设施层 1-2周- 数据库、应用程序配置核心控件层 2-3周- ShapeBox、RectShape、状态机业务模型层 1-2周- ImageBindable、FileRepositoryBindable业务服务层 1-2周- YOLO解析器、项目管理服务UI展示层 2-3周- MainWindow、ImagePresenter集成测试与优化 1-2周- 功能测试、性能优化WPF-LabelImg 项目重写顺序指南基于WPF-Control框架一、项目重写总体架构基于对WPF-Control框架和WPF-LabelImg业务逻辑的深入分析我为你制定了以下重写顺序二、重写流程图┌─────────────────────────────────────────────────────────────────┐ │ WPF-LabelImg 重写流程图 │ └─────────────────────────────────────────────────────────────────┘ 阶段1基础设施层 (1-2周) ┌─────────────────────────────────────────────────────────────┐ │ 1.1 创建解决方案结构 │ │ └─ 创建WPF项目解决方案 │ │ └─ 引用WPF-Control框架 │ │ └─ 配置项目依赖关系 │ ├─────────────────────────────────────────────────────────────┤ │ 1.2 数据库层设计 │ │ └─ 定义数据模型 (fm_dd_image, fm_dd_label) │ │ └─ 配置Entity Framework Core SQLite │ │ └─ 创建DbContext和数据库迁移 │ ├─────────────────────────────────────────────────────────────┤ │ 1.3 应用程序基础配置 │ │ └─ 创建App.xaml.cs (继承ApplicationBase) │ │ └─ 配置DI容器 (ConfigureServices) │ │ └─ 配置应用程序选项 (Configure) │ └─────────────────────────────────────────────────────────────┘ ↓ 阶段2核心控件层 (2-3周) ┌─────────────────────────────────────────────────────────────┐ │ 2.1 形状绘制基础接口 │ │ └─ 定义IShape接口 │ │ └─ 定义IView接口 │ │ └─ 定义IBoundingBoxable接口 │ ├─────────────────────────────────────────────────────────────┤ │ 2.2 形状基类实现 │ │ └─ ShapeBase基类 │ │ └─ TitleShapeBase基类 (带标题的形状) │ │ └─ 实现属性变更通知 (INotifyPropertyChanged) │ ├─────────────────────────────────────────────────────────────┤ │ 2.3 矩形形状实现 │ │ └─ RectShape类 (继承TitleShapeBase) │ │ └─ 实现Draw方法 (绘制矩形) │ │ └─ 实现CreateHandles方法 (创建控制点) │ │ └─ 实现Hit方法 (命中测试) │ ├─────────────────────────────────────────────────────────────┤ │ 2.4 状态机系统 │ │ └─ 定义IState接口 │ │ └─ 定义StateBase基类 │ │ └─ 实现鼠标事件处理 (MouseDown, MouseMove, MouseUp) │ ├─────────────────────────────────────────────────────────────┤ │ 2.5 形状绘制控件 │ │ └─ ShapeBox类 (继承FrameworkElement) │ │ └─ 实现VisualCollection (分层渲染) │ │ └─ 实现DrawShapes方法 │ │ └─ 实现依赖属性 (ImageSource, Shapes, Scale等) │ └─────────────────────────────────────────────────────────────┘ ↓ 阶段3业务模型层 (1-2周) ┌─────────────────────────────────────────────────────────────┐ │ 3.1 图像绑定模型 │ │ └─ ImageBindable类 (继承SelectBindablefm_dd_image) │ │ └─ 实现Shapes属性 (ObservableCollectionIShape) │ │ └─ 实现UpdateToShapes方法 (数据库标签→形状转换) │ │ └─ 实现AddShapes/DeleteShapes方法 │ ├─────────────────────────────────────────────────────────────┤ │ 3.2 文件仓储绑定模型 │ │ └─ FileRepositoryBindable类 (继承RepositoryBindable) │ │ └─ 实现RefreshData方法 (加载图像文件) │ │ └─ 实现业务命令 (RefreshCommand, ExportYoloCommand等) │ │ └─ 实现历史记录功能 │ ├─────────────────────────────────────────────────────────────┤ │ 3.3 项目管理模型 │ │ └─ FileProjectItem类 (继承ProjectItemBase) │ │ └─ 实现BaseFolder属性 │ │ └─ 实现Labels属性 (标签类别集合) │ │ └─ 实现Load/Save/Close方法 │ ├─────────────────────────────────────────────────────────────┤ │ 3.4 标签管理模型 │ │ └─ LabelItem类 (继承BindableBase) │ │ └─ 实现LabelName和LabelColor属性 │ └─────────────────────────────────────────────────────────────┘ ↓ 阶段4业务服务层 (1-2周) ┌─────────────────────────────────────────────────────────────┐ │ 4.1 项目服务 │ │ └─ FileProjectService类 (继承ProjectServiceBase) │ │ └─ 实现Create方法 (创建新项目) │ │ └─ 配置标签和收藏夹默认值 │ ├─────────────────────────────────────────────────────────────┤ │ 4.2 标签服务 │ │ └─ ProjectTagService类 (继承TagServiceBase) │ │ └─ 实现标签的加载和保存 │ ├─────────────────────────────────────────────────────────────┤ │ 4.3 收藏夹服务 │ │ └─ ProjectFavoriteService类 (继承FavoriteServiceBase) │ │ └─ 实现收藏夹的加载和保存 │ ├─────────────────────────────────────────────────────────────┤ │ 4.4 应用保存服务 │ │ └─ AppSaveService类 (实现IAppSaveService) │ │ └─ 实现定时保存功能 │ ├─────────────────────────────────────────────────────────────┤ │ 4.5 YOLO格式解析器 │ │ └─ YoloTxtParser类 │ │ └─ 实现ParseYoloFile方法 (解析YOLO格式) │ │ └─ 实现坐标转换 (归一化→像素坐标) │ ├─────────────────────────────────────────────────────────────┤ │ 4.6 YOLO格式导出器 │ │ └─ FmDdLabelYoloExporter类 │ │ └─ 实现ExportBatch方法 (批量导出) │ │ └─ 实现SaveClassNamesFile方法 (保存类别文件) │ └─────────────────────────────────────────────────────────────┘ ↓ 阶段5UI展示层 (2-3周) ┌─────────────────────────────────────────────────────────────┐ │ 5.1 图像展示器 │ │ └─ ImagePresenter类 (继承ModelBindableImageBindable) │ │ └─ 实现ViewStates属性 (标注状态集合) │ │ └─ 实现AddLabelCommand (新增标签命令) │ │ └─ 实现ShowLabelManagerCommand (标签管理命令) │ ├─────────────────────────────────────────────────────────────┤ │ 5.2 标签管理器 │ │ └─ LabelManagerPresenter类 │ │ └─ 实现标签的增删改查 │ ├─────────────────────────────────────────────────────────────┤ │ 5.3 主窗口设计 │ │ └─ MainWindow.xaml │ │ └─ 配置OutlookBar布局 (左侧中间右侧) │ │ └─ 配置菜单栏 (文件、编辑、帮助) │ │ └─ 配置数据绑定 (DataContext绑定) │ ├─────────────────────────────────────────────────────────────┤ │ 5.4 过滤器组件 │ │ └─ 实现FavoriteFileFilter (收藏过滤) │ │ └─ 实现LabelItemFilter (标签过滤) │ │ └─ 实现ScoreFileFilter (评分过滤) │ │ └─ 实现WatchedFileFilter (查看状态过滤) │ ├─────────────────────────────────────────────────────────────┤ │ 5.5 排序器组件 │ │ └─ 实现FileOrderBySize (按文件大小排序) │ │ └─ 实现FileOrderByScore (按评分排序) │ │ └─ 实现FileOrderByAccessTime (按访问时间排序) │ ├─────────────────────────────────────────────────────────────┤ │ 5.6 转换器组件 │ │ └─ 实现GetFileToViewConverter (文件→视图转换) │ │ └─ 实现GetFileToThumbImageConverter (文件→缩略图转换) │ └─────────────────────────────────────────────────────────────┘ ↓ 阶段6集成测试与优化 (1-2周) ┌─────────────────────────────────────────────────────────────┐ │ 6.1 功能测试 │ │ └─ 测试项目创建/打开/保存 │ │ └─ 测试图像加载和标注 │ │ └─ 测试过滤和排序功能 │ │ └─ 测试YOLO导入导出 │ ├─────────────────────────────────────────────────────────────┤ │ 6.2 性能优化 │ │ └─ 优化ShapeBox渲染性能 │ │ └─ 优化数据库查询性能 │ │ └─ 优化大量图像加载速度 │ ├─────────────────────────────────────────────────────────────┤ │ 6.3 用户体验优化 │ │ └─ 添加快捷键支持 │ │ └─ 优化界面响应速度 │ │ └─ 添加撤销/重做功能 │ ├─────────────────────────────────────────────────────────────┤ │ 6.4 文档编写 │ │ └─ 编写用户使用手册 │ │ └─ 编写开发者文档 │ └─────────────────────────────────────────────────────────────┘三、详细重写步骤说明阶段1基础设施层1-2周1.1 创建解决方案结构// 1. 创建新的WPF项目// 2. 添加对WPF-Control的引用// 3. 配置项目文件 (.csproj)关键文件YourLabelImg.sln- 解决方案文件YourLabelImg.csproj- 项目文件1.2 数据库层设计// 定义数据模型publicclassfm_dd_image:ObservableObject{publicintId{get;set;}publicstringUrl{get;set;}publicintPixelWidth{get;set;}publicintPixelHeight{get;set;}publicObservableCollectionfm_dd_labelLabels{get;set;}}publicclassfm_dd_label:ObservableObject{publicintId{get;set;}publicstringLabelName{get;set;}publicRectBoundingBox{get;set;}publicColorLabelColor{get;set;}}// 配置DbContextpublicclassDataContext:DbContext{publicDbSetfm_dd_imagefm_dd_images{get;set;}publicDbSetfm_dd_labelfm_dd_labels{get;set;}}1.3 应用程序基础配置publicpartialclassApp:ApplicationBase{protectedoverrideWindowCreateMainWindow(StartupEventArgse){returnnewMainWindow();}protectedoverridevoidConfigureServices(IServiceCollectionservices){base.ConfigureServices(services);services.AddApplicationServices();services.AddProjectFileProjectService();services.AddSingletonIAppSaveService,AppSaveService();}protectedoverridevoidConfigure(IApplicationBuilderapp){base.Configure(app);app.UseApplicationOptions(xx.UseModulesOptions(...));app.UseSettingDataOptions(xx.Add(AppSetting.Instance));app.UseWindowSetting();}}阶段2核心控件层2-3周2.1 形状绘制基础接口publicinterfaceIShape{voidDraw(IViewview,DrawingContextdrawingContext,Brushstroke,doublestrokeThickness1,Brushfillnull);}publicinterfaceIView{doubleScale{get;}SizeSize{get;}}publicinterfaceIBoundingBoxable{RectBoundingBox{get;}}2.2 形状基类实现publicabstractclassShapeBase:BindableBase,IShape{publicabstractvoidDraw(IViewview,DrawingContextdrawingContext,Brushstroke,doublestrokeThickness1,Brushfillnull);}publicabstractclassTitleShapeBase:ShapeBase{privatestring_Title;publicstringTitle{get{return_Title;}set{_Titlevalue;RaisePropertyChanged();}}}2.3 矩形形状实现publicclassRectShape:TitleShapeBase,IRectShape,IBoundingBoxable{publicRectRect{get;set;}publicRectBoundingBoxthis.Rect;publicoverridevoidDraw(IViewview,DrawingContextdrawingContext,Brushstroke,doublestrokeThickness1,Brushfillnull){if(this.Rect.IsZoreOrEmpty())return;drawingContext.DrawRectangle(fill,newPen(stroke,strokeThickness),Rect);this.DrawTitle(view,drawingContext,Rect.TopLeft,stroke,10/view.Scale);}protectedoverrideIEnumerableIHandleCreateHandles(){yieldreturnnewActionHandle(xthis.RectnewRect(x,this.Rect.BottomRight),this.Rect.TopLeft,this);yieldreturnnewActionHandle(xthis.RectnewRect(this.Rect.TopLeft,x),this.Rect.BottomRight,this);}}2.4 状态机系统publicinterfaceIState{ModifierKeysModifierKeys{get;set;}voidMouseDown(objectsender,MouseButtonEventArgse);voidMouseMove(objectsender,MouseEventArgse);voidMouseUp(objectsender,MouseButtonEventArgse);}publicabstractclassStateBase:IState{publicModifierKeysModifierKeys{get;set;}publicabstractvoidMouseDown(objectsender,MouseButtonEventArgse);publicabstractvoidMouseMove(objectsender,MouseEventArgse);publicabstractvoidMouseUp(objectsender,MouseButtonEventArgse);}2.5 形状绘制控件publicclassShapeBox:FrameworkElement,IView{privateVisualCollection_visualCollection;privateImageDrawingVisual_imageDrawingVisual;privateShapeDrawingVisual_shapeDrawingVisual;publicImageSourceImageSource{get;set;}publicObservableCollectionIShapeShapes{get;set;}publicdoubleScale{get;set;}1.0;publicvoidDrawShapes(){usingvardrawingContext_shapeDrawingVisual.RenderOpen();foreach(varshapeinShapes){shape.Draw(this,drawingContext,Stroke,StrokeThickness/Scale,Fill);}}}阶段3业务模型层1-2周3.1 图像绑定模型publicclassImageBindable:SelectBindablefm_dd_image{publicObservableCollectionIShapeShapes{get;set;}publicImageBindable(fm_dd_imaget):base(t){t.Labels.CollectionChanged(l,k)UpdateToShapes(t);UpdateToShapes(t);}privatevoidUpdateToShapes(fm_dd_imageimage){this.Shapes.Clear();foreach(variteminimage.Labels){varshapenewRectShape{Titleitem.LabelName,Rectitem.BoundingBox,StrokenewSolidColorBrush(item.LabelColor)};this.Shapes.Add(shape);}}}3.2 文件仓储绑定模型publicclassFileRepositoryBindable:RepositoryBindablefm_dd_image{protectedoverrideSelectBindablefm_dd_imageCreateSelectBindable(fm_dd_imageentity){returnnewImageBindable(entity);}publicoverridevoidRefreshData(paramsstring[]includes){varcollectionthis.Repository.GetList(includes).Select(xthis.CreateSelectBindable(x));this.Collection.Load(collection);}}阶段4业务服务层1-2周4.1 YOLO格式解析器publicclassYoloTxtParser{publicListfm_dd_labelParseYoloFile(fm_dd_imageimageInfo,Dictionaryint,stringclassMapping){stringtxtFilePathPath.ChangeExtension(imageInfo.Url,.txt);if(!File.Exists(txtFilePath))returnnewListfm_dd_label();string[]linesFile.ReadAllLines(txtFilePath);varlabelsnewListfm_dd_label();foreach(stringlineinlines){varlabelParseYoloLine(line,imageInfo,classMapping);if(label!null)labels.Add(label);}returnlabels;}}阶段5UI展示层2-3周5.1 主窗口设计h:MainWindowx:ClassYourLabelImg.MainWindowGridDockPanelDataContext{Binding Source{x:Static IocProject.Instance}, PathCurrent.File}!-- 左侧面板 --h:OutlookBarDockPanel.DockLefth:OutlookSectionHeader项目管理h:ProjectBox//h:OutlookSectionh:OutlookSectionHeader过滤器h:FilterBox//h:OutlookSection/h:OutlookBar!-- 中间区域 --ContentPresenterContent{Binding}/!-- 右侧面板 --h:OutlookBarDockPanel.DockRighth:OutlookSectionHeader标签列表ListBoxItemsSource{Binding Collection.SelectedItem.Shapes}//h:OutlookSection/h:OutlookBar/DockPanel/Grid/h:MainWindow四、依赖关系图┌─────────────────────────────────────────────────────────────┐ │ 依赖关系层次图 │ └─────────────────────────────────────────────────────────────┘ 第1层基础设施 ├─ WPF-Control框架 (已存在) ├─ .NET 8.0 └─ Entity Framework Core SQLite 第2层数据模型 (依赖第1层) ├─ fm_dd_image ├─ fm_dd_label └─ DataContext 第3层控件基础 (依赖第1层) ├─ IShape, IView, IBoundingBoxable ├─ ShapeBase, TitleShapeBase └─ IState, StateBase 第4层具体控件 (依赖第3层) ├─ RectShape ├─ ShapeBox └─ 状态机实现 第5层业务模型 (依赖第2、4层) ├─ ImageBindable ├─ FileRepositoryBindable └─ FileProjectItem 第6层业务服务 (依赖第5层) ├─ FileProjectService ├─ YoloTxtParser └─ FmDdLabelYoloExporter 第7层UI展示 (依赖第4、5、6层) ├─ ImagePresenter ├─ MainWindow └─ 各种过滤器和排序器 第8层应用程序 (依赖第7层) └─ App.xaml.cs