using System; using System.Runtime.InteropServices; using System.Windows.Media; using System.Windows.Media.Imaging; using Emgu.CV; using Emgu.CV.CvEnum; namespace XP.Common.Converters { /// /// 图像数据转换工具类,基于 Emgu CV 实现 /// public static class ImageConverter { /// /// 将 16 位无符号灰度数据转换为 RGB BitmapSource /// 使用 Emgu CV 的 Normalize 进行线性拉伸,CvtColor 转 BGR /// /// 16 位灰度原始数据 /// 图像宽度 /// 图像高度 /// BGR24 格式的 BitmapSource public static BitmapSource ConvertGray16ToBitmapSource(ushort[] data, int width, int height) { if (data == null) throw new ArgumentNullException(nameof(data)); if (width <= 0 || height <= 0) throw new ArgumentException("图像尺寸无效"); // 从 ushort[] 按字节拷贝构建 16 位灰度 Mat using var mat16 = new Mat(height, width, DepthType.Cv16U, 1); int byteCount = data.Length * sizeof(ushort); unsafe { fixed (ushort* pData = data) { Buffer.MemoryCopy(pData, mat16.DataPointer.ToPointer(), byteCount, byteCount); } } // 归一化到 0~255 并转为 8 位 using var mat8 = new Mat(); CvInvoke.Normalize(mat16, mat8, 0, 255, NormType.MinMax, DepthType.Cv8U); // 灰度转 BGR(立式 CT 显示需要 RGB 格式) using var matBgr = new Mat(); CvInvoke.CvtColor(mat8, matBgr, ColorConversion.Gray2Bgr); // Mat 转 BitmapSource return MatToBitmapSource(matBgr); } /// /// 将 Emgu CV Mat 转换为 WPF BitmapSource /// private static BitmapSource MatToBitmapSource(Mat mat) { int width = mat.Width; int height = mat.Height; int channels = mat.NumberOfChannels; int stride = mat.Step; byte[] pixels = new byte[height * stride]; Marshal.Copy(mat.DataPointer, pixels, 0, pixels.Length); var format = channels == 3 ? PixelFormats.Bgr24 : PixelFormats.Gray8; return BitmapSource.Create(width, height, 96, 96, format, null, pixels, stride); } } }