/// <summary> /// 图片转换dcm /// </summary> /// <param name="file"></param> public static void Image2dcm(Img2DcmOptions options) { if (options.images.Count <= 0) { Console.WriteLine("请传入图片路径"); return; } // 取第一张图片作为基准图片 Bitmap bitmap = new Bitmap(@options.images[0]); byte[] pixels = GetPixels(bitmap); MemoryByteBuffer buffer = new MemoryByteBuffer(pixels); DicomDataset dataset = new DicomDataset(); dataset.Add(DicomTag.SpecificCharacterSet, "GB18030"); // 写入tag数据 dataset.Add(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Rgb.Value); dataset.Add(DicomTag.Rows, (ushort)bitmap.Height); dataset.Add(DicomTag.Columns, (ushort)bitmap.Width); dataset.Add(DicomTag.BitsAllocated, (ushort)8); dataset.Add(DicomTag.SOPClassUID, "1.2.840.10008.5.1.4.1.1.2"); dataset.Add(DicomTag.SOPInstanceUID, "1.2.840.10008.5.1.4.1.1.2." + GetTimeStamp()); dataset.Add(DicomTag.PatientName, Encoding.Default, string.IsNullOrEmpty(options.patientName) ? "test" : options.patientName); dataset.Add(DicomTag.PatientID, string.IsNullOrEmpty(options.patientID) ? Guid.NewGuid().ToString("N") : options.patientID); dataset.Add(DicomTag.StudyInstanceUID, "1.2.3.4.5.6.7.8.9.11." + GetTimeStamp()); dataset.Add(DicomTag.StudyDate, DateTime.Now.ToString("yyyyMMdd")); dataset.Add(DicomTag.StudyTime, DateTime.Now.ToString("HHmmss")); dataset.Add(DicomTag.StudyID, GetTimeStamp()); dataset.Add(DicomTag.Modality, "CT"); dataset.Add(DicomTag.SeriesInstanceUID, "1.2.3.4.5.6.7.8.9.11." + GetTimeStamp()); dataset.Add(DicomTag.InstanceNumber, "1000"); DicomPixelData pixelData = DicomPixelData.Create(dataset, true); pixelData.BitsStored = 8; pixelData.SamplesPerPixel = 3; pixelData.HighBit = 7; pixelData.PixelRepresentation = 0; pixelData.PlanarConfiguration = 0; pixelData.AddFrame(buffer); // 如果图片大于等于两张,则继续追加 if (options.images.Count >= 2) { for (var i = 1; i < options.images.Count; i++) { Bitmap addBit = new Bitmap(@options.images[i]); byte[] addPixels = GetPixels(addBit); MemoryByteBuffer addBuffer = new MemoryByteBuffer(addPixels); pixelData.AddFrame(addBuffer); } } // 保存dcm文件 DicomFile dicomfile = new DicomFile(dataset); dicomfile.Save(@options.outDcm); Console.WriteLine("success:jpg转dcm成功"); }
public static NativePixelData ToNativePixelData(this DicomPixelData dicomPixelData) { return(new NativePixelData { NumberOfFrames = dicomPixelData.NumberOfFrames, Width = dicomPixelData.Width, Height = dicomPixelData.Height, SamplesPerPixel = dicomPixelData.SamplesPerPixel, HighBit = dicomPixelData.HighBit, BitsStored = dicomPixelData.BitsStored, BitsAllocated = dicomPixelData.BitsAllocated, BytesAllocated = dicomPixelData.BytesAllocated, UncompressedFrameSize = dicomPixelData.UncompressedFrameSize, PlanarConfiguration = (int)dicomPixelData.PlanarConfiguration, PixelRepresentation = (int)dicomPixelData.PixelRepresentation, TransferSyntaxIsLossy = dicomPixelData.Syntax.IsLossy, PhotometricInterpretation = dicomPixelData.PhotometricInterpretation.Value, GetFrameImpl = index => dicomPixelData.GetFrame(index).Data, AddFrameImpl = buffer => dicomPixelData.AddFrame(new MemoryByteBuffer(buffer)), SetPlanarConfigurationImpl = value => dicomPixelData.PlanarConfiguration = (PlanarConfiguration)value, SetPhotometricInterpretationImpl = value => dicomPixelData.PhotometricInterpretation = PhotometricInterpretation.Parse(value) }); }
public void ExportImage(Bitmap bitmap) { bitmap = GetValidImage(bitmap); int rows, columns; byte[] pixels = GetPixels(bitmap, out rows, out columns); MemoryByteBuffer buffer = new MemoryByteBuffer(pixels); DicomDataset dataset = new DicomDataset(); FillDataset(dataset); dataset.Add(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Rgb.Value); dataset.Add(DicomTag.Rows, (ushort)rows); dataset.Add(DicomTag.Columns, (ushort)columns); dataset.AddOrUpdate(DicomTag.BitsAllocated, (ushort)8); DicomPixelData pixelData = DicomPixelData.Create(dataset, true); pixelData.BitsStored = 8; pixelData.BitsAllocated = 8; pixelData.SamplesPerPixel = 3; pixelData.HighBit = 7; pixelData.PixelRepresentation = 0; pixelData.PlanarConfiguration = 0; pixelData.AddFrame(buffer); DicomFile dicomfile = new DicomFile(dataset); dicomfile.Save("dicomfile.dcm"); }
public DicomFile GetDicom(Image <Gray, byte> outputImage, DicomInformation dicomInformation) { var bitmap = outputImage.Bitmap; bitmap = GetValidImage(bitmap); int rows, columns; byte[] pixels = GetPixels(bitmap, out rows, out columns); MemoryByteBuffer buffer = new MemoryByteBuffer(pixels); DicomDataset dataset = new DicomDataset(); FillDataset(dataset, dicomInformation); dataset.Add(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Rgb.Value); dataset.Add(DicomTag.Rows, (ushort)rows); dataset.Add(DicomTag.Columns, (ushort)columns); dataset.Add(DicomTag.BitsAllocated, (ushort)8); DicomPixelData pixelData = DicomPixelData.Create(dataset, true); pixelData.BitsStored = 8; pixelData.BitsAllocated = 8; pixelData.SamplesPerPixel = 3; pixelData.HighBit = 7; pixelData.PixelRepresentation = 0; pixelData.PlanarConfiguration = 0; pixelData.AddFrame(buffer); DicomFile dicomfile = new DicomFile(dataset); return(dicomfile); }
/// <summary> /// The GetDicomFileByRaw. /// </summary> /// <param name="pixels">The pixels<see cref="byte[]"/>.</param> /// <param name="Heigh">The Heigh<see cref="int"/>.</param> /// <param name="width">The width<see cref="int"/>.</param> /// <returns>The <see cref="DicomFile"/>.</returns> public static DicomFile GetDicomFileByRaw(byte[] pixels, int Heigh, int width) { MemoryByteBuffer buffer = new MemoryByteBuffer(pixels); DicomDataset dataset = new DicomDataset(); //FillDataset(dataset); dataset.AddOrUpdate(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Monochrome2.Value); // dataset.Add(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Monochrome2.ToString()); dataset.AddOrUpdate(DicomTag.Rows, (ushort)Heigh); dataset.AddOrUpdate(DicomTag.Columns, (ushort)width); dataset.AddOrUpdate(DicomTag.BitsAllocated, (ushort)16); dataset.AddOrUpdate(DicomTag.SOPClassUID, "1.2.840.10008.5.1.4.1.1.2"); dataset.Add(DicomTag.SOPInstanceUID, "1.2.840.10008.5.1.4.1.1.2.20181120090837121314"); DicomPixelData pixelData = DicomPixelData.Create(dataset, true); pixelData.BitsStored = 16; //pixelData.BitsAllocated = 8; pixelData.SamplesPerPixel = pixelData.HighBit = 15; pixelData.PixelRepresentation = 0; pixelData.PlanarConfiguration = 0; pixelData.AddFrame(buffer); DicomFile dicomfile = new DicomFile(dataset); // dicomfile.Save(@"C:\Users\admin\Pictures\Saved Pictures\" + System.DateTime.Now.ToString("FFFF")); ; return(dicomfile); }
internal void DrawBlackBoxWithWhiteText(DicomDataset ds, int width, int height, string msg) { var bitmap = new Bitmap(500, 500); using (var g = Graphics.FromImage(bitmap)) { g.FillRectangle(blackBrush, 0, 0, width, height); g.DrawString(msg, new Font(FontFamily.GenericMonospace, 12), whiteBrush, 250, 100); } byte[] pixels = GetPixels(bitmap, out int rows, out int columns); MemoryByteBuffer buffer = new MemoryByteBuffer(pixels); ds.Add(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Rgb.Value); ds.Add(DicomTag.Rows, (ushort)rows); ds.Add(DicomTag.Columns, (ushort)columns); ds.Add(DicomTag.BitsAllocated, (ushort)8); DicomPixelData pixelData = DicomPixelData.Create(ds, true); pixelData.BitsStored = 8; pixelData.SamplesPerPixel = 3; pixelData.HighBit = 7; pixelData.PixelRepresentation = 0; pixelData.PlanarConfiguration = 0; pixelData.AddFrame(buffer); }
public static void ImportImage() { Bitmap bitmap = new Bitmap(@"C:\Users\ryan.chang\Desktop\output\testabc.bmp"); //bitmap = GetValidImage(bitmap); byte[] pixels = GetPixels(bitmap); MemoryByteBuffer buffer = new MemoryByteBuffer(pixels); DicomDataset dataset = new DicomDataset(); //FillDataset(dataset); dataset.Add(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Rgb.Value); dataset.Add(DicomTag.Rows, (ushort)bitmap.Height); dataset.Add(DicomTag.Columns, (ushort)bitmap.Width); dataset.Add(DicomTag.BitsAllocated, (ushort)8); dataset.Add(DicomTag.SOPClassUID, "1.2.840.10008.5.1.4.1.1.7"); dataset.Add(DicomTag.StudyInstanceUID, "1.2.840.10008.5.1.4.1.1.2.20181120090837121311"); dataset.Add(DicomTag.SeriesInstanceUID, "1.2.840.10008.5.1.4.1.1.2.20181120090837121312"); dataset.Add(DicomTag.SOPInstanceUID, "1.2.840.10008.5.1.4.1.1.2.20181120090837121314"); dataset.Add(DicomTag.TransferSyntaxUID, "1.2.840.10008.1.2.4.70"); //dataset.Add(DicomTag.SpecificCharacterSet, "ISO_IR 192"); //dataset.Add(new DicomPersonName(DicomTag.PatientName,Encoding.UTF8,"王曉明")); DicomPixelData pixelData = DicomPixelData.Create(dataset, true); pixelData.BitsStored = 8; //pixelData.BitsAllocated = 8; pixelData.SamplesPerPixel = 3; pixelData.HighBit = 7; pixelData.PixelRepresentation = 0; pixelData.PlanarConfiguration = 0; pixelData.AddFrame(buffer); DicomFile dicomfile = new DicomFile(dataset); dicomfile.Save(@"C:\Users\ryan.chang\Desktop\output\dicomfile.dcm"); }
static DicomFile CreatDicomFileNoDicomImage(DicomFile dicomFile) { byte[] temp = new byte[512 * 512]; dicomFile.Dataset.AddOrUpdate(DicomTag.Rows, (ushort)512); dicomFile.Dataset.AddOrUpdate(DicomTag.Columns, (ushort)512); dicomFile.Dataset.AddOrUpdate(DicomTag.BitsAllocated, (ushort)16); dicomFile.Dataset.TryGetString(DicomTag.SOPInstanceUID, out string str); if (str == null) { dicomFile.Dataset.Add(DicomTag.SOPInstanceUID, "1.1.1.1.1.1"); } MemoryByteBuffer buffer = new MemoryByteBuffer(temp); DicomPixelData pixelData = DicomPixelData.Create(dicomFile.Dataset, true); pixelData.BitsStored = 16; //pixelData.BitsAllocated = 8; pixelData.SamplesPerPixel = pixelData.HighBit = 15; pixelData.PixelRepresentation = 0; pixelData.PlanarConfiguration = 0; pixelData.AddFrame(buffer); dicomFile = new DicomFile(dicomFile.Dataset); return(dicomFile); }
public static void SaveToDICOMFile(short[] pixels,int noRows,int noCols,string fileName) { DicomDataset dataset = new DicomDataset(); byte[] buf = new byte[2*noCols*noRows]; Buffer.BlockCopy(pixels, 0, buf, 0, 2 * noCols * noRows); FillDataset(dataset); dataset.Add(DicomTag.PixelAspectRatio, noRows.ToString()+"\\"+noCols.ToString()); dataset.Add(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Monochrome2.Value); dataset.Add(DicomTag.Rows, (ushort)noRows); dataset.Add(DicomTag.Columns, (ushort)noCols); dataset.Add(DicomTag.BitsStored, (ushort)16); dataset.Add(DicomTag.BitsAllocated, (ushort)16); dataset.Add(DicomTag.HighBit, (ushort)15); DicomPixelData pixelData = DicomPixelData.Create(dataset, true); pixelData.BitsStored = 16; //pixelData.BitsAllocated = 16; pixelData.SamplesPerPixel = 1; pixelData.HighBit = 15; pixelData.PixelRepresentation = PixelRepresentation.Unsigned; pixelData.PlanarConfiguration = 0; MemoryByteBuffer pixelsInBytes = new MemoryByteBuffer(buf); pixelData.AddFrame(pixelsInBytes); DicomFile dicomfile = new DicomFile(dataset); dicomfile.Save(fileName); }
public override void Decode(DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomCodecParams parameters) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && !RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { throw new InvalidOperationException("Unsupported OS Platform"); } for (int frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { IByteBuffer jpegData = oldPixelData.GetFrame(frame); //Converting photmetricinterpretation YbrFull or YbrFull422 to RGB if (oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrFull) { jpegData = PixelDataConverter.YbrFullToRgb(jpegData); oldPixelData.PhotometricInterpretation = PhotometricInterpretation.Rgb; } else if (oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrFull422) { jpegData = PixelDataConverter.YbrFull422ToRgb(jpegData, oldPixelData.Width); oldPixelData.PhotometricInterpretation = PhotometricInterpretation.Rgb; } PinnedByteArray jpegArray = new PinnedByteArray(jpegData.Data); byte[] frameData = new byte[newPixelData.UncompressedFrameSize]; PinnedByteArray frameArray = new PinnedByteArray(frameData); JlsParameters jls = new JlsParameters(); char[] errorMessage = new char[256]; // IMPORT JpegLsDecode unsafe { if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { CharlsApiResultType err = JpegLSDecode_Linux64((void *)frameArray.Pointer, frameData.Length, (void *)jpegArray.Pointer, Convert.ToUInt32(jpegData.Size), ref jls, errorMessage); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { CharlsApiResultType err = JpegLSDecode_Windows64((void *)frameArray.Pointer, frameData.Length, (void *)jpegArray.Pointer, Convert.ToUInt32(jpegData.Size), ref jls, errorMessage); } IByteBuffer buffer; if (frameData.Length >= (1 * 1024 * 1024) || oldPixelData.NumberOfFrames > 1) { buffer = new TempFileBuffer(frameData); } else { buffer = new MemoryByteBuffer(frameData); } buffer = EvenLengthBuffer.Create(buffer); newPixelData.AddFrame(buffer); } } }
static private void BreakUp() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); const string sourcePath = "/media/nikolaev_ov/CEFE3C54FE3C36D5/DICOM/ComputerTomography/Covid/favorite/several-frames/sources/1.2.392.200036.9116.2.5.1.37.2418295482.1507184833.33568"; DicomFile dicomFile = DicomFile.Open(sourcePath); DicomPixelData pixelData = DicomPixelData.Create(dicomFile.Dataset, false); MemoryStream[] frameFiles = new MemoryStream[pixelData.NumberOfFrames]; MemoryStream zip = new MemoryStream(); using (ZipArchive archive = new ZipArchive(zip, ZipArchiveMode.Create, true)) { for (int frameIndex = 0; frameIndex != pixelData.NumberOfFrames; frameIndex++) { DicomDataset frameDataset = new DicomDataset(dicomFile.Dataset.InternalTransferSyntax); dicomFile.Dataset.CopyTo(frameDataset); DicomPixelData framePixelData = DicomPixelData.Create(frameDataset, true); IByteBuffer buffer = pixelData.GetFrame(frameIndex); framePixelData.AddFrame(buffer); ZipArchiveEntry readmeEntry = archive.CreateEntry(frameIndex.ToString()); using (Stream stream = readmeEntry.Open()) new DicomFile(frameDataset).Save(stream); } } stopwatch.Stop(); Console.WriteLine(stopwatch.ElapsedMilliseconds); using (FileStream file = new FileStream("/media/nikolaev_ov/CEFE3C54FE3C36D5/test.zip", FileMode.OpenOrCreate, FileAccess.ReadWrite)) { zip.Position = 0; zip.CopyTo(file); } }
internal static void Decode( DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomJpegLsParams parameters) { for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var jpegData = oldPixelData.GetFrame(frame); var frameSize = newPixelData.UncompressedFrameSize; if ((frameSize & 1) == 1) { ++frameSize; } var frameData = new byte[frameSize]; string errorMessage; var err = JpegLs.Decode(frameData, jpegData.Data, null, out errorMessage); if (err != ApiResult.OK) { throw new InvalidOperationException(GetErrorMessage(err, errorMessage)); } newPixelData.AddFrame(new MemoryByteBuffer(frameData)); } }
private static DicomDataset CreateDatasetForFrame(DicomDataset dataset, int frameIndex) { IByteBuffer frameData = DicomPixelData.Create(dataset).GetFrame(frameIndex); DicomDataset newDataset = dataset.Clone(); DicomPixelData newdata = DicomPixelData.Create(newDataset, true); newdata.AddFrame(frameData); return(newDataset); }
public override void Encode( DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomCodecParams parameters) { var pixelCount = oldPixelData.Width * oldPixelData.Height; var numberOfSegments = oldPixelData.BytesAllocated * oldPixelData.SamplesPerPixel; for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var frameData = oldPixelData.GetFrame(frame); var frameArray = frameData.Data; using (var encoder = new RLEEncoder()) { for (var s = 0; s < numberOfSegments; s++) { encoder.NextSegment(); var sample = s / oldPixelData.BytesAllocated; var sabyte = s % oldPixelData.BytesAllocated; int pos; int offset; if (newPixelData.PlanarConfiguration == PlanarConfiguration.Interleaved) { pos = sample * oldPixelData.BytesAllocated; offset = numberOfSegments; } else { pos = sample * oldPixelData.BytesAllocated * pixelCount; offset = oldPixelData.BytesAllocated; } pos += oldPixelData.BytesAllocated - sabyte - 1; for (var p = 0; p < pixelCount; p++) { if (pos >= frameArray.Length) { throw new InvalidOperationException("Read position is past end of frame buffer"); } encoder.Encode(frameArray[pos]); pos += offset; } encoder.Flush(); } encoder.MakeEvenLength(); var data = encoder.GetBuffer(); newPixelData.AddFrame(data); } } }
public override void Encode( DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomCodecParams parameters) { var pixelCount = oldPixelData.Width * oldPixelData.Height; var numberOfSegments = oldPixelData.BytesAllocated * oldPixelData.SamplesPerPixel; for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var frameData = oldPixelData.GetFrame(frame); var frameArray = frameData.Data; using (var encoder = new RLEEncoder()) { for (var s = 0; s < numberOfSegments; s++) { encoder.NextSegment(); var sample = s / oldPixelData.BytesAllocated; var sabyte = s % oldPixelData.BytesAllocated; int pos; int offset; if (newPixelData.PlanarConfiguration == PlanarConfiguration.Interleaved) { pos = sample * oldPixelData.BytesAllocated; offset = numberOfSegments; } else { pos = sample * oldPixelData.BytesAllocated * pixelCount; offset = oldPixelData.BytesAllocated; } pos += oldPixelData.BytesAllocated - sabyte - 1; for (var p = 0; p < pixelCount; p++) { if (pos >= frameArray.Length) { throw new InvalidOperationException("Read position is past end of frame buffer"); } encoder.Encode(frameArray[pos]); pos += offset; } encoder.Flush(); } encoder.MakeEvenLength(); var data = encoder.GetBuffer(); newPixelData.AddFrame(data); } } }
public override void Decode(DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomCodecParams parameters) { for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var encodedData = oldPixelData.GetFrame(frame); var decodedData = ReadImage(encodedData); newPixelData.AddFrame(new StreamByteBuffer(decodedData, 0, (uint)decodedData.Length)); } }
public override void Decode( DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomCodecParams parameters) { for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var rleData = oldPixelData.GetFrame(frame); // Create new frame data of even length var frameSize = newPixelData.UncompressedFrameSize; if ((frameSize & 1) == 1) { ++frameSize; } var frameData = new MemoryByteBuffer(new byte[frameSize]); var pixelCount = oldPixelData.Width * oldPixelData.Height; var numberOfSegments = oldPixelData.BytesAllocated * oldPixelData.SamplesPerPixel; var decoder = new RLEDecoder(rleData); if (decoder.NumberOfSegments != numberOfSegments) { throw new InvalidOperationException("Unexpected number of RLE segments!"); } for (var s = 0; s < numberOfSegments; s++) { var sample = s / newPixelData.BytesAllocated; var sabyte = s % newPixelData.BytesAllocated; int pos, offset; if (newPixelData.PlanarConfiguration == PlanarConfiguration.Interleaved) { pos = sample * newPixelData.BytesAllocated; offset = newPixelData.SamplesPerPixel * newPixelData.BytesAllocated; } else { pos = sample * newPixelData.BytesAllocated * pixelCount; offset = newPixelData.BytesAllocated; } pos += newPixelData.BytesAllocated - sabyte - 1; decoder.DecodeSegment(s, frameData, pos, offset); } newPixelData.AddFrame(frameData); } }
internal static void Encode( DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomJpegLsParams parameters) { if (oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrFull422 || oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrPartial422 || oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrPartial420) { throw new InvalidOperationException( "Photometric Interpretation '{oldPixelData.PhotometricInterpretation}' not supported by JPEG-LS encoder"); } var jparameters = new JlsParameters { width = oldPixelData.Width, height = oldPixelData.Height, bitsPerSample = oldPixelData.BitsStored, stride = oldPixelData.BytesAllocated * oldPixelData.Width * oldPixelData.SamplesPerPixel, components = oldPixelData.SamplesPerPixel, interleaveMode = oldPixelData.SamplesPerPixel == 1 ? InterleaveMode.None : oldPixelData.PlanarConfiguration == PlanarConfiguration.Interleaved ? InterleaveMode.Sample : InterleaveMode.Line, colorTransformation = ColorTransformation.None }; for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var frameData = oldPixelData.GetFrame(frame); // assume compressed frame will be smaller than original var jpegData = new byte[frameData.Size]; ulong jpegDataSize; string errorMessage; var err = JpegLs.Encode(jpegData, frameData.Data, jparameters, out jpegDataSize, out errorMessage); if (err != ApiResult.OK) { throw new InvalidOperationException(GetErrorMessage(err, errorMessage)); } Array.Resize(ref jpegData, (int)jpegDataSize + ((jpegDataSize & 1) == 1 ? 1 : 0)); newPixelData.AddFrame(new MemoryByteBuffer(jpegData)); } }
public static void ImportImage(Bitmap img, String id, String name, String birthDate, String gender, String path) { Bitmap bitmap = img; byte[] pixels = GetPixels(bitmap); MemoryByteBuffer buffer = new MemoryByteBuffer(pixels); DicomDataset dataset = new DicomDataset(); //FillDataset(dataset); dataset.Add(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Rgb.Value); dataset.Add(DicomTag.Rows, (ushort)bitmap.Height); dataset.Add(DicomTag.Columns, (ushort)bitmap.Width); dataset.Add(DicomTag.BitsAllocated, (ushort)8); dataset.Add(DicomTag.SOPClassUID, "1.2.840.10008.5.1.4.1.1.2"); dataset.Add(DicomTag.SOPInstanceUID, "1.2.840.10008.5.1.4.1.1.2.20181120090837121314"); DicomPixelData pixelData = DicomPixelData.Create(dataset, true); pixelData.BitsStored = 8; //pixelData.BitsAllocated = 8; pixelData.SamplesPerPixel = 3; pixelData.HighBit = 7; pixelData.PixelRepresentation = 0; pixelData.PlanarConfiguration = 0; pixelData.AddFrame(buffer); dataset.Add(DicomTag.PatientID, id); dataset.Add(DicomTag.PatientName, name); dataset.Add(DicomTag.PatientBirthDate, birthDate); dataset.Add(DicomTag.PatientSex, gender); dataset.Add(DicomTag.StudyDate, DateTime.Now); dataset.Add(DicomTag.StudyTime, DateTime.Now); dataset.Add(DicomTag.AccessionNumber, string.Empty); dataset.Add(DicomTag.ReferringPhysicianName, string.Empty); dataset.Add(DicomTag.StudyID, "1"); dataset.Add(DicomTag.SeriesNumber, "1"); dataset.Add(DicomTag.ModalitiesInStudy, "CR"); dataset.Add(DicomTag.Modality, "CR"); dataset.Add(DicomTag.NumberOfStudyRelatedInstances, "1"); dataset.Add(DicomTag.NumberOfStudyRelatedSeries, "1"); dataset.Add(DicomTag.NumberOfSeriesRelatedInstances, "1"); DicomFile dicomfile = new DicomFile(dataset); dicomfile.Save(@path); //dicomfile.Save(@"D:\STUDIA\6 semestr\InformatykaWMedycynie\Projekt1\DANE\test2.dcm"); }
/// <summary> /// The JPEG-LS decoding function /// </summary> /// <param name="oldPixelData">The old pixel data</param> /// <param name="newPixelData">The new pixel data</param> /// <param name="parameters">The compression parameters</param> public override void Decode(DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomCodecParams parameters) { for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var jpegLsData = oldPixelData.GetFrame(frame); var message = String.Empty; var jpegLsParams = new JlsParameters(); var frameData = new byte[newPixelData.UncompressedFrameSize]; var err = JpegLs.Decode(frameData, jpegLsData.Data, jpegLsParams, out message); var buffer = frameData.Length >= 1 * 1024 * 1024 || oldPixelData.NumberOfFrames > 1 ? (IByteBuffer) new TempFileBuffer(frameData) : new MemoryByteBuffer(frameData); newPixelData.AddFrame(EvenLengthBuffer.Create(buffer)); } }
internal static void Decode( DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomJpeg2000Params parameters) { var pixelCount = oldPixelData.Height * oldPixelData.Width; if (newPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrIct || newPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrRct) { newPixelData.PhotometricInterpretation = PhotometricInterpretation.Rgb; } if (newPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrFull422 || newPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrPartial422) { newPixelData.PhotometricInterpretation = PhotometricInterpretation.YbrFull; } if (newPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrFull) { newPixelData.PlanarConfiguration = PlanarConfiguration.Planar; } for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var jpegData = oldPixelData.GetFrame(frame); // Destination frame should be of even length var frameSize = newPixelData.UncompressedFrameSize; if ((frameSize & 1) == 1) { ++frameSize; } var destArray = new byte[frameSize]; var image = J2kImage.FromBytes(jpegData.Data, ToParameterList(parameters, true)); if (image == null) { throw new InvalidOperationException("Error in JPEG 2000 code stream!"); } for (var c = 0; c < image.NumberOfComponents; c++) { var comp = image.GetComponent(c); var pos = newPixelData.PlanarConfiguration == PlanarConfiguration.Planar ? (c * pixelCount) : c; var offset = newPixelData.PlanarConfiguration == PlanarConfiguration.Planar ? 1 : image.NumberOfComponents; if (newPixelData.BytesAllocated == 1) { for (var p = 0; p < pixelCount; p++) { destArray[pos] = comp[p]; pos += offset; } } #if SUPPORT16BIT else if (newPixelData.BytesAllocated == 2) { for (var p = 0; p < pixelCount; p++) { destArray[2 * pos] = comp[p]; pos += offset; } } #endif else { throw new InvalidOperationException( $"JPEG 2000 codec does not support Bits Allocated == {newPixelData.BitsAllocated}!"); } } newPixelData.AddFrame(new MemoryByteBuffer(destArray)); } }
public static void MakeEachDicominFolder(string ImageFileFolder) { List <string> dirs = new List <string>(Directory.EnumerateDirectories(ImageFileFolder)); StringBuilder PATIENT_ID = new StringBuilder(); StringBuilder PATIENT_NAME = new StringBuilder(); StringBuilder PATIENT_SEX = new StringBuilder(); StringBuilder PATIENT_BOD = new StringBuilder(); StringBuilder STUDY_DATE = new StringBuilder(); StringBuilder STUDY_TIME = new StringBuilder(); StringBuilder STUDY_DESC = new StringBuilder(); StringBuilder ACCESSION_NO = new StringBuilder(); StringBuilder ORDER_CODE = new StringBuilder(); StringBuilder FILE_CNT = new StringBuilder(); StringBuilder REQUEST = new StringBuilder(); StringBuilder SEND_RESULT = new StringBuilder(); foreach (string dir in dirs) { string existSettingIniStr = dir + @"\info.ini"; FileInfo fileInfo = new FileInfo(existSettingIniStr); if (!fileInfo.Exists) { Form1.lb1.Items.Add("infoINI not exist : " + dir + "[" + DateTime.Now + "]"); continue; } //Example : GetPrivateProfileString("WookoaSetting", "TopAlways", "", topAlways, topAlways.Capacity, "C:\\info.ini"); //Example : WritePrivateProfileString("WookoaSetting", "ViewTray", "false", "C:\\info.ini"); //not need dirs name GetPrivateProfileString("INFO", "PATIENT_ID", "", PATIENT_ID, PATIENT_ID.Capacity, dir + @"\info.ini"); GetPrivateProfileString("INFO", "PATIENT_NAME", "", PATIENT_NAME, PATIENT_NAME.Capacity, dir + @"\info.ini"); GetPrivateProfileString("INFO", "PATIENT_SEX", "", PATIENT_SEX, PATIENT_SEX.Capacity, dir + @"\info.ini"); GetPrivateProfileString("INFO", "PATIENT_BOD", "", PATIENT_BOD, PATIENT_BOD.Capacity, dir + @"\info.ini"); GetPrivateProfileString("INFO", "STUDY_DATE", "", STUDY_DATE, STUDY_DATE.Capacity, dir + @"\info.ini"); GetPrivateProfileString("INFO", "STUDY_TIME", "", STUDY_TIME, STUDY_TIME.Capacity, dir + @"\info.ini"); GetPrivateProfileString("INFO", "STUDY_DESC", "", STUDY_DESC, STUDY_DESC.Capacity, dir + @"\info.ini"); GetPrivateProfileString("INFO", "ACCESSION_NO", "", ACCESSION_NO, ACCESSION_NO.Capacity, dir + @"\info.ini"); GetPrivateProfileString("INFO", "ORDER_CODE", "", ORDER_CODE, ORDER_CODE.Capacity, dir + @"\info.ini"); GetPrivateProfileString("INFO", "FILE_CNT", "", FILE_CNT, FILE_CNT.Capacity, dir + @"\info.ini"); GetPrivateProfileString("INFO", "REQUEST", "", REQUEST, REQUEST.Capacity, dir + @"\info.ini"); GetPrivateProfileString("INFO", "SEND_RESULT", "", SEND_RESULT, SEND_RESULT.Capacity, dir + @"\info.ini"); if (REQUEST.ToString() != "1") { Form1.lb1.Items.Add("Request num is : " + REQUEST.ToString() + "[" + DateTime.Now + "]"); continue; } if (SEND_RESULT.ToString() == "O") { Form1.lb1.Items.Add("Already dcm sended : " + dir + "[" + DateTime.Now + "]"); continue; } List <string> imgFiles = new List <string>(Directory.EnumerateFiles(dir)); List <string> tmp = new List <string>(); DicomUID studyuid = GenerateUid(); DicomUID seriesuid = GenerateUid(); DicomUID sopclassid = DicomUID.SecondaryCaptureImageStorage; int totalImages = 0; // 폴더 내의 총 이미지 갯수 int imgindex = 0; // 시리즈 내의 이미지의 번호를 특정(지금까지 처리된 이미지의 갯수) foreach (string imgfile in imgFiles) { if ((string.Compare(imgfile.Substring(imgfile.Length - 3, 3), "png") == 0) || (string.Compare(imgfile.Substring(imgfile.Length - 3, 3), "jpg") == 0)) { totalImages++; tmp.Add(imgfile); } } imgFiles = tmp; foreach (string imgfile in imgFiles) { DicomDataset dataset = new DicomDataset(); DicomUID sopinstanceid = GenerateUid(); //두개 위로 올려야할수도있음 FillDataset(dataset, PATIENT_ID.ToString(), PATIENT_NAME.ToString(), PATIENT_SEX.ToString(), PATIENT_BOD.ToString(), STUDY_DATE.ToString(), STUDY_TIME.ToString(), STUDY_DESC.ToString(), ACCESSION_NO.ToString(), ORDER_CODE.ToString() , studyuid, seriesuid, sopclassid, sopinstanceid); //TODO : change need priavate profile string dataset.AddOrUpdate(DicomTag.InstanceNumber, Convert.ToString(++imgindex)); // 이미지 번호 (VIEWREX와 UBPACS 모두 이미지 번호를 기준으로 ordering 됨) dataset.AddOrUpdate(DicomTag.ImagesInAcquisition, Convert.ToString(totalImages)); // 검사에서 획득한 이미지의 총합(=Series 내에 속한 Instance 수) bool imageDataSetFlag = false; DicomPixelData pixelData = DicomPixelData.Create(dataset, true); //TODO : bug fix dicompixeldata create ///////////////////////////////// Bitmap bitmap = new Bitmap(imgfile); // bitmap = GetValidImage(bitmap); int rows, columns; double ratioCol = sizeCOL / (double)bitmap.Width; double ratioRow = sizeROW / (double)bitmap.Height; double ratio = Math.Min(ratioRow, ratioCol); int newWidth = (int)(bitmap.Width * ratio); int newHeight = (int)(bitmap.Height * ratio); Bitmap newImage = new Bitmap(sizeCOL, sizeROW); using (Graphics g = Graphics.FromImage(newImage)) { g.FillRectangle(Brushes.Black, 0, 0, newImage.Width, newImage.Height); g.DrawImage(bitmap, (sizeCOL - newWidth) / 2, (sizeROW - newHeight) / 2, newWidth, newHeight); } newImage = GetValidImage(newImage); byte[] pixels = GetPixels(newImage, out rows, out columns); MemoryByteBuffer buffer = new MemoryByteBuffer(pixels); if (imageDataSetFlag == false) { dataset.Add(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Rgb.Value); dataset.Add(DicomTag.Rows, (ushort)sizeROW); dataset.Add(DicomTag.Columns, (ushort)sizeCOL); //TODO : ADD Dcm image count check imageDataSetFlag = true; } pixelData.BitsStored = 8; pixelData.SamplesPerPixel = 3; // 3 : red/green/blue 1 : CT/MR Single Grey Scale pixelData.HighBit = 7; pixelData.PixelRepresentation = 0; pixelData.PlanarConfiguration = 0; //pixelData.NumberOfFrames = imgFiles.Count; // add number of frames. //pixelData.NumberOfFrames = 1; pixelData.AddFrame(buffer); // AddFrame 되면서 Number of Frame은 auto increment됨. 위에서 Number of Frame을 1로 설정할 경우, 아무것도 없는 프레임이 하나 추가됨. //TODO : Need to check if it is created dcm in directory DicomFile dicomfile = new DicomFile(dataset); //string TargetFile = Path.Combine(TargetPath, sopInstanceUID + ".dcm"); string TargetFile = Path.Combine(dir, dataset.GetString(DicomTag.SOPInstanceUID) + ".dcm"); dicomfile.Save(TargetFile); //todo : dicom file save error try { //SendToPACS(TargetFile, Form1.tb2.Text, Form1.tb3.Text, int.Parse(Form1.tb4.Text), Form1.tb5.Text); DicomFile m_pDicomFile = DicomFile.Open(TargetFile, DicomEncoding.GetEncoding("ISO 2022 IR 149")); DicomClient pClient = new DicomClient(Form1.tb3.Text, int.Parse(Form1.tb4.Text), false, Form1.tb2.Text, Form1.tb5.Text); pClient.NegotiateAsyncOps(); pClient.AddRequestAsync(new Dicom.Network.DicomCStoreRequest(m_pDicomFile, Dicom.Network.DicomPriority.Medium)); pClient.SendAsync(); //error event pClient.RequestTimedOut += (object sender, RequestTimedOutEventArgs e) => { WritePrivateProfileString("INFO", "SEND_RESULT", "X", dir + @"\info.ini"); Form1.lb1.Items.Add("Send PACS error exception : " + e.Request + " + " + e.Timeout); throw new NotImplementedException(); }; WritePrivateProfileString("INFO", "SEND_RESULT", "O", dir + @"\info.ini"); Form1.lb1.Items.Add("dcm send finish : " + dir + "[" + DateTime.Now + "]"); } catch (Exception e) { WritePrivateProfileString("INFO", "SEND_RESULT", "X", dir + @"\info.ini"); Form1.lb1.Items.Add("Send PACS error exception : " + e.Message + " + " + e.StackTrace); Form1.lb1.Items.Add(dir + "[" + DateTime.Now + "]"); } } } }
public static void Bmp2Dcm(string bmpPath, string dcmPath, string patient_name, string sex, string age, string process_num, string modality, string hospital_name, string study_description = "", string studydate = "", int TransferSyntax = -1, string sop_uid = "") { Bitmap bitmap = new Bitmap(bmpPath); bitmap = DicomUtility.GetValidImage(bitmap); int rows; int columns; byte[] pixels = DicomUtility.GetPixelsForDicom(bitmap, out rows, out columns); MemoryByteBuffer buffer = new MemoryByteBuffer(pixels); DicomDataset dataset = new DicomDataset(); Encoding encoding = Encoding.GetEncoding("GB18030"); dataset.Add <DicomUID>(DicomTag.SOPClassUID, new DicomUID[] { DicomUID.SecondaryCaptureImageStorage }); dataset.Add <DicomUID>(DicomTag.StudyInstanceUID, new DicomUID[] { DicomUtility.GenerateUid() }); dataset.Add <DicomUID>(DicomTag.SeriesInstanceUID, new DicomUID[] { DicomUtility.GenerateUid() }); dataset.Add <DicomUID>(DicomTag.SOPInstanceUID, new DicomUID[] { DicomUtility.GenerateUid() }); dataset.Add <string>(DicomTag.PatientID, new string[] { process_num }); dataset.Add(new DicomItem[] { DicomUtility.GetDicomItem(DicomTag.PatientName, encoding, patient_name) }); dataset.Add <string>(DicomTag.PatientBirthDate, new string[] { "00000000" }); dataset.Add(new DicomItem[] { DicomUtility.GetDicomItem(DicomTag.PatientAge, encoding, age) }); dataset.Add <string>(DicomTag.PatientSex, new string[] { sex }); if (studydate == "") { dataset.Add <DateTime>(DicomTag.StudyDate, new DateTime[] { DateTime.Now }); dataset.Add <DateTime>(DicomTag.StudyTime, new DateTime[] { DateTime.Now }); } else { dataset.Add <string>(DicomTag.StudyDate, new string[] { studydate }); dataset.Add <string>(DicomTag.StudyTime, new string[] { DateTime.Now.ToString("hhmmssfff") }); } dataset.Add <string>(DicomTag.AccessionNumber, new string[] { string.Empty }); dataset.Add <string>(DicomTag.ReferringPhysicianName, new string[] { string.Empty }); dataset.Add <string>(DicomTag.StudyID, new string[] { "1" }); dataset.Add <string>(DicomTag.SeriesNumber, new string[] { "1" }); dataset.Add <string>(DicomTag.ModalitiesInStudy, new string[] { modality }); dataset.Add <string>(DicomTag.Modality, new string[] { modality }); dataset.Add <string>(DicomTag.NumberOfStudyRelatedInstances, new string[] { "1" }); dataset.Add <string>(DicomTag.NumberOfStudyRelatedSeries, new string[] { "1" }); dataset.Add <string>(DicomTag.NumberOfSeriesRelatedInstances, new string[] { "1" }); dataset.Add <string>(DicomTag.PatientOrientation, new string[] { "F/A" }); dataset.Add <string>(DicomTag.ImageLaterality, new string[] { "U" }); dataset.Add(new DicomItem[] { DicomUtility.GetDicomItem(DicomTag.InstitutionName, encoding, hospital_name) }); dataset.Add <string>(DicomTag.StudyDescription, new string[] { study_description }); dataset.Add <string>(DicomTag.PhotometricInterpretation, new string[] { PhotometricInterpretation.Rgb.Value }); dataset.Add <ushort>(DicomTag.Rows, new ushort[] { (ushort)rows }); dataset.Add <ushort>(DicomTag.Columns, new ushort[] { (ushort)columns }); if (sop_uid != "") { dataset.Add <string>(DicomTag.SOPInstanceUID, new string[] { sop_uid }); } DicomPixelData pixelData = DicomPixelData.Create(dataset, true); pixelData.BitsStored = 8; pixelData.BitsAllocated = 8; pixelData.SamplesPerPixel = 3; pixelData.HighBit = 7; pixelData.PixelRepresentation = PixelRepresentation.Unsigned; pixelData.PlanarConfiguration = PlanarConfiguration.Interleaved; pixelData.AddFrame(buffer); DicomFile _dicomfile = new DicomFile(dataset); DicomFile file = new DicomFile(); switch (TransferSyntax) { case 0: file = _dicomfile.ChangeTransferSyntax(DicomTransferSyntax.JPEG2000Lossless, null); goto IL_579; case 1: file = _dicomfile.ChangeTransferSyntax(DicomTransferSyntax.RLELossless, null); goto IL_579; case 2: file = _dicomfile.ChangeTransferSyntax(DicomTransferSyntax.JPEGProcess14, null); goto IL_579; case 3: { int bits = _dicomfile.Dataset.Get <int>(DicomTag.BitsAllocated, 0, 8); DicomTransferSyntax syntax = DicomTransferSyntax.JPEGProcess1; if (bits == 16) { syntax = DicomTransferSyntax.JPEGProcess2_4; } file = _dicomfile.ChangeTransferSyntax(syntax, new DicomJpegParams { Quality = 100 }); goto IL_579; } case 4: file = _dicomfile.ChangeTransferSyntax(DicomTransferSyntax.ExplicitVRLittleEndian, null); goto IL_579; case 5: file = _dicomfile.ChangeTransferSyntax(DicomTransferSyntax.ExplicitVRBigEndian, null); goto IL_579; case 6: file = _dicomfile.ChangeTransferSyntax(DicomTransferSyntax.ImplicitVRLittleEndian, null); goto IL_579; case 8: file = _dicomfile.ChangeTransferSyntax(DicomTransferSyntax.ImplicitVRBigEndian, null); goto IL_579; } file = _dicomfile; IL_579: file.Save(dcmPath); }
static internal unsafe void Start(string[] args) { DicomFile file = new DicomFile(); var z = file.Dataset.InternalTransferSyntax; string sourceDirectory = Environment.GetEnvironmentVariable("SOURCE_DIRECTORY"); string fontDirectory = Environment.GetEnvironmentVariable("FONT_DIRECTORY"); System.Drawing.Bitmap w = new System.Drawing.Bitmap(100, 100, System.Drawing.Imaging.PixelFormat.Format24bppRgb); w.Save(System.IO.Path.Combine(sourceDirectory, "image.png")); var d = System.Drawing.Image.FromFile(System.IO.Path.Combine(sourceDirectory, "image.png"), false); // string filePath = System.IO.Path.Combine(sourceDirectory, "DICOM/SikorskayaN.M/1.2.840.113681.3232266507.1433317480.4724.262"); // string filePath = System.IO.Path.Combine(sourceDirectory, "DICOM/Topina V A/1.2.840.113681.169869557.1534493190.4808.47144"); // string filePath = System.IO.Path.Combine(sourceDirectory, "DICOM/!Test/ИС Флюорография/ФЛЮ для показа/Пациент001/Пациент001.dcm"); // string filePath = System.IO.Path.Combine(sourceDirectory, "1"); // string filePath = System.IO.Path.Combine(sourceDirectory, "DICOM/Fluorography/Emias Compressed/1.871.3.2050448135.34720.20335.72851334.2248937210.1.1.1"); // string filePath = System.IO.Path.Combine(sourceDirectory, "DICOM/Fluorography/Emias Compressed/1.871.3.1778880733.53108.19741.3386264761.3888045999.1.1.1"); // string filePath = System.IO.Path.Combine(sourceDirectory, "DICOM/Fluorography/Emias Compressed/1.871.3.3958735481.62656.17963.4096047274.351950500.1.1.1"); string filePath = System.IO.Path.Combine(sourceDirectory, "/media/nikolaev_ov/CEFE3C54FE3C36D5/DICOM/ComputerTomography/Covid/SE0 (3)/IM0"); // string filePath = System.IO.Path.Combine(sourceDirectory, "SE000001/IM000000"); // string filePath = System.IO.Path.Combine(sourceDirectory, "SC_R_CC.dcm"); // string[] files = Directory.GetFiles("/media/nikolaev_ov/CEFE3C54FE3C36D5/DICOM/ComputerTomography/3000566.000000-03192/"); DicomFile dicomFile = DicomFile.Open(filePath); DicomDataset dataset = dicomFile.Dataset; // var t = dataset.InternalTransferSyntax; // dataset = Compress(dataset, DicomTransferSyntax.JPEGProcess1, new DicomJpegProcess1Codec()); // dicomFile = new DicomFile(dataset); // dicomFile.Save(System.IO.Path.Combine(sourceDirectory, "1")); // dataset.AddOrUpdate(DicomTag.WindowCenter, 32767.0); // dataset.AddOrUpdate(DicomTag.WindowWidth, 65534.0); // dicomFile.Save(System.IO.Path.Combine(sourceDirectory, "1")); // PullDicom(dataset); // GetAverageValue(dataset, out double average, out double dispersion, out ushort min, out ushort max); // GetAverageValue(dataset, new DicomJpegLsLosslessCodec(), out double average, out double dispersion, out ushort min, out ushort max); // GetAverageValue(dataset, new JpegLosslessDecoderWrapperProcess14SV1(), out double average, out double dispersion, out ushort min, out ushort max); var bitsAllocated = dataset.GetSingleValue <string>(DicomTag.BitsAllocated); var BitsStored = dataset.GetSingleValue <string>(DicomTag.BitsStored); var samplesPerPixel = dataset.GetSingleValue <string>(DicomTag.SamplesPerPixel); var photometricInterpretation = dataset.GetSingleValue <string>(DicomTag.PhotometricInterpretation); var PixelRepresentation = dataset.GetSingleValue <string>(DicomTag.PixelRepresentation); double windowCenter = dataset.GetValue <double>(DicomTag.WindowCenter, 0); double windowWidth = dataset.GetValue <double>(DicomTag.WindowWidth, 0); byte[] pixelData; using (FileStream readStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) pixelData = DicomDatasetExtensions.DecodeImage(readStream, out _).PixelData; // using FileStream stream1 = new FileStream("/media/nikolaev_ov/CEFE3C54FE3C36D5/pixelData.bin", FileMode.OpenOrCreate, FileAccess.ReadWrite); // pixelData = new byte[stream1.Length]; // stream1.Read(pixelData, 0, pixelData.Length); // GetAverageValue(dataset, pixelData, pixelData.Length, out double average, out double dispersion, out ushort min, out ushort max); DicomImage image = new DicomImage(dataset); image.RenderImage().AsSharedBitmap().Save(System.IO.Path.Combine(sourceDirectory, "image.png")); DicomPixelData sdsd = DicomPixelData.Create(dataset); // pixelData = sdsd.GetFrame(0).Data; fixed(byte *p = &pixelData[0]) { // var bitmap2 = new System.Drawing.Bitmap(image.Width, image.Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb); // stream1.SetLength(0); // for (int x = 0; x != bitmap2.Width; x++) // for (int y = 0; y != bitmap2.Height; y++) // { // byte value = pixelData[y * bitmap2.Width + x]; // bitmap2.SetPixel(x, y, System.Drawing.Color.FromArgb(value)); // stream1.WriteByte(value); // } // stream1.Close(); // bitmap2.Save("/media/nikolaev_ov/CEFE3C54FE3C36D5/image.png"); // var img = new SixLabors.ImageSharp.Image<L8>(image.Width, image.Height); // for (int y = 0; y < image.Height; y++) // { // Span<L8> span = img.GetPixelRowSpan(y); // for (int x = 0; x < image.Width; x++) // span[x] = new L8(pixelData[y * image.Width + x]); // } // var img = Image.LoadPixelData<L8>(new ReadOnlySpan<L8>(p, pixelData.Length), image.Width, image.Height); var img = Image.LoadPixelData <L16>(new ReadOnlySpan <L16>(p, pixelData.Length / 2), image.Width, image.Height); img.Mutate(a => { // Color whiteColor = new Color(new Rgba64(ushort.MaxValue & 0x0FFF, ushort.MaxValue & 0x0FFF, ushort.MaxValue & 0x0FFF, ushort.MaxValue & 0x0FFF)); Color whiteColor = new Color(new Rgba64(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue)); Color blackColor = new Color(new Rgba64(ushort.MinValue, ushort.MinValue, ushort.MinValue, ushort.MinValue)); a.Draw(Pens.Solid(whiteColor, 10), new EllipsePolygon(new PointF(image.Width * 0.5F, image.Height * 0.5F), 200F)); FontCollection fontCollection = new FontCollection(); fontCollection.Install(System.IO.Path.Combine(fontDirectory, "fonts/TIMES.TTF")); string text = "ТОЛЬКО ДЛЯ ИССЛЕДОВАТЕЛЬСКИХ ЦЕЛЕЙ"; Font font = new Font(fontCollection.Families.First(), 64, FontStyle.Regular); FontRectangle fontRectangle = TextMeasurer.Measure(text, new RendererOptions(font)); PointF textPoint = new PointF(image.Width * 0.5F - fontRectangle.Width * 0.5F, image.Height * 0.5F - 200F - fontRectangle.Height); a.DrawText(text, font, blackColor, new PointF(textPoint.X + 5, textPoint.Y + 5)); a.DrawText(text, font, whiteColor, textPoint); }); using FileStream stream = new FileStream(System.IO.Path.Combine(sourceDirectory, "image.jpg"), FileMode.OpenOrCreate, FileAccess.Write); img.Save(stream, new JpegEncoder() { Quality = 100, Subsample = JpegSubsample.Ratio444 }); for (int y = 0; y < image.Height; y++) { Span <L16> span = img.GetPixelRowSpan(y); fixed(L16 *p2 = &span[0]) Buffer.MemoryCopy(p2, p + y * image.Width * 2, image.Width * 2, image.Width * 2); } } DicomDataset dataset2 = new DicomDataset(); dataset.CopyTo(dataset2); dataset = dataset2; dicomFile = new DicomFile(dataset); DicomPixelData dicomPixelData = DicomPixelData.Create(dataset, true); dicomPixelData.AddFrame(new MemoryByteBuffer(pixelData)); // dicomFile.Save(Path.Combine(sourceDirectory, "1"); // GetAverageValue(dataset, out average, out dispersion, out min, out max); windowCenter = dataset.GetSingleValue <double>(DicomTag.WindowCenter); windowWidth = dataset.GetSingleValue <double>(DicomTag.WindowWidth); // string VOILUTFunction = dataset.GetSingleValue<string>(DicomTag.VOILUTFunction); // dataset = GenerateUncompressedDicomDataset(dataset); dataset = dataset.Compress(DicomTransferSyntax.JPEGLSLossless, new DicomJpegLsLosslessCodec(), new DicomJpegParams { }); // GetAverageValue(dataset, new DicomJpegLsLosslessCodec(), out average, out dispersion, out min, out max); // dataset = Uncompress(dataset, new DicomJpegLsLosslessCodec()); // GetAverageValue(dataset, out average, out dispersion, out min, out max); dicomFile = new DicomFile(dataset); // dataset.AddOrUpdate(DicomTag.WindowCenter, 255.0 * 0.5); // dataset.AddOrUpdate(DicomTag.WindowWidth, 255.0); dataset.Remove(DicomTag.WindowCenter); dataset.Remove(DicomTag.WindowWidth); // CheckDicomTransferSyntax(dataset); // PullDicom(dataset); dicomFile.Save(System.IO.Path.Combine(sourceDirectory, "1")); }
string WorkerFunc(Tuple <string, Tuple <int, int, int, int>, List <string> > param, BackgroundWorker worker, DoWorkEventArgs e) { List <string> lFailed = new List <string>(); string strPath = param.Item1; Tuple <int, int, int, int> lCrop = param.Item2; List <string> files = param.Item3; bool bCrop = lCrop.Item1 + lCrop.Item2 + lCrop.Item3 + lCrop.Item4 > 0 ? true : false; DicomUIDGenerator uidGen = new DicomUIDGenerator(); List <Tuple <string, string, string, string> > listDCM = new List <Tuple <string, string, string, string> >(); int i = 0, k = 0; // Randomize input list Random rand = new Random(); // For each spot in the array, pick // a random item to swap into that spot. for (k = 0; k < files.Count - 1; k++) { int j = rand.Next(k, files.Count); string temp = files[k]; files[k] = files[j]; files[j] = temp; } DateTime dt = DateTime.Now; int nSuccess = 0; foreach (string strFile in files) { i++; DicomFile file; try { file = DicomFile.Open(strFile); } catch (Exception ex) { // Transmit message back with worker? lFailed.Add(strFile); System.Diagnostics.Debug.WriteLine(ex.ToString()); continue; } string strOriginalPatientID = ""; try { strOriginalPatientID = file.Dataset.GetValue <string>(DicomTag.PatientID, 0); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); } DicomAnonymizer anon = new DicomAnonymizer(); DicomFile fileAnon; try { fileAnon = anon.Anonymize(file); } catch (Exception ex) { // Transmit message back with worker? lFailed.Add(strFile); System.Diagnostics.Debug.WriteLine(ex.ToString()); continue; } DicomTag[] tagsToRemove = { DicomTag.StudyDate, DicomTag.StudyTime, DicomTag.PatientID, DicomTag.StudyID, DicomTag.StudyInstanceUID }; foreach (DicomTag d in tagsToRemove) { try { fileAnon.Dataset.Remove(d); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("Error removing element: " + ex.ToString()); } } fileAnon.Dataset.Add(DicomTag.StudyInstanceUID, DicomUID.Generate()); fileAnon.Dataset.Add(DicomTag.StudyDate, dt.Year.ToString("0000") + dt.Month.ToString("00") + dt.Day.ToString("00")); fileAnon.Dataset.Add(DicomTag.StudyTime, dt.Hour.ToString("00") + dt.Minute.ToString("00") + dt.Second.ToString("00")); fileAnon.Dataset.Add(DicomTag.PatientID, i.ToString()); fileAnon.Dataset.Add(DicomTag.StudyID, i.ToString()); string strStudyID = fileAnon.Dataset.GetValue <string>(DicomTag.StudyInstanceUID, 0); try { var header = DicomPixelData.Create(fileAnon.Dataset); var pixelData = PixelDataFactory.Create(header, header.NumberOfFrames - 1); int rows = header.Height; int columns = header.Width; Array a; byte[] result; bool b16bit = false; if (pixelData is GrayscalePixelDataU16) { ushort[] pixels = ((GrayscalePixelDataU16)pixelData).Data; a = pixels; b16bit = true; } else if (pixelData is GrayscalePixelDataS16) { short[] pixels = ((GrayscalePixelDataS16)pixelData).Data; a = pixels; b16bit = true; } else if (pixelData is GrayscalePixelDataU32) { uint[] pixels = ((GrayscalePixelDataU32)pixelData).Data; a = pixels; } else if (pixelData is GrayscalePixelDataS32) { int[] pixels = ((GrayscalePixelDataS32)pixelData).Data; a = pixels; } else if (pixelData is GrayscalePixelDataU8) { byte[] pixels = ((GrayscalePixelDataU8)pixelData).Data; a = pixels; } else { throw new Exception("DICOM image format not supported (this program only supports greyscale)."); } // Can't seem to figure out the byte formatting between 16-bit greyscale DCM versus C#'s 16-bit greyscale. //b16bit = false; if (bCrop) { // Top if (lCrop.Item1 > 0) { Array cropped = Array.CreateInstance(a.GetValue(0).GetType(), a.Length - (columns * lCrop.Item1)); Array.Copy(a, columns * lCrop.Item1, cropped, 0, cropped.Length); a = cropped; rows -= lCrop.Item1; } // Right if (lCrop.Item2 > 0) { Array cropped = Array.CreateInstance(a.GetValue(0).GetType(), a.Length - (rows * lCrop.Item2)); for (k = 0; k < rows; k++) { Array.Copy(a, k * columns, cropped, k * (columns - lCrop.Item2), columns - lCrop.Item2); } a = cropped; columns -= lCrop.Item2; } // Bottom if (lCrop.Item3 > 0) { Array cropped = Array.CreateInstance(a.GetValue(0).GetType(), a.Length - (columns * lCrop.Item3)); Array.Copy(a, 0, cropped, 0, cropped.Length); a = cropped; rows -= lCrop.Item3; } // Left if (lCrop.Item4 > 0) { Array cropped = Array.CreateInstance(a.GetValue(0).GetType(), a.Length - (rows * lCrop.Item4)); for (k = 0; k < rows; k++) { Array.Copy(a, k * columns + lCrop.Item4, cropped, k * (columns - lCrop.Item4), columns - lCrop.Item4); } a = cropped; columns -= lCrop.Item4; } // Now we need to copy the Array "a" into a byte array. // But first! Should we make sure that it's actually a 16-bit array? int nBytes = a.Length * System.Runtime.InteropServices.Marshal.SizeOf(a.GetValue(0)); result = new byte[nBytes]; Buffer.BlockCopy(a, 0, result, 0, nBytes); Dicom.IO.Buffer.MemoryByteBuffer buffer = new Dicom.IO.Buffer.MemoryByteBuffer(result); DicomDataset dataset = new DicomDataset(); dataset = fileAnon.Dataset.Clone(); dataset.AddOrUpdate(DicomTag.Rows, (ushort)rows); dataset.AddOrUpdate(DicomTag.Columns, (ushort)columns); DicomPixelData newPixelData = DicomPixelData.Create(dataset, true); newPixelData.BitsStored = header.BitsStored; newPixelData.SamplesPerPixel = header.SamplesPerPixel; newPixelData.HighBit = header.HighBit; newPixelData.PhotometricInterpretation = header.PhotometricInterpretation; newPixelData.PixelRepresentation = header.PixelRepresentation; newPixelData.PlanarConfiguration = header.PlanarConfiguration; newPixelData.Height = (ushort)rows; newPixelData.Width = (ushort)columns; newPixelData.AddFrame(buffer); fileAnon = new DicomFile(dataset); } // Only do this if it's a 16bit file that we want a 16bit png for if (b16bit) { int nBytes = a.Length * System.Runtime.InteropServices.Marshal.SizeOf(a.GetValue(0)); result = new byte[nBytes]; // If we're using a format that's "16bit" but actually less, scale the values? if (header.BitsStored < header.BitsAllocated) { int nShift = header.BitsAllocated - header.BitsStored; int nFlag = (0x1 << header.BitsStored) - 1; for (k = 0; k < a.Length; k++) { a.SetValue((ushort)(((nFlag - ((ushort)a.GetValue(k) & nFlag)) << nShift) & 0xFFFF), k); } } Buffer.BlockCopy(a, 0, result, 0, nBytes); unsafe { fixed(byte *ptr = result) { using (Bitmap img16 = new Bitmap(columns, rows, 4 * ((2 * columns + 3) / 4), System.Drawing.Imaging.PixelFormat.Format16bppGrayScale, new IntPtr(ptr))) { SaveBmp(img16, strPath + "/Anonymised/" + strStudyID + "-16bitGreyscale.tif"); //img16.Save(strPath + "/Anonymised/" + strStudyID + "-16bitGreyscale.png"); } } } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("Failed to crop image"); System.Diagnostics.Debug.WriteLine(ex.ToString()); } fileAnon.Save(strPath + "/Anonymised/" + strStudyID + ".dcm"); listDCM.Add(new Tuple <string, string, string, string>(i.ToString(), strStudyID, strFile, strOriginalPatientID)); var img = new DicomImage(strPath + "/Anonymised/" + strStudyID + ".dcm"); // Convert DCM to a 32-bit per pixel (8-bit per each color RGB + 8-bit unused) PNG file try { Dicom.IO.PinnedIntArray px = img.RenderImage().Pixels; int[] pxi = px.Data; byte[] result = new byte[px.ByteSize]; Buffer.BlockCopy(pxi, 0, result, 0, result.Length); unsafe { fixed(byte *ptr = result) { using (Bitmap image = new Bitmap(img.Width, img.Height, img.Width * 4, System.Drawing.Imaging.PixelFormat.Format32bppRgb, new IntPtr(ptr))) { image.Save(strPath + "/Anonymised/" + strStudyID + ".png"); } } } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); } worker.ReportProgress(i * 100 / files.Count); nSuccess++; //Console.WriteLine("Anonymized image " + i + " (of " + nFrames + " frame" + (nFrames == 1 ? "" : "s") + "): " + strFile); } // Create a map file using (System.IO.StreamWriter file = new System.IO.StreamWriter(new FileStream(strPath + "/Anonymised/Map.csv", FileMode.Create, FileAccess.ReadWrite), Encoding.UTF8)) { file.WriteLine("NewPatientID,NewStudyInstanceUID,OriginalFile,OriginalPatientID"); foreach (Tuple <string, string, string, string> line in listDCM) { file.WriteLine(line.Item1 + "," + line.Item2 + "," + line.Item3 + "," + line.Item4); } } string strRet = nSuccess.ToString() + " images successfully anonymised, Map.csv created.\nOutput at:\n" + strPath + "\\Anonymised"; if (lFailed.Count > 0) { strRet += "\nThese files failed to anonymise:"; foreach (string sf in lFailed) { strRet += "\n" + sf; } } return(strRet); }
internal static void Decode( DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomJpeg2000Params parameters) { var pixelCount = oldPixelData.Height * oldPixelData.Width; var bytesAllocated = newPixelData.BytesAllocated; if (newPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrIct || newPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrRct) { newPixelData.PhotometricInterpretation = PhotometricInterpretation.Rgb; } if (newPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrFull422 || newPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrPartial422) { newPixelData.PhotometricInterpretation = PhotometricInterpretation.YbrFull; } if (newPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrFull) { newPixelData.PlanarConfiguration = PlanarConfiguration.Planar; } for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var jpegData = oldPixelData.GetFrame(frame); // Destination frame should be of even length var frameSize = newPixelData.UncompressedFrameSize; if ((frameSize & 1) == 1) { ++frameSize; } var destArray = new byte[frameSize]; var image = J2kImage.FromBytes(jpegData.Data, ToParameterList(parameters, true)); if (image == null) { throw new InvalidOperationException("Error in JPEG 2000 code stream!"); } for (var c = 0; c < image.NumberOfComponents; c++) { // convert RGB BGR colorspace var comp = image.GetComponent(image.NumberOfComponents - c - 1); var pos = bytesAllocated * (newPixelData.PlanarConfiguration == PlanarConfiguration.Planar ? c * pixelCount : c); var offset = bytesAllocated * (newPixelData.PlanarConfiguration == PlanarConfiguration.Planar ? 1 : image.NumberOfComponents); if (bytesAllocated == 1) { if (newPixelData.PixelRepresentation == PixelRepresentation.Signed) { var sign = 1 << newPixelData.HighBit; var mask = 0xff ^ sign; for (var p = 0; p < pixelCount; p++) { int i = (i = comp[p] - sign) < 0 ? (i & mask) | sign : i & mask; destArray[pos] = (byte)i; pos += offset; } } else { for (var p = 0; p < pixelCount; p++) { destArray[pos] = (byte)comp[p]; pos += offset; } } } else if (bytesAllocated == 2) { if (newPixelData.PixelRepresentation == PixelRepresentation.Signed) { var sign = 1 << newPixelData.HighBit; var mask = 0xffff ^ sign; for (var p = 0; p < pixelCount; p++) { int i = (i = comp[p] - sign) < 0 ? (i & mask) | sign : i & mask; destArray[pos] = (byte)(i & 0xff); destArray[pos + 1] = (byte)((i >> 8) & 0xff); pos += offset; } } else { for (var p = 0; p < pixelCount; p++) { var i = comp[p]; destArray[pos] = (byte)(i & 0xff); destArray[pos + 1] = (byte)((i >> 8) & 0xff); pos += offset; } } } else { throw new InvalidOperationException( $"JPEG 2000 codec does not support Bits Allocated == {newPixelData.BitsAllocated}!"); } } newPixelData.AddFrame(new MemoryByteBuffer(destArray)); } }
internal static void Encode( DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomJpeg2000Params parameters) { if ((oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrFull422) || (oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrPartial422) || (oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrPartial420)) { throw new InvalidOperationException( "Photometric Interpretation '" + oldPixelData.PhotometricInterpretation + "' not supported by JPEG 2000 encoder"); } var jparams = parameters ?? new DicomJpeg2000Params(); jparams.Irreversible = newPixelData.IsLossy; jparams.AllowMCT = oldPixelData.PhotometricInterpretation == PhotometricInterpretation.Rgb; var pixelCount = oldPixelData.Height * oldPixelData.Width; for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var frameData = oldPixelData.GetFrame(frame); var nc = oldPixelData.SamplesPerPixel; var sgnd = oldPixelData.PixelRepresentation == PixelRepresentation.Signed && !jparams.EncodeSignedPixelValuesAsUnsigned; var comps = new int[nc][]; for (var c = 0; c < nc; c++) { var comp = new int[pixelCount]; var pos = oldPixelData.PlanarConfiguration == PlanarConfiguration.Planar ? (c * pixelCount) : c; var offset = oldPixelData.PlanarConfiguration == PlanarConfiguration.Planar ? 1 : nc; if (oldPixelData.BytesAllocated == 1) { var data = frameData.Data; if (sgnd) { if (oldPixelData.BitsStored < 8) { var sign = (byte)(1 << oldPixelData.HighBit); var mask = (byte)(0xff >> (oldPixelData.BitsAllocated - oldPixelData.BitsStored)); for (var p = 0; p < pixelCount; p++) { var pixel = (sbyte)data[pos]; comp[p] = (pixel & sign) > 0 ? -(((-pixel) & mask) + 1) : pixel; pos += offset; } } else { for (var p = 0; p < pixelCount; p++) { comp[p] = (sbyte)data[pos]; pos += offset; } } } else { for (var p = 0; p < pixelCount; p++) { comp[p] = data[pos]; pos += offset; } } } else if (oldPixelData.BytesAllocated == 2) { if (sgnd) { if (oldPixelData.BitsStored < 16) { var frameData16 = new ushort[pixelCount]; Buffer.BlockCopy(frameData.Data, 0, frameData16, 0, (int)frameData.Size); var sign = (ushort)(1 << oldPixelData.HighBit); var mask = (ushort)(0xffff >> (oldPixelData.BitsAllocated - oldPixelData.BitsStored)); for (var p = 0; p < pixelCount; p++) { var pixel = frameData16[pos]; comp[p] = (pixel & sign) > 0 ? -(((-pixel) & mask) + 1) : pixel; pos += offset; } } else { var frameData16 = new short[pixelCount]; Buffer.BlockCopy(frameData.Data, 0, frameData16, 0, (int)frameData.Size); for (var p = 0; p < pixelCount; p++) { comp[p] = frameData16[pos]; pos += offset; } } } else { var frameData16 = new ushort[pixelCount]; Buffer.BlockCopy(frameData.Data, 0, frameData16, 0, (int)frameData.Size); for (var p = 0; p < pixelCount; p++) { comp[p] = frameData16[pos]; pos += offset; } } } else { throw new InvalidOperationException( $"JPEG 2000 codec does not support Bits Allocated == {oldPixelData.BitsAllocated}"); } comps[c] = comp; } var image = new PortableImageSource( oldPixelData.Width, oldPixelData.Height, nc, oldPixelData.BitsAllocated, Enumerable.Repeat(sgnd, nc).ToArray(), comps); try { var cbuf = J2kImage.ToBytes(image, ToParameterList(jparams, false)); newPixelData.AddFrame(new MemoryByteBuffer(cbuf)); } catch (Exception e) { throw new InvalidOperationException("Unable to JPEG 2000 encode image", e); } } if (oldPixelData.PhotometricInterpretation == PhotometricInterpretation.Rgb) { newPixelData.PlanarConfiguration = PlanarConfiguration.Interleaved; if (jparams.AllowMCT && jparams.UpdatePhotometricInterpretation) { if (newPixelData.IsLossy && jparams.Irreversible) { newPixelData.PhotometricInterpretation = PhotometricInterpretation.YbrIct; } else { newPixelData.PhotometricInterpretation = PhotometricInterpretation.YbrRct; } } } }
public override void Decode( DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomCodecParams parameters) { for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var rleData = oldPixelData.GetFrame(frame); // Create new frame data of even length var frameSize = newPixelData.UncompressedFrameSize; if ((frameSize & 1) == 1) { ++frameSize; } var frameData = new MemoryByteBuffer(new byte[frameSize]); var pixelCount = oldPixelData.Width * oldPixelData.Height; var numberOfSegments = oldPixelData.BytesAllocated * oldPixelData.SamplesPerPixel; var decoder = new RLEDecoder(rleData); if (decoder.NumberOfSegments != numberOfSegments) { throw new InvalidOperationException("Unexpected number of RLE segments!"); } for (var s = 0; s < numberOfSegments; s++) { var sample = s / newPixelData.BytesAllocated; var sabyte = s % newPixelData.BytesAllocated; int pos, offset; if (newPixelData.PlanarConfiguration == PlanarConfiguration.Interleaved) { pos = sample * newPixelData.BytesAllocated; offset = newPixelData.SamplesPerPixel * newPixelData.BytesAllocated; } else { pos = sample * newPixelData.BytesAllocated * pixelCount; offset = newPixelData.BytesAllocated; } pos += newPixelData.BytesAllocated - sabyte - 1; decoder.DecodeSegment(s, frameData, pos, offset); } newPixelData.AddFrame(frameData); } }
internal static void Encode( DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomJpegParams parameters) { if ((oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrFull422) || (oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrPartial422) || (oldPixelData.PhotometricInterpretation == PhotometricInterpretation.YbrPartial420)) { throw new InvalidOperationException( "Photometric Interpretation '" + oldPixelData.PhotometricInterpretation + "' not supported by JPEG encoder"); } var w = oldPixelData.Width; var h = oldPixelData.Height; for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var frameData = oldPixelData.GetFrame(frame); var nc = oldPixelData.SamplesPerPixel; var sgnd = oldPixelData.PixelRepresentation == PixelRepresentation.Signed; var rows = Enumerable.Range(0, h).Select(i => new short[w, nc]).ToArray(); for (var c = 0; c < nc; c++) { var pos = oldPixelData.PlanarConfiguration == PlanarConfiguration.Planar ? (c * w * h) : c; var offset = oldPixelData.PlanarConfiguration == PlanarConfiguration.Planar ? 1 : nc; if (oldPixelData.BytesAllocated == 1) { var data = frameData.Data; if (sgnd) { if (oldPixelData.BitsStored < 8) { var sign = (byte)(1 << oldPixelData.HighBit); var mask = (byte)(0xff >> (oldPixelData.BitsAllocated - oldPixelData.BitsStored)); for (var y = 0; y < h; ++y) { for (var x = 0; x < w; ++x) { var pixel = (sbyte)data[pos]; rows[y][x, c] = (short)((pixel & sign) > 0 ? -(((-pixel) & mask) + 1) : pixel); pos += offset; } } } else { for (var y = 0; y < h; ++y) { for (var x = 0; x < w; ++x) { rows[y][x, c] = (sbyte)data[pos]; pos += offset; } } } } else { for (var y = 0; y < h; ++y) { for (var x = 0; x < w; ++x) { rows[y][x, c] = data[pos]; pos += offset; } } } } #if SUPPORT16BIT else if (oldPixelData.BytesAllocated == 2) { if (sgnd) { if (oldPixelData.BitsStored < 16) { var frameData16 = new ushort[w * h]; Buffer.BlockCopy(frameData.Data, 0, frameData16, 0, (int)frameData.Size); var sign = (ushort)(1 << oldPixelData.HighBit); var mask = (ushort)(0xffff >> (oldPixelData.BitsAllocated - oldPixelData.BitsStored)); for (var y = 0; y < h; ++y) { for (var x = 0; x < w; ++x) { var pixel = frameData16[pos]; rows[y][x, c] = (short)((pixel & sign) > 0 ? -(((-pixel) & mask) + 1) : pixel); pos += offset; } } } else { var frameData16 = new short[w * h]; Buffer.BlockCopy(frameData.Data, 0, frameData16, 0, (int)frameData.Size); for (var y = 0; y < h; ++y) { for (var x = 0; x < w; ++x) { rows[y][x, c] = frameData16[pos]; pos += offset; } } } } else { var frameData16 = new ushort[w * h]; Buffer.BlockCopy(frameData.Data, 0, frameData16, 0, (int)frameData.Size); for (var y = 0; y < h; ++y) { for (var x = 0; x < w; ++x) { rows[y][x, c] = (short)frameData16[pos]; pos += offset; } } } } #endif else { throw new InvalidOperationException( $"JPEG codec does not support Bits Allocated == {oldPixelData.BitsAllocated}"); } } try { using (var stream = new MemoryStream()) { var sampleRows = rows.Select( row => new SampleRow( ToRawRow(row, oldPixelData.BitsAllocated), w, (byte)oldPixelData.BitsStored, (byte)nc)).ToArray(); var colorSpace = GetColorSpace(oldPixelData.PhotometricInterpretation); using (var encoder = new JpegImage(sampleRows, colorSpace)) { encoder.WriteJpeg(stream, ToCompressionParameters(parameters)); } newPixelData.AddFrame(new MemoryByteBuffer(stream.ToArray())); newPixelData.PhotometricInterpretation = (parameters != null && parameters.SampleFactor == DicomJpegSampleFactor.SF422) ? PhotometricInterpretation.YbrFull422 : PhotometricInterpretation.YbrFull; } } catch (Exception e) { throw new InvalidOperationException("Unable to JPEG encode image", e); } } if (oldPixelData.PhotometricInterpretation == PhotometricInterpretation.Rgb) { newPixelData.PlanarConfiguration = PlanarConfiguration.Interleaved; } }
/// <summary> /// 将BMP文件转换成DICOM文件 /// </summary> /// <param name="file"></param> public static void Bmp2Dcm(string bmpPath, string dcmPath, int TransferSyntax = -1, string sop_uid = "") { Bitmap bitmap = new Bitmap(bmpPath); bitmap = GetValidImage(bitmap); int rows, columns; byte[] pixels = GetPixelsForDicom(bitmap, out rows, out columns); MemoryByteBuffer buffer = new MemoryByteBuffer(pixels); DicomDataset dataset = new DicomDataset(); FillDataset(dataset); dataset.Add(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Rgb.Value); dataset.Add(DicomTag.Rows, (ushort)rows); dataset.Add(DicomTag.Columns, (ushort)columns); if (sop_uid != "") { dataset.Add(DicomTag.SOPInstanceUID, sop_uid); } DicomPixelData pixelData = DicomPixelData.Create(dataset, true); pixelData.BitsStored = 8; pixelData.BitsAllocated = 8; pixelData.SamplesPerPixel = 3; pixelData.HighBit = 7; pixelData.PixelRepresentation = 0; pixelData.PlanarConfiguration = 0; pixelData.AddFrame(buffer); DicomFile _dicomfile = new DicomFile(dataset); DicomFile file = new DicomFile(); switch (TransferSyntax) { case 0: file = _dicomfile.ChangeTransferSyntax(DicomTransferSyntax.JPEG2000Lossless); break; case 1: file = _dicomfile.ChangeTransferSyntax(DicomTransferSyntax.RLELossless); break; case 2: file = _dicomfile.ChangeTransferSyntax(DicomTransferSyntax.JPEGProcess14); break; //JPEG Lossy P1 && P4 case 3: var bits = _dicomfile.Dataset.Get <int>(DicomTag.BitsAllocated, 0, 8); var syntax = DicomTransferSyntax.JPEGProcess1; if (bits == 16) { syntax = DicomTransferSyntax.JPEGProcess2_4; } file = _dicomfile.ChangeTransferSyntax(syntax, new DicomJpegParams { Quality = 100 }); break; case 4: file = _dicomfile.ChangeTransferSyntax(DicomTransferSyntax.ExplicitVRLittleEndian); break; case 5: file = _dicomfile.ChangeTransferSyntax(DicomTransferSyntax.ExplicitVRBigEndian); break; case 6: file = _dicomfile.ChangeTransferSyntax(DicomTransferSyntax.ImplicitVRLittleEndian); break; case 8: file = _dicomfile.ChangeTransferSyntax(DicomTransferSyntax.ImplicitVRBigEndian); break; default: file = _dicomfile; break; } file.Save(dcmPath); }
internal static void Decode( DicomPixelData oldPixelData, DicomPixelData newPixelData, DicomJpegParams parameters) { var pixelCount = oldPixelData.Height * oldPixelData.Width; if (parameters.ConvertColorspaceToRGB) { if (oldPixelData.PixelRepresentation == PixelRepresentation.Signed) { throw new DicomCodecException( "JPEG codec unable to perform colorspace conversion on signed pixel data"); } newPixelData.PhotometricInterpretation = PhotometricInterpretation.Rgb; newPixelData.PlanarConfiguration = PlanarConfiguration.Interleaved; } for (var frame = 0; frame < oldPixelData.NumberOfFrames; frame++) { var jpegData = oldPixelData.GetFrame(frame); // Destination frame should be of even length var frameSize = newPixelData.UncompressedFrameSize; if ((frameSize & 1) == 1) { ++frameSize; } var destArray = new byte[frameSize]; using (var stream = new MemoryStream(jpegData.Data)) { var decoder = new JpegImage(stream); var w = decoder.Width; var h = decoder.Height; for (var c = 0; c < decoder.ComponentsPerSample; c++) { var pos = newPixelData.PlanarConfiguration == PlanarConfiguration.Planar ? c * pixelCount : c; var offset = newPixelData.PlanarConfiguration == PlanarConfiguration.Planar ? 1 : decoder.ComponentsPerSample; if (newPixelData.BytesAllocated == 1) { for (var y = 0; y < h; ++y) { var row = decoder.GetRow(y); for (var x = 0; x < w; ++x) { destArray[pos] = (byte)row[x][c]; pos += offset; } } } #if SUPPORT16BIT else if (newPixelData.BytesAllocated == 2) { var destArray16 = new short[frameSize >> 1]; for (var y = 0; y < h; ++y) { var row = decoder.GetRow(y); for (var x = 0; x < w; ++x) { destArray16[pos] = row[x][c]; pos += offset; } } Buffer.BlockCopy(destArray16, 0, destArray, 0, frameSize); } #endif else { throw new InvalidOperationException( $"JPEG module does not support Bits Allocated == {newPixelData.BitsAllocated}!"); } } newPixelData.AddFrame(new MemoryByteBuffer(destArray)); } } }
// static private void StartGdcm() // { // var s = new gdcm.Reader(); // s.SetFileName("/mnt/c/Users/nikol/Desktop/CR.1.871.3.1522049724.50292.18240.95439262.3570939512.1.1.1"); // bool b = s.CanRead(); // bool d = s.Read(); // } static private unsafe void Main(string[] args) { // ComparingDicomFiles.Start(args); // return; // StartGdcm(); Dicom.Imaging.Codec.TranscoderManager.SetImplementation(new NativeTranscoderManager()); ImageManager.SetImplementation(WinFormsImageManager.Instance); const string filePath = "/mnt/d/DICOM/Fluorography/favorite/jpeg-process14-1/sources/1.871.3.2050448135.34720.20335.72851334.2248937210.1.1.1"; DicomFile dicomFile = DicomFile.Open(filePath); DicomDataset dataset = dicomFile.Dataset; DicomImage dicomImage = new DicomImage(dataset, 0); var image = dicomImage.RenderImage(0); var bitmap = image.AsSharedBitmap(); bitmap.Save("/mnt/c/Users/nikol/Desktop/image-new.png"); byte[] pixelData; Dictionary <string, string> meta; using (FileStream readStream = new FileStream(filePath, FileMode.Open, FileAccess.Read)) pixelData = DicomDatasetExtensions.DecodeImage(readStream, out meta).PixelData; // using (FileStream readStream = new FileStream(sc, FileMode.Open, FileAccess.Read)) // pixelData = DicomDatasetExtensions.DecodeImage(readStream, out meta).PixelData; ushort width = dataset.GetValue <ushort>(DicomTag.Columns, 0); ushort height = dataset.GetValue <ushort>(DicomTag.Rows, 0); byte[] pixelData2 = new byte[pixelData.Length / 2 * 3]; double windowCenter = dataset.GetValue <double>(DicomTag.WindowCenter, 0); double windowWidth = dataset.GetValue <double>(DicomTag.WindowWidth, 0); fixed(byte *pPixelData = &pixelData[0]) for (int pixelIndex = 0; pixelIndex != pixelData.Length / 2; pixelIndex++) { int rowIndex = pixelIndex / width; pixelData2[pixelIndex * 3 + (int)(rowIndex / (double)height * 3)] = (byte)(Math.Clamp((*(((ushort *)pPixelData) + pixelIndex) - windowCenter + windowWidth * 0.5), 0.0, windowWidth) / windowWidth * 255.0); } meta = new Dictionary <string, string>(); foreach (var item in dataset) { try { string value = dataset.GetValue <string>(item.Tag, 0); int count = dataset.GetValueCount(item.Tag); for (int valueIndex = 1; valueIndex != count; valueIndex++) { value += $"\\{dataset.GetValue<string>(item.Tag, valueIndex)}"; } meta.Add(item.Tag.ToString().Replace("(", string.Empty).Replace(")", string.Empty).Replace(',', '|'), value); } catch { } } fixed(byte *p = &pixelData2[0]) { var im = itk.simple.SimpleITK.ImportAsUInt8(new IntPtr(p), new itk.simple.VectorUInt32(new uint[] { width, height }), new itk.simple.VectorDouble(new double[] { 1, 1 }), new itk.simple.VectorDouble(new double[] { 0, 0 }), new itk.simple.VectorDouble(new double[] { 1, 0, 0, 1 }), 3); itk.simple.ImageFileWriter writer = new itk.simple.ImageFileWriter(); writer.SetFileName("/mnt/c/Users/nikol/Desktop/rewritten.dcm"); writer.KeepOriginalImageUIDOff(); foreach (var pair in meta) { im.SetMetaData(pair.Key, pair.Value); } writer.SetImageIO("GDCMImageIO"); writer.UseCompressionOff(); writer.Execute(im); writer.Dispose(); im.Dispose(); } // dicomFile = DicomFile.Open("/mnt/c/Users/nikol/Desktop/CR.1.871.3.1522049724.50292.18240.95439262.3570939512.1.1.dcm"); // dicomFile.Dataset.AddOrUpdate<string>(DicomTag.StudyInstanceUID, dicomFile.Dataset.GetSingleValue<string>(DicomTag.StudyInstanceUID)); // dicomFile.Save("/mnt/c/Users/nikol/Desktop/CR.1.871.3.1522049724.50292.18240.95439262.3570939512.1.2.dcm"); DicomDataset dataset2 = new DicomDataset(); dataset.CopyTo(dataset2); dataset = dataset2; DicomPixelData dicomPixelData = DicomPixelData.Create(dataset, true); dicomPixelData.AddFrame(new MemoryByteBuffer(pixelData2)); dataset.AddOrUpdate(DicomTag.StudyInstanceUID, DicomUIDGenerator.GenerateDerivedFromUUID()); dataset.AddOrUpdate(DicomTag.SeriesInstanceUID, DicomUIDGenerator.GenerateDerivedFromUUID()); dataset.AddOrUpdate(DicomTag.SOPInstanceUID, DicomUIDGenerator.GenerateDerivedFromUUID()); dataset.AddOrUpdate(DicomTag.BitsAllocated, (ushort)8); dataset.AddOrUpdate(DicomTag.BitsStored, (ushort)8); dataset.AddOrUpdate(DicomTag.HighBit, (ushort)7); dataset.AddOrUpdate(DicomTag.PixelRepresentation, (ushort)0); dataset.AddOrUpdate(DicomTag.SamplesPerPixel, (ushort)3); dataset.AddOrUpdate(DicomTag.PlanarConfiguration, (ushort)0); dataset.AddOrUpdate(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Rgb.Value); dataset.AddOrUpdate(DicomTag.WindowCenter, 127.5); dataset.AddOrUpdate(DicomTag.WindowWidth, 255.0); dicomFile = new DicomFile(dataset); dicomFile.Save("/mnt/c/Users/nikol/Desktop/efferent-no-compression.dcm"); var j2000lossy = dataset.Compress(DicomTransferSyntax.JPEGLSLossless, new DicomJpegLsLosslessCodec(), new Dicom.Imaging.Codec.DicomJpegLsParams()); j2000lossy.AddOrUpdate(DicomTag.StudyInstanceUID, DicomUIDGenerator.GenerateDerivedFromUUID()); j2000lossy.AddOrUpdate(DicomTag.SeriesInstanceUID, DicomUIDGenerator.GenerateDerivedFromUUID()); j2000lossy.AddOrUpdate(DicomTag.SOPInstanceUID, DicomUIDGenerator.GenerateDerivedFromUUID()); dicomFile = new DicomFile(j2000lossy); dicomFile.Save("/mnt/c/Users/nikol/Desktop/efferent-ls-lossless.dcm"); var j2000lossless = dataset.Compress(DicomTransferSyntax.JPEGLSNearLossless, new DicomJpegLsNearLosslessCodec(), new Dicom.Imaging.Codec.DicomJpegLsParams()); j2000lossless.AddOrUpdate(DicomTag.StudyInstanceUID, DicomUIDGenerator.GenerateDerivedFromUUID()); j2000lossless.AddOrUpdate(DicomTag.SeriesInstanceUID, DicomUIDGenerator.GenerateDerivedFromUUID()); j2000lossless.AddOrUpdate(DicomTag.SOPInstanceUID, DicomUIDGenerator.GenerateDerivedFromUUID()); dicomFile = new DicomFile(j2000lossless); dicomFile.Save("/mnt/c/Users/nikol/Desktop/efferent-ls-near-lossless.dcm"); // RemovePixelDataProgram.Start(args); // ItkSimpleTestProgram.Start(args); // ImageTestProgram.Start(args); // CheckImageAttributesProgram.Start(args); // TestDicom48bpp.Start(args); // Testing3D.Start(args); // TestingWindowPresets.Start(args); // TestingMultiImageDicom.Start(args); // ComparingDicomFiles.Start(args); // PresentationState.Start(args); // PresentationStateAnalyzer.Start(args); }