1. 項目概述在VisionPro中動態顯示文本標簽在機器視覺項目開發中尤其是在使用康耐視VisionPro這類強大的工具時我們經常遇到一個看似簡單卻至關重要的需求如何在圖像上清晰、動態地顯示文本信息。這個信息可能是檢測結果如“OK”或“NG”、測量數據如直徑12.34mm、狀態提示甚至是調試過程中的中間變量值。CogGraphicLabel正是VisionPro圖形顯示庫中專門用于解決這個問題的核心工具。簡單來說CogGraphicLabel就是一個可以在CogDisplay控件上繪制的文本圖形對象。與靜態的、寫在界面上的Label控件不同它是通過腳本C#或VB.NET動態創建、配置位置、內容和樣式并疊加到實時圖像或處理結果上的。這對于需要將視覺分析結果直觀“標注”在圖像上的場景來說是不可或缺的功能。無論是簡單的字符識別結果顯示還是復雜的多參數測量報告疊加CogGraphicLabel都能讓操作者一目了然。想象一下這樣的場景一個圓環零件經過視覺系統檢測我們需要在圖像上該圓環旁邊顯示“外徑25.60mm內徑15.20mm判定合格”。如果這個結果顯示在軟件界面角落的某個文本框里操作員需要來回對照圖像和數字既容易出錯又效率低下。而使用CogGraphicLabel我們可以直接將這行文本繪制在圓環圖像的旁邊實現“所見即所得”的效果。這對于齒輪檢測、孔洞尺寸測量、車牌識別結果標注等應用能極大提升人機交互的友好度和系統的專業性。2. CogGraphicLabel核心功能與屬性解析要熟練使用CogGraphicLabel首先必須深入理解它的關鍵屬性。這些屬性決定了標簽在屏幕上呈現的一切內容、位置、外觀。下面我們將逐一拆解并解釋其背后的設計邏輯和常見用法。2.1 內容與位置文本顯示的基礎CogGraphicLabel的核心是顯示文本因此與文本內容和位置相關的屬性是首先要掌握的。Text屬性這是標簽的靈魂類型為string。你需要動態賦值的所有信息都存儲在這里。例如myLabel.Text $直徑: {diameter:F2} mm;。這里有一個關鍵技巧為了確保文本能清晰顯示且不被截斷在設置Text屬性前尤其是當文本內容來自變量如測量值、識別結果時建議使用String.Format或C#的字符串插值$””來規范格式控制小數位數避免因數字過長導致顯示混亂。X和Y屬性這兩個double類型的屬性定義了標簽的錨點在顯示坐標系中的位置。這里有一個非常重要的概念錨點。(X, Y)指定的坐標點并不是文本區域的左上角或中心而是由Alignment屬性后文詳述決定的那個“對齊基準點”。例如當Alignment設置為CogGraphicLabelAlignmentConstants.TopLeft時(X, Y)就是文本包圍盒的左上角坐標如果設置為CogGraphicLabelAlignmentConstants.Center那么(X, Y)就是文本的中心點坐標。理解這一點對于精確定位標簽至關重要。通常我們會根據一個特征點如一個圓的中心、一個Blob的質心來計算標簽的期望位置。Space屬性這是一個容易被忽視但極其重要的屬性類型為CogCoordinateSpaceConstants枚舉。它定義了X和Y屬性所使用的坐標系。常見選項有CogCoordinateSpaceConstants.Pixel: 使用圖像像素坐標。這是最直接的方式標簽位置相對于圖像左上角(0,0)定義。CogCoordinateSpaceConstants.Scene: 使用“場景”坐標這是VisionPro中經過標定轉換后的物理坐標如毫米。如果你的視覺系統經過了標定并且希望標簽顯示在與物理位置對應的點上就應該使用此選項。例如測量一個圓環的外徑圓的中心坐標是通過標定后的工具得到的物理坐標那么將標簽的Space設為SceneX/Y設為該物理坐標就能確保標簽始終“跟”著特征點即使圖像分辨率或相機位置發生變化。CogCoordinateSpaceConstants.Display: 相對于顯示控件客戶區的坐標。這種方式較少用于標注圖像特征更多用于在顯示控件固定位置顯示狀態信息。實操心得在涉及物理測量的項目中強烈建議將CogGraphicLabel的Space屬性設置為CogCoordinateSpaceConstants.Scene。這樣你的文本標簽就和你的測量工具如CogCircularArc、CogLineSegment處于同一坐標系下定位邏輯清晰且能適應相機視野的變化。如果混合使用像素坐標和場景坐標進行定位會導致標簽在圖像縮放或平移時“飄走”。2.2 外觀與樣式讓信息清晰可讀光有內容和位置還不夠在復雜的工業圖像背景可能充滿紋理、反光、陰影下讓文本清晰可辨是一門學問。CogGraphicLabel提供了一系列屬性來控制其外觀。Color屬性類型為CogColor用于設置文本顏色。選擇顏色時必須考慮圖像背景。一個簡單的原則是選擇與背景區域對比度最高的顏色。例如在暗色背景上用亮色白、黃、青在亮色背景上用暗色黑、紅、深藍。VisionPro的CogColor可以通過CogColorConstants枚舉快速獲取如CogColorConstants.Green也可以通過CogColor.FromArgb(alpha, red, green, blue)方法自定義帶透明度的顏色。Font屬性類型為System.Drawing.Font。你可以像在WinForms中一樣設置字體名稱如“Arial”、“微軟雅黑”、大小和樣式加粗、斜體。字體大小的選擇需要謹慎。在場景坐標系下字體大小單位是“世界單位”如毫米這意味著如果你設置Font.Size 2文本高度就大約是2毫米。這能保證在不同放大倍數下文本的物理大小是恒定的易于閱讀。如果在像素坐標系下字體大小是像素單位放大圖像時字體會顯得很小。Alignment屬性類型為CogGraphicLabelAlignmentConstants枚舉。如前所述它決定了文本相對于(X, Y)坐標點的對齊方式。常用值包括TopLeft、TopCenter、Center、BottomRight等。這個屬性與定位邏輯緊密相關。例如如果你想在一個檢測到的斑點(CogBlob)質心正上方顯示標簽可以將Alignment設為BottomCenter然后將標簽的(X, Y)設置為斑點的質心坐標。這樣文本的底部中心點就會對準質心文本出現在斑點的正上方。其他增強屬性BackColor設置文本的背景色。在背景雜亂時給文本加一個不透明的背景色塊如半透明的黑色可以極大地提升可讀性。BackOpacity背景色的不透明度0-255。設置為128左右可以實現半透明效果既突出文字又不完全遮擋圖像細節。Selected一個bool值表示該圖形是否被選中。當為true時VisionPro會以高亮形式如虛線框顯示該圖形這在交互式調試時非常有用。3. 腳本中創建與顯示CogGraphicLabel的完整流程理解了核心屬性后我們來看如何在C#腳本中從頭開始創建并顯示一個CogGraphicLabel。這個過程可以分解為幾個清晰的步驟我們將結合一個“在檢測到的圓環中心顯示其外徑”的具體案例來講解。3.1 環境準備與引用首先確保你的VisionPro項目通常是Windows Forms或WPF應用正確引用了必要的VisionPro程序集。最主要的是Cognex.VisionPro.dll。在C#腳本文件例如一個ToolBlock的腳本工具或者一個自定義的C#腳本模塊的開頭你需要添加對應的using指令using Cognex.VisionPro; using Cognex.VisionPro.Display; // 包含CogDisplay和CogGraphicLabel // 其他可能用到的命名空間如System.Drawing用于字體 using System.Drawing;3.2 動態創建與配置標簽創建CogGraphicLabel實例非常簡單直接使用new關鍵字即可。接下來的配置才是重點。假設我們已經通過一個CogCircularArcTool測量了一個圓環并得到了一個CogCircularArc結果對象myCircle其中包含了圓心物理坐標(CenterX,CenterY)和外徑Radius。// 1. 創建CogGraphicLabel實例 CogGraphicLabel resultLabel new CogGraphicLabel(); // 2. 設置文本內容格式化測量結果保留兩位小數 double outerDiameter myCircle.Radius * 2; // 直徑半徑*2 resultLabel.Text $外徑: {outerDiameter:F2} mm; // 3. 設置位置使用圓的中心坐標 resultLabel.X myCircle.CenterX; resultLabel.Y myCircle.CenterY; // 4. 設置坐標系與測量工具保持一致使用場景坐標物理單位 resultLabel.Space CogCoordinateSpaceConstants.Scene; // 5. 設置對齊方式我們希望文本顯示在圓心的正上方所以讓文本的底部中心對準圓心點 resultLabel.Alignment CogGraphicLabelAlignmentConstants.BottomCenter; // 6. 設置外觀 // 使用綠色字體在大多數工業圖像偏灰上對比度較好 resultLabel.Color CogColorConstants.Green; // 創建字體使用“Arial”高度為3毫米場景坐標下加粗 // 注意Font構造函數中size參數在場景坐標下代表字體高度世界單位 resultLabel.Font new Font(Arial, 3.0f, FontStyle.Bold); // 設置深色半透明背景提升在復雜背景下的可讀性 resultLabel.BackColor CogColorConstants.Black; resultLabel.BackOpacity 128; // 半透明3.3 將標簽添加到顯示控件創建并配置好標簽后它只是一個內存中的對象并不會自動顯示出來。你需要將它添加到CogDisplay控件的圖形集合中。通常我們會在圖像處理流程的最后一步將結果圖形一次性添加到顯示控件。在你的窗體類或腳本上下文中需要有一個CogDisplay控件假設名為cogDisplay1的引用。// 清除顯示控件上之前添加的所有臨時圖形可選根據需求決定 cogDisplay1.InteractiveGraphics.Clear(); cogDisplay1.StaticGraphics.Clear(); // 將我們創建的結果標簽添加到靜態圖形集合中 // StaticGraphics用于顯示不需要交互的、結果性的圖形 cogDisplay1.StaticGraphics.Add(resultLabel, ResultLabel); // 如果你還需要顯示其他圖形比如圓環本身 CogGraphicCircle circleGraphic new CogGraphicCircle(); circleGraphic.Set(myCircle); circleGraphic.Color CogColorConstants.Cyan; cogDisplay1.StaticGraphics.Add(circleGraphic, MeasuredCircle); // 最后刷新顯示控件使所有更改生效 cogDisplay1.Refresh();關鍵點解析InteractiveGraphics和StaticGraphics這是CogDisplay的兩個核心圖形容器。InteractiveGraphics中的圖形通常用于交互如手動繪制ROI可以被用戶選擇和拖動。StaticGraphics中的圖形則是只讀的用于顯示最終的、固定的結果。對于CogGraphicLabel這類純信息展示的圖形放入StaticGraphics是更合適的選擇。Add方法的第二個參數這是一個圖形名稱的標識符字符串可以為空但建議賦予一個有意義的名稱如“ResultLabel”。這樣便于在后續代碼中通過名稱查找、更新或刪除特定的圖形。Refresh()方法在修改了圖形集合后必須調用Refresh()來通知控件重繪否則更改可能不會立即顯示在屏幕上。3.4 封裝與復用創建標簽工具函數在實際項目中我們可能需要在不同地方創建風格一致的標簽。為了避免代碼重復可以將其封裝成一個工具函數。public CogGraphicLabel CreateMeasurementLabel(double x, double y, string text, CogCoordinateSpaceConstants space CogCoordinateSpaceConstants.Scene, CogColor color null, string fontName Arial, float fontSize 2.5f) { CogGraphicLabel label new CogGraphicLabel(); label.Text text; label.X x; label.Y y; label.Space space; label.Alignment CogGraphicLabelAlignmentConstants.BottomCenter; // 常用對齊方式 // 默認顏色為綠色如果傳入顏色則使用傳入的 label.Color color ?? CogColorConstants.Green; // 創建字體默認加粗 label.Font new Font(fontName, fontSize, FontStyle.Bold); // 默認添加半透明黑色背景 label.BackColor CogColorConstants.Black; label.BackOpacity 128; return label; } // 使用示例 CogGraphicLabel label1 CreateMeasurementLabel(centerX, centerY, $直徑: {diam:F2}mm); CogGraphicLabel label2 CreateMeasurementLabel(posX, posY, 狀態: OK, color: CogColorConstants.Cyan); cogDisplay1.StaticGraphics.Add(label1, DiamLabel); cogDisplay1.StaticGraphics.Add(label2, StatusLabel);4. 高級應用與實戰技巧掌握了基礎用法后我們可以探索一些更高級和實用的場景這些技巧能顯著提升你的VisionPro應用的專業性和用戶體驗。4.1 多標簽管理與布局策略當一個畫面中需要顯示多個信息時例如多齒輪檢測每個齒輪都需要顯示編號和狀態雜亂無章的標簽會讓人眼花繚亂。我們需要管理策略。使用集合管理不要散落著創建多個標簽變量。可以使用ListCogGraphicLabel來統一管理。ListCogGraphicLabel allLabels new ListCogGraphicLabel(); foreach (var gearResult in gearResults) { var label CreateMeasurementLabel(...); allLabels.Add(label); cogDisplay1.StaticGraphics.Add(label, $Gear_{gearResult.ID}); }智能避讓當兩個特征點距離很近時它們的標簽可能會重疊。一個簡單的策略是根據特征點的Y坐標從上到下對標簽進行排序然后動態調整Y軸偏移量。// 假設features是一個包含位置信息的列表 var sortedFeatures features.OrderBy(f f.Y).ToList(); float verticalSpacing 5.0f; // 標簽垂直間距單位毫米場景坐標 float currentYOffset 0; foreach (var feat in sortedFeatures) { // 在原始Y坐標基礎上增加一個偏移避免重疊 float labelY (float)feat.Y currentYOffset; var label CreateMeasurementLabel(feat.X, labelY, ...); // ... 添加標簽 currentYOffset verticalSpacing; // 為下一個標簽增加偏移 }分組與顏色編碼用顏色區分不同類型的信息。例如測量值用白色合格結果用綠色超差結果用紅色警告信息用黃色。CogColor statusColor; if (result.IsPass) statusColor CogColorConstants.Green; else if (result.IsWarning) statusColor CogColorConstants.Yellow; else statusColor CogColorConstants.Red;4.2 與VisionPro工具深度集成CogGraphicLabel的真正威力在于與其他VisionPro工具的運行時結果無縫集成。在ToolBlock腳本中直接使用這是最常見的場景。在ToolBlock的“腳本”工具中你可以訪問上游工具的輸出變量并創建標簽來顯示它們。// 在ToolBlock腳本中Inputs和Outputs是預定義對象 // 假設上游有一個CogPMAlignTool輸出名為“Pose” ICogTransform2D partPose Inputs.Pose; // 獲取部件位置 // 假設還有一個CogCaliperTool輸出名為“Width” double measuredWidth Inputs.Width; // 創建顯示位置的標簽 CogGraphicLabel poseLabel new CogGraphicLabel(); poseLabel.Text $位置: ({partPose.TranslationX:F1}, {partPose.TranslationY:F1}); poseLabel.X partPose.TranslationX; poseLabel.Y partPose.TranslationY 5; // 在位置點下方5mm處顯示 poseLabel.Space CogCoordinateSpaceConstants.Scene; poseLabel.Color CogColorConstants.White; // 將標簽添加到腳本工具的圖形輸出中 Outputs.AddGraphicLabelToDisplay(poseLabel, “PoseInfo”);注意在ToolBlock腳本中通常不直接操作CogDisplay控件而是通過Outputs.AddGraphicToDisplay()或類似方法將圖形添加到輸出集合由VisionPro框架負責將其渲染到關聯的顯示控件上。標注Blob分析結果對于CogBlobTool你可能想標注每個斑點的面積、質心位置。CogBlobResult blobResult myBlobTool.Results; // 假設已運行并獲取結果 foreach (CogBlobResultItem blob in blobResult.GetBlobs()) { string info $Area: {blob.Area:F0}\nCentroid: ({blob.CenterX:F1}, {blob.CenterY:F1}); var label CreateMeasurementLabel(blob.CenterX, blob.CenterY, info); label.Alignment CogGraphicLabelAlignmentConstants.TopCenter; // 信息較多放在質心上方 cogDisplay1.StaticGraphics.Add(label, $Blob_{blob.Id}); }動態更新標簽內容在連續運行如Live Display模式下標簽內容需要隨著每一幀的新結果而更新。與其不斷創建新標簽不如復用已有的標簽對象并更新其Text屬性。// 在初始化時創建標簽并保存引用 private CogGraphicLabel _fpsLabel; void InitializeDisplay() { _fpsLabel new CogGraphicLabel(); _fpsLabel.Space CogCoordinateSpaceConstants.Display; // 使用顯示坐標固定在界面角落 _fpsLabel.X 10; // 距離左邊10像素 _fpsLabel.Y 10; // 距離頂部10像素 _fpsLabel.Alignment CogGraphicLabelAlignmentConstants.TopLeft; _fpsLabel.Color CogColorConstants.Yellow; cogDisplay1.StaticGraphics.Add(_fpsLabel, “FPS”); } // 在每一幀處理完成后更新它 void ProcessFrame() { // ... 圖像處理邏輯 double currentFPS CalculateFPS(); _fpsLabel.Text $FPS: {currentFPS:F1}; // 只更新文本無需重新添加圖形 cogDisplay1.Refresh(); }4.3 性能優化與內存管理在高速、連續運行的視覺系統中圖形渲染可能成為性能瓶頸。不當使用CogGraphicLabel可能導致內存泄漏或界面卡頓。避免在循環中重復創建如果在每一幀的處理循環中都new CogGraphicLabel()并添加而不清理舊的StaticGraphics集合會無限膨脹最終消耗大量內存并導致程序變慢甚至崩潰。正確的更新模式清除-重建模式適用于結果圖形每次完全變化的場景。在每次處理前清除所有靜態圖形然后根據新結果創建全新的標簽。這是最簡單直接的方式。cogDisplay1.StaticGraphics.Clear(); foreach (var newResult in latestResults) { var label new CogGraphicLabel(); // 創建新的 // ... 配置label cogDisplay1.StaticGraphics.Add(label); }復用-更新模式適用于圖形結構穩定僅內容變化的場景如固定在角落的FPS顯示、狀態燈。在初始化時創建圖形并保存引用后續只更新其屬性如Text,Color。控制圖形數量在需要顯示大量標簽如上百個時考慮是否所有信息都是必要的。或許可以只顯示異常結果或者通過鼠標懸停Tooltip的方式來顯示詳細信息。使用using語句對于非托管資源雖然CogGraphicLabel本身是托管對象但其底層與顯示系統交互養成良好的習慣對于確定不再使用的、獨立創建的圖形對象如果后續不再需要可以考慮將其從圖形集合中移除并置為null以幫助垃圾回收。但通常更關鍵的是管理好StaticGraphics集合本身。5. 常見問題排查與調試技巧實錄即使按照步驟操作在實際開發中你仍可能遇到一些問題。下面是我在多年項目中總結的一些典型問題及其解決方法。5.1 標簽不顯示或位置不對這是新手最常遇到的問題可以從以下幾個維度排查問題現象可能原因排查步驟與解決方案標簽完全看不見1. 未將標簽添加到CogDisplay的圖形集合中。2. 添加后沒有調用Refresh()。3. 標簽的坐標遠超出當前顯示視野。4. 標簽顏色與背景色完全相同。1. 檢查代碼是否有cogDisplay.StaticGraphics.Add(label, ...)。2. 確保在添加圖形后調用了cogDisplay.Refresh()。3. 檢查X,Y坐標值是否合理。嘗試先設置為(0,0)或一個已知的特征點坐標看是否出現。4. 將Color設置為一個高對比度顏色如CogColorConstants.Red測試。標簽位置偏離預期1.Space屬性設置錯誤坐標系統一。2.Alignment屬性理解有誤錨點不對。3. 提供的X,Y坐標值本身有誤。1.這是最常見的原因確認你的X,Y來源如工具結果使用什么坐標系像素/場景并確保標簽的Space屬性與之匹配。如果不匹配需要進行坐標轉換。2. 畫圖理解在紙上畫一個點作為(X,Y)根據你設置的Alignment如TopLeft,Center畫出文本包圍盒應該出現的位置。這能幫你快速理解對齊邏輯。3. 在調試器中輸出你用來設置X,Y的變量值檢查是否正確。標簽在圖像縮放/平移時“亂跑”Space屬性使用不當。在圖像縮放時使用Pixel坐標的標簽會相對于圖像像素移動而使用Scene坐標的標簽會保持在物理世界的位置。如果你的應用涉及標定和物理測量始終堅持使用Scene坐標系來創建結果標簽。確保你的圖像顯示控件正確關聯了標定空間CogDisplay的SpaceTree屬性。5.2 文本顯示模糊或大小異常字體模糊通常發生在將低分辨率的位圖字體進行非整數倍縮放時。確保CogDisplay控件的縮放模式Zoom屬性設置合理盡量避免使用“縮放到適合”等導致非整數倍縮放的模式進行精細查看。使用常見的TrueType字體如Arial, Tahoma通常比系統點陣字體效果更好。字體大小異常牢記Font.Size在場景坐標下的意義。如果你設置Font.Size 10且Space Scene那么文本高度就是10個世界單位如10毫米。如果你覺得字太大或太小請檢查你的標定關系是否正確即一個像素代表多少毫米。在像素坐標下(Space Pixel)Font.Size的單位是像素數值通常較小如12, 14。5.3 在ToolBlock腳本中圖形不顯示在VisionPro的ToolBlock腳本工具中你不能直接操作UI線程上的CogDisplay控件。必須通過VisionPro提供的特定接口來輸出圖形。錯誤做法在腳本中直接new CogGraphicLabel()并嘗試添加到某個窗體控件的集合中。正確做法使用腳本工具的Outputs集合的圖形添加方法。// 在ToolBlock腳本工具中 CogGraphicLabel myLabel new CogGraphicLabel(); // ... 配置myLabel // 關鍵步驟通過Outputs的圖形添加方法傳遞出去 Outputs.AddGraphicLabelToDisplay(myLabel, “MyOutputLabel”); // 或者使用更通用的方法 // Outputs.AddGraphicToDisplay(myLabel, “MyOutputLabel”);然后在ToolBlock編輯器中你需要將該腳本工具的“圖形”輸出端口通常是一個名為“Graphics”的集合連接到下游通常是“CogDisplay”類型的終端工具或者直接連接到Job的圖形輸出。這樣VisionPro運行框架才會自動將這些圖形渲染到關聯的顯示窗口。5.4 內存泄漏與性能排查如果長時間運行后軟件變慢可以按以下步驟排查檢查圖形集合在調試模式下在運行一段時間后檢查cogDisplay1.StaticGraphics.Count的數量。如果這個數字持續增長說明舊的圖形沒有被清理存在“只加不刪”的問題。審查代碼邏輯確認在每次更新結果前是否調用了Clear()方法清除了不再需要的舊圖形。或者是否采用了正確的“復用-更新”模式。使用性能分析工具如果問題復雜可以使用Visual Studio的性能分析器Performance Profiler查看CogGraphicLabel對象的分配和存活情況定位沒有被釋放的對象。一個實用的調試技巧在開發階段可以臨時添加一個顯示當前圖形數量的標簽幫助你監控。// 在某個更新顯示的函數中 int graphicCount cogDisplay1.StaticGraphics.Count cogDisplay1.InteractiveGraphics.Count; _debugLabel.Text $圖形數量: {graphicCount}; // _debugLabel是一個預先創建好的、固定在角落的標簽如果發現這個數量只增不減你就知道問題出在哪里了。