public void Cross(Vector v1, Vector v2) { X = (v1.Y * v2.Z) - (v1.Z * v2.Y); Y = -(v1.X * v2.Z) - (v1.Z * v2.X); Z = (v1.X * v2.Y) - (v1.Z * v2.X); }
private static unsafe ImageData ReadImageData(IDictionary<uint, Element> dataset) { var imageData = new ImageData(); var element = dataset[Dicom.ReverseDictionary["PixelData"]]; imageData.PixelData = element.Value[0].Bytes; element = dataset[Dicom.ReverseDictionary["Rows"]]; imageData.Rows = (int)element.Value[0].Long; element = dataset[Dicom.ReverseDictionary["Columns"]]; imageData.Columns = (int)element.Value[0].Long; element = dataset[Dicom.ReverseDictionary["WindowWidth"]]; imageData.WindowWidth = element.Value[0].Double; element = dataset[Dicom.ReverseDictionary["WindowCenter"]]; imageData.WindowCenter = element.Value[0].Double; element = dataset[Dicom.ReverseDictionary["RescaleIntercept"]]; imageData.RescaleIntercept = element.Value[0].Double; element = dataset[Dicom.ReverseDictionary["RescaleSlope"]]; imageData.RescaleSlope = element.Value[0].Double; element = dataset[Dicom.ReverseDictionary["ImageOrientationPatient"]]; imageData.ImageOrientationPatient = (from v in element.Value select v.Double).ToArray(); element = dataset[Dicom.ReverseDictionary["ImagePositionPatient"]]; imageData.ImagePositionPatient = (from v in element.Value select v.Double).ToArray(); // Calculate SliceLocation. var x = new Vector { X = imageData.ImageOrientationPatient[0], Y = imageData.ImageOrientationPatient[1], Z = imageData.ImageOrientationPatient[2] }; var y = new Vector { X = imageData.ImageOrientationPatient[3], Y = imageData.ImageOrientationPatient[4], Z = imageData.ImageOrientationPatient[5] }; var z = new Vector(); z.Cross(x, y); imageData.SliceLocation = imageData.ImagePositionPatient[0] * z.X + imageData.ImagePositionPatient[1] * z.Y + imageData.ImagePositionPatient[2] * z.Z; // Check pixel padding value - application is later. element = dataset[Dicom.ReverseDictionary["PixelRepresentation"]]; var pixelRepresentation = element.Value[0].Long; var pixelPaddingValue = long.MinValue; var pixelPaddingValueId = Dicom.ReverseDictionary["PixelPaddingValue"]; if (dataset.ContainsKey(pixelPaddingValueId)) { element = dataset[pixelPaddingValueId]; pixelPaddingValue = element.Value[0].Long; if (pixelRepresentation == 1) { pixelPaddingValue -= ushort.MinValue; } } // Convert to unsigned short pixel data. if (pixelRepresentation == 1) // Need to convert to unsigned short. { fixed (byte* pixelData = imageData.PixelData) { var shortPixelData = (short*)pixelData; var ushortPixelData = (ushort*)pixelData; var pixelCount = imageData.Rows * imageData.Columns; for (var i = 0; i < pixelCount; i++) { ushortPixelData[i] = (ushort)(shortPixelData[i] - short.MinValue); } } imageData.RescaleIntercept -= short.MinValue; } // Apply pixel padding value and record minimum and maximum intensities. fixed (byte* pixelData = imageData.PixelData) { var ushortPixelData = (ushort*)pixelData; var pixelCount = imageData.Rows * imageData.Columns; for (var i = 0; i < pixelCount; i++) { if (ushortPixelData[i] == pixelPaddingValue) { ushortPixelData[i] = 0; } var value = ushortPixelData[i]; imageData.MinIntensity = Math.Min(imageData.MinIntensity, value); imageData.MaxIntensity = Math.Max(imageData.MaxIntensity, value); } } // Calculate image physical dimensions in mm. element = dataset[Dicom.ReverseDictionary["PixelSpacing"]]; var pixelSpacing = element; imageData.Width = imageData.Columns * pixelSpacing.Value[0].Double; imageData.Height = imageData.Rows * pixelSpacing.Value[0].Double; return imageData; }