优化高级模块CNC执行的可视化

CNC执行 → PipelineExecutionService(返回 LastStepOutputData)
                  → CncExecutionService(调用 PushDetectionOverlay)
                  → MainViewportService(触发 DetectionOverlayUpdated 事件)
                  → ViewportPanelView(订阅事件,调用 DetectionOverlayRenderer)
                  → PolygonRoiCanvas.SetDetectionOverlayCanvas(插入叠加层 Canvas)
This commit is contained in:
zhengxuan.zhang
2026-05-19 14:10:16 +08:00
parent eb6ee48a5e
commit 1546aec567
11 changed files with 279 additions and 135 deletions
@@ -207,65 +207,12 @@ public class VoidMeasurementProcessor : ImageProcessorBase
OutputData["Voids"] = voids;
OutputData["ResultText"] = $"Void: {voidRate:F1}% | {classification} | {voids.Count} voids | ROI: {roiArea}px";
// 渲染带标注的彩色结果图像
OutputData["RenderedResultImage"] = RenderAnnotatedResult(inputImage, voids, voidRate, voidLimit, classification);
blurred.Dispose();
voidImg.Dispose();
roiMask.Dispose();
return inputImage.Clone();
}
/// <summary>
/// 渲染带标注的彩色结果图像(轮廓、编号、半透明填充、总览信息)
/// </summary>
private Image<Bgr, byte> RenderAnnotatedResult(Image<Gray, byte> grayImage, List<VoidRegionInfo> voids, double voidRate, double voidLimit, string classification)
{
var colorImage = new Image<Bgr, byte>(grayImage.Width, grayImage.Height);
CvInvoke.CvtColor(grayImage, colorImage, ColorConversion.Gray2Bgr);
if (voids.Count == 0)
return colorImage;
// 半透明气泡填充
var overlay = colorImage.Clone();
foreach (var v in voids)
{
if (v.ContourPoints.Length > 0)
{
using var vop = new VectorOfPoint(v.ContourPoints);
using var vvop = new VectorOfVectorOfPoint(vop);
CvInvoke.DrawContours(overlay, vvop, 0, new MCvScalar(0, 200, 255), -1);
}
}
CvInvoke.AddWeighted(overlay, 0.4, colorImage, 0.6, 0, colorImage);
overlay.Dispose();
// 绘制轮廓 + 编号
foreach (var v in voids)
{
if (v.ContourPoints.Length > 0)
{
using var vop = new VectorOfPoint(v.ContourPoints);
using var vvop = new VectorOfVectorOfPoint(vop);
CvInvoke.DrawContours(colorImage, vvop, 0, new MCvScalar(0, 255, 255), 1);
}
CvInvoke.PutText(colorImage, $"#{v.Index}",
new Point((int)v.CenterX - 8, (int)v.CenterY + 5),
FontFace.HersheySimplex, 0.35, new MCvScalar(255, 100, 0), 1);
}
// 左上角总览
var overallColor = classification == "PASS"
? new MCvScalar(0, 255, 0) : new MCvScalar(0, 0, 255);
CvInvoke.PutText(colorImage,
$"Void: {voidRate:F1}% | Limit: {voidLimit:F0}% | {voids.Count} voids | {classification}",
new Point(10, 25),
FontFace.HersheySimplex, 0.5, overallColor, 2);
return colorImage;
}
}
/// <summary>