在C#、Keras.Net中转换语义分割预测结果为Bitmap的技术问询
解决C#中语义分割Argmax结果转Bitmap的问题
先明确返回对象的实际类型
首先要确定ImageUtil.ArrayToImg返回的System对象具体是什么类型,调试时可通过以下代码查看:
var result = ImageUtil.ArrayToImg(yourArgmaxResultArray); Console.WriteLine(result.GetType().FullName); // 打印完整类型名
针对常见返回类型的转换方案
1. 返回类型为System.Drawing.Image
Bitmap是Image的子类,可直接强制转换,或用安全转换避免异常:
// 直接强制转换(确定类型匹配时用) Bitmap bitmap = (Bitmap)ImageUtil.ArrayToImg(yourArgmaxResultArray); // 安全转换+空检查(推荐) var img = ImageUtil.ArrayToImg(yourArgmaxResultArray) as Image; if (img != null) { Bitmap bitmap = new Bitmap(img); }
2. 返回类型为byte[](RGB字节流)
如果返回的是图像字节数组,通过MemoryStream构建Bitmap:
var imgBytes = ImageUtil.ArrayToImg(yourArgmaxResultArray) as byte[]; if (imgBytes != null) { using (var ms = new MemoryStream(imgBytes)) { Bitmap bitmap = new Bitmap(ms); } }
手动实现Argmax数组转Bitmap(如果ImageUtil不可靠)
如果ImageUtil的方法不符合需求,可直接基于Argmax结果(类别索引数组)生成Bitmap:
- 先定义类别与颜色的映射关系:
// 根据你的语义分割类别数量自定义 var classColorMap = new Dictionary<int, Color> { {0, Color.Black}, // 背景类 {1, Color.Red}, // 类别1 {2, Color.Green}, // 类别2 // ... 其他类别 };
- 高效生成Bitmap(推荐用
LockBits替代SetPixel,适合大尺寸图像):
// 假设argmaxArray是int[,]类型,尺寸为[height, width] int height = argmaxArray.GetLength(0); int width = argmaxArray.GetLength(1); Bitmap bitmap = new Bitmap(width, height); Rectangle rect = new Rectangle(0, 0, width, height); var bmpData = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); IntPtr ptr = bmpData.Scan0; int stride = bmpData.Stride; byte[] pixelBuffer = new byte[stride * height]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int classId = argmaxArray[y, x]; Color color = classColorMap.TryGetValue(classId, out var c) ? c : Color.Gray; int bufferIndex = y * stride + x * 3; pixelBuffer[bufferIndex] = color.B; // B通道 pixelBuffer[bufferIndex + 1] = color.G; // G通道 pixelBuffer[bufferIndex + 2] = color.R; // R通道 } } Marshal.Copy(pixelBuffer, 0, ptr, pixelBuffer.Length); bitmap.UnlockBits(bmpData);
内容的提问来源于stack exchange,提问作者vuict
相关产品推荐
相关产品推荐

