예제 #1
0
        public async Task GivenMultipleFrames_WhenRetrieveFrame_ThenServerShouldReturnExpectedContent()
        {
            string studyInstanceUid = TestUidGenerator.Generate();

            DicomFile          dicomFile1    = Samples.CreateRandomDicomFileWithPixelData(studyInstanceUid, frames: 3);
            DicomPixelData     pixelData     = DicomPixelData.Create(dicomFile1.Dataset);
            InstanceIdentifier dicomInstance = dicomFile1.Dataset.ToInstanceIdentifier();

            await InternalStoreAsync(new[] { dicomFile1 });

            using DicomWebAsyncEnumerableResponse <Stream> response = await _client.RetrieveFramesAsync(
                      dicomInstance.StudyInstanceUid,
                      dicomInstance.SeriesInstanceUid,
                      dicomInstance.SopInstanceUid,
                      frames : new[] { 1, 2 },
                      dicomTransferSyntax : "*");

            Stream[] frames = await response.ToArrayAsync();

            Assert.NotNull(frames);
            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            Assert.Equal(2, frames.Length);
            Assert.Equal(KnownContentTypes.MultipartRelated, response.ContentHeaders.ContentType.MediaType);
            Assert.Equal(pixelData.GetFrame(0).Data, frames[0].ToByteArray());
            Assert.Equal(pixelData.GetFrame(1).Data, frames[1].ToByteArray());
        }
예제 #2
0
		/// <summary>
		/// Create <see cref="IPixelData"/> form <see cref="DicomPixelData"/> 
		/// according to the input <paramref name="pixelData"/> <seealso cref="PhotometricInterpretation"/>
		/// </summary>
		/// <param name="pixelData">Input pixel data</param>
		/// <param name="frame">Frame number (0 based)</param>
		/// <returns>Implementation of <seealso cref="IPixelData"/> according to <seealso cref="PhotometricInterpretation"/></returns>
		public static IPixelData Create(DicomPixelData pixelData, int frame) {
			PhotometricInterpretation pi = pixelData.PhotometricInterpretation;

			if (pi == null) {
				// generally ACR-NEMA
				var samples = pixelData.SamplesPerPixel;
				if (samples == 0 || samples == 1) {
					if (pixelData.Dataset.Contains(DicomTag.RedPaletteColorLookupTableData))
						pi = PhotometricInterpretation.PaletteColor;
					else
						pi = PhotometricInterpretation.Monochrome2;
				} else {
					// assume, probably incorrectly, that the image is RGB
					pi = PhotometricInterpretation.Rgb;
				}
			}

			if (pixelData.BitsStored == 1) {
				if (pixelData.Dataset.Get<DicomUID>(DicomTag.SOPClassUID) == DicomUID.MultiFrameSingleBitSecondaryCaptureImageStorage)
					// Multi-frame Single Bit Secondary Capture is stored LSB -> MSB
					return new SingleBitPixelData(pixelData.Width, pixelData.Height, PixelDataConverter.ReverseBits(pixelData.GetFrame(frame)));
				else
					// Need sample images to verify that this is correct
					return new SingleBitPixelData(pixelData.Width, pixelData.Height, pixelData.GetFrame(frame));
			} else if (pi == PhotometricInterpretation.Monochrome1 || pi == PhotometricInterpretation.Monochrome2 || pi == PhotometricInterpretation.PaletteColor) {
				if (pixelData.BitsAllocated <= 8)
					return new GrayscalePixelDataU8(pixelData.Width, pixelData.Height, pixelData.GetFrame(frame));
				else if (pixelData.BitsAllocated <= 16) {
					if (pixelData.PixelRepresentation == PixelRepresentation.Signed)
						return new GrayscalePixelDataS16(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame));
					else
						return new GrayscalePixelDataU16(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame));
				} else if (pixelData.BitsAllocated <= 32) {
                    if (pixelData.PixelRepresentation == PixelRepresentation.Signed)
						return new GrayscalePixelDataS32(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame));
                    else
						return new GrayscalePixelDataU32(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame));
				} else
					throw new DicomImagingException("Unsupported pixel data value for bits stored: {0}", pixelData.BitsStored);
			} else if (pi == PhotometricInterpretation.Rgb || pi == PhotometricInterpretation.YbrFull) {
				var buffer = pixelData.GetFrame(frame);
				if (pixelData.PlanarConfiguration == PlanarConfiguration.Planar)
					buffer = PixelDataConverter.PlanarToInterleaved24(buffer);
				return new ColorPixelData24(pixelData.Width, pixelData.Height, buffer);
			} else {
				throw new DicomImagingException("Unsupported pixel data photometric interpretation: {0}", pi.Value);
			}
		}
예제 #3
0
		/// <summary>
		/// Create <see cref="IPixelData"/> form <see cref="DicomPixelData"/> 
		/// according to the input <paramref name="pixelData"/> <seealso cref="PhotometricInterpretation"/>
		/// </summary>
		/// <param name="pixelData">Input pixel data</param>
		/// <param name="frame">Frame number (0 based)</param>
		/// <returns>Implementation of <seealso cref="IPixelData"/> according to <seealso cref="PhotometricInterpretation"/></returns>
		public static IPixelData Create(DicomPixelData pixelData, int frame) {
			PhotometricInterpretation pi = pixelData.PhotometricInterpretation;

			if (pi == null) {
				// generally ACR-NEMA
				var samples = pixelData.SamplesPerPixel;
				if (samples == 0 || samples == 1) {
					if (pixelData.Dataset.Contains(DicomTag.RedPaletteColorLookupTableData))
						pi = PhotometricInterpretation.PaletteColor;
					else
						pi = PhotometricInterpretation.Monochrome2;
				} else {
					// assume, probably incorrectly, that the image is RGB
					pi = PhotometricInterpretation.Rgb;
				}
			}

			if (pi == PhotometricInterpretation.Monochrome1 || pi == PhotometricInterpretation.Monochrome2 || pi == PhotometricInterpretation.PaletteColor) {
				if (pixelData.BitsAllocated <= 8)
					return new GrayscalePixelDataU8(pixelData.Width, pixelData.Height, pixelData.GetFrame(frame));
				else if (pixelData.BitsAllocated <= 16) {
					if (pixelData.PixelRepresentation == PixelRepresentation.Signed)
						return new GrayscalePixelDataS16(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame));
					else
						return new GrayscalePixelDataU16(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame));
				} else if (pixelData.BitsAllocated <= 32) {
                    if (pixelData.PixelRepresentation == PixelRepresentation.Signed)
						return new GrayscalePixelDataS32(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame));
                    else
						return new GrayscalePixelDataU32(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame));
				} else
					throw new DicomImagingException("Unsupported pixel data value for bits stored: {0}", pixelData.BitsStored);
			} else if (pi == PhotometricInterpretation.Rgb || pi == PhotometricInterpretation.YbrFull) {
				var buffer = pixelData.GetFrame(frame);
				if (pixelData.PlanarConfiguration == PlanarConfiguration.Planar)
					buffer = PixelDataConverter.PlanarToInterleaved24(buffer);
				return new ColorPixelData24(pixelData.Width, pixelData.Height, buffer);
            } else if (pi == PhotometricInterpretation.YbrFull422)
            {
                var buffer = pixelData.GetFrame(frame);
                if (pixelData.PlanarConfiguration == PlanarConfiguration.Planar)
                    throw new DicomImagingException("Unsupported planar configuration for YBR_FULL_422");
                return new ColorPixelData24(pixelData.Width, pixelData.Height, buffer);
            }
            else {
				throw new DicomImagingException("Unsupported pixel data photometric interpretation: {0}", pi.Value);
			}
		}
        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);
            }
        }
예제 #5
0
        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));
            }
        }
 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)
     });
 }
예제 #7
0
        public async Task GivenSupportedAcceptHeaders_WhenRetrieveFrame_ThenServerShouldReturnExpectedContent(string testDataFolder, string mediaType, string transferSyntax)
        {
            TranscoderTestData transcoderTestData = TranscoderTestDataHelper.GetTestData(testDataFolder);
            DicomFile          inputDicomFile     = await DicomFile.OpenAsync(transcoderTestData.InputDicomFile);

            await EnsureFileIsStoredAsync(inputDicomFile);

            var instanceId = inputDicomFile.Dataset.ToInstanceIdentifier();

            _studiesToClean.Add(instanceId.StudyInstanceUid);

            DicomFile      outputDicomFile = DicomFile.Open(transcoderTestData.ExpectedOutputDicomFile);
            DicomPixelData pixelData       = DicomPixelData.Create(outputDicomFile.Dataset);

            using DicomWebAsyncEnumerableResponse <Stream> response = await _client.RetrieveFramesAsync(
                      instanceId.StudyInstanceUid,
                      instanceId.SeriesInstanceUid,
                      instanceId.SopInstanceUid,
                      mediaType,
                      transferSyntax,
                      frames : new[] { 1 });

            int frameIndex = 0;

            await foreach (Stream item in response)
            {
                // TODO: verify media type once https://microsofthealth.visualstudio.com/Health/_workitems/edit/75185 is done
                Assert.Equal(item.ToByteArray(), pixelData.GetFrame(frameIndex).Data);
                frameIndex++;
            }
        }
예제 #8
0
        private DicomDataset Encode(DicomDataset oldDataset, DicomTransferSyntax inSyntax, IDicomCodec codec, DicomCodecParams parameters)
        {
            DicomPixelData oldPixelData = DicomPixelData.Create(oldDataset, false);

            DicomDataset newDataset = oldDataset.Clone();

            newDataset.InternalTransferSyntax = codec.TransferSyntax;
            DicomPixelData newPixelData = DicomPixelData.Create(newDataset, true);

            codec.Encode(oldPixelData, newPixelData, parameters);

            if (codec.TransferSyntax.IsLossy && newPixelData.NumberOfFrames > 0)
            {
                newDataset.Add(new DicomCodeString(DicomTag.LossyImageCompression, "01"));

                List <string> methods = new List <string>();
                if (newDataset.Contains(DicomTag.LossyImageCompressionMethod))
                {
                    methods.AddRange(newDataset.Get <string[]>(DicomTag.LossyImageCompressionMethod));
                }
                methods.Add(codec.TransferSyntax.LossyCompressionMethod);
                newDataset.Add(new DicomCodeString(DicomTag.LossyImageCompressionMethod, methods.ToArray()));

                double oldSize = oldPixelData.GetFrame(0).Size;
                double newSize = newPixelData.GetFrame(0).Size;
                string ratio   = String.Format("{0:0.000}", oldSize / newSize);
                newDataset.Add(new DicomDecimalString(DicomTag.LossyImageCompressionRatio, ratio));
            }

            ProcessOverlays(oldDataset, newDataset);

            newDataset.RecalculateGroupLengths(false);

            return(newDataset);
        }
예제 #9
0
        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);
                }
            }
        }
예제 #10
0
        public void SavePixels(string filename)
        {
            DicomPixelData pd = DicomPixelData.CreateFrom(_dicomFile);

            if (File.Exists(filename))
            {
                File.Delete(filename);
            }

            using (FileStream fs = new FileStream(filename, FileMode.CreateNew))
            {
                byte[] ba;
                DicomCompressedPixelData compressed = pd as DicomCompressedPixelData;
                if (compressed != null)
                {
                    ba = compressed.GetFrameFragmentData(0);
                }
                else
                {
                    ba = pd.GetFrame(0);
                }

                fs.Write(ba, 0, ba.Length);
                fs.Flush();
                fs.Close();
            }
        }
예제 #11
0
        private Stream GetFrameAsDicomData(DicomPixelData pixelData, int frame)
        {
            EnsureArg.IsNotNull(pixelData, nameof(pixelData));

            IByteBuffer resultByteBuffer = pixelData.GetFrame(frame);

            return(_recyclableMemoryStreamManager.GetStream("FrameHandler.GetFrameAsDicomData", resultByteBuffer.Data, 0, resultByteBuffer.Data.Length));
        }
        /// <summary>
        /// Extracts DICOM file data and saves it as a UByteArrayAsImage.
        /// </summary>
        /// <param name="f">A DICOM file</param>
        /// <returns>A UByteArrayAsImage</returns>
        public static UByteArrayAsImage GetUByteImageInfo(this DicomFile f)
        {
            DicomPixelData pixelData = DicomPixelData.Create(f.Dataset);
            int            columns   = f.Dataset.GetValue <int>(DicomTag.Columns, 0);
            int            rows      = f.Dataset.GetValue <int>(DicomTag.Rows, 0);

            byte[] byteData = pixelData.GetFrame(0).Data;
            return(new UByteArrayAsImage(byteData, columns, rows));
        }
예제 #13
0
        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);
                }
            }
        }
예제 #14
0
        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);
                }
            }
        }
예제 #15
0
        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));
            }
        }
예제 #16
0
        protected override void Upload(fo.DicomDataset dicomObject, int frame, IStorageLocation storeLocation)
        {
            var frameIndex = frame - 1;

            DicomPixelData pd = DicomPixelData.Create(dicomObject);


            byte[] buffer = pd.GetFrame(frameIndex).Data;

            storeLocation.Upload(buffer);
        }
예제 #17
0
        private string GetFramesHashCode(DicomFile dicomFile)
        {
            DicomPixelData dicomPixelData = DicomPixelData.Create(dicomFile.Dataset);
            List <byte>    frames         = new List <byte>();

            for (int i = 0; i < dicomPixelData.NumberOfFrames; i++)
            {
                frames.AddRange(dicomPixelData.GetFrame(i).Data);
            }

            return(GetByteArrayHashCode(frames.ToArray()));
        }
예제 #18
0
        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);
            }
        }
        protected override void Upload(DicomFile dicomObject, int frame, IStorageLocation storeLocation)
        {
            DicomPixelData pd = null;

            byte[] buffer = null;


            pd     = DicomPixelData.CreateFrom(dicomObject);
            buffer = pd.GetFrame(frame - 1);

            storeLocation.Upload(buffer);
        }
예제 #20
0
        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);
            }
        }
예제 #21
0
        private static int[] GetGrayPixelData(DicomDataset dataset)
        {
            DicomPixelData pixelData = DicomPixelData.Create(dataset);
            IByteBuffer    buffer    = pixelData.GetFrame(0);

            IPixelData data          = PixelDataFactory.Create(pixelData, 0);
            var        renderOptions = GrayscaleRenderOptions.FromDataset(dataset);

            int[] output = new int[pixelData.Width * pixelData.Height];
            data.Render(new ModalityLUT(renderOptions), output);
            return(output);
        }
예제 #22
0
        public byte[] ReadFrame(int frame)
        {
            DicomPixelData pd = _context.PixelData;

            if (pd is DicomCompressedPixelData)
            {
                byte[] buffer = (pd as DicomCompressedPixelData).GetFrameFragmentData(frame);
                return(buffer);
            }
            else
            {
                return(pd.GetFrame(frame));
            }
        }
예제 #23
0
    private void loadPixels()
    {
        // code found at https://groups.google.com/forum/#!topic/fo-dicom/EQtF5-7_PAU
        DicomPixelData pxd    = DicomPixelData.Create(dicomFile.Dataset);
        IByteBuffer    buffer = pxd.GetFrame(0);

        slicePixels = Dicom.IO.ByteConverter.ToArray <ushort>(buffer);
        //byte[] bSlicePixels = Dicom.IO.ByteConverter.ToArray<byte>(buffer);

        // alternative:
        //var header = DicomPixelData.Create(dicomFile.Dataset);
        //var pixelData = PixelDataFactory.Create(header, 0);
        //ushort[] pixels = ((GrayscalePixelDataU16)pixelData).Data;
    }
예제 #24
0
        public Stream Convert(DicomAttributeCollection ds)
        {
            DicomAttributeCollection command = new DicomAttributeCollection();

            command[DicomTags.TransferSyntaxUid] = ds[DicomTags.TransferSyntaxUid];
            DicomMessage message = new DicomMessage(command, ds);


            DicomPixelData pd       = DicomPixelData.CreateFrom(message);
            string         tempFile = System.IO.Path.GetTempFileName( );

            System.IO.File.WriteAllBytes(tempFile, pd.GetFrame(0));

            return(new DICOMcloud.Core.Storage.TempStream(new TempFile(tempFile)));
        }
예제 #25
0
        public static IByteBuffer ExtractSingleFrame(DicomDataset dataset, int frame)
        {
            DicomPixelData pixelData = DicomPixelData.Create(dataset);
            int            frames    = pixelData.NumberOfFrames;

            if (frame > frames)
            {
                return(null);
            }
            else
            {
                var frameData = pixelData.GetFrame(frame);
                return(frameData);
            }
        }
예제 #26
0
        static public unsafe void GetAverageValue(this DicomDataset original, out double average, out double dispersion, out ushort min, out ushort max)
        {
            DicomPixelData pixelDataSource = DicomPixelData.Create(original, false);

            if (pixelDataSource.BytesAllocated != 2 || pixelDataSource.SamplesPerPixel != 1)
            {
                throw new Exception();
            }
            IByteBuffer buffer = pixelDataSource.GetFrame(0);

            byte[] bytes = buffer.Data;
            int    size  = (int)buffer.Size;

            GetAverageValue(original, bytes, size, out average, out dispersion, out min, out max);
        }
예제 #27
0
        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));
            }
        }
예제 #28
0
        public GridBasedVoxelDataStructure Load(DicomFile[] dicomFiles)
        {
            GridBasedVoxelDataStructure grid = new GridBasedVoxelDataStructure();

            DicomFile[]   files       = SortOnZIncreasing(dicomFiles);
            PixelDataInfo DicomHeader = new PixelDataInfo(files[0]);
            Point3d       size        = GetSize(files);

            grid.ConstantGridSpacing = true;
            grid.GridSpacing         = GetSpacing(files);
            grid.XCoords             = GetCoords(files, (int)size.X, DicomHeader.RowDir.X, DicomHeader.ColDir.X, DicomHeader.ImagePositionPatient.X, 1);
            grid.YCoords             = GetCoords(files, (int)size.Y, DicomHeader.RowDir.Y, DicomHeader.ColDir.Y, DicomHeader.ImagePositionPatient.Y, 1);
            grid.ZCoords             = GetCoords(files, (int)size.Z, DicomHeader.RowDir.Z, DicomHeader.ColDir.Z, DicomHeader.ImagePositionPatient.Z, 1);
            grid.Data = new float[(int)size.X / 1, (int)size.Y / 1, (int)size.Z / 1];

            int currYIndex = 0;
            int currZIndex = 0;
            int currXIndex = 0;

            for (int i = 0; i < files.Length; i++)
            {
                DicomPixelData dicomPixelData = DicomPixelData.Create(files[i].Dataset);
                PixelDataInfo  tempHeaderInfo = new PixelDataInfo(files[i]);
                for (int j = 0; j < tempHeaderInfo.GridFrameOffsetVector.Length; j++)
                {
                    byte[]  framePixelData = dicomPixelData.GetFrame(j).Data;
                    float[] dataArray      = GetDataArray(framePixelData, tempHeaderInfo.BitsAllocated, tempHeaderInfo.PixelRepresentation);
                    for (int k = 0; k < dataArray.Length; k++)
                    {
                        int currRow = k % tempHeaderInfo.Columns;
                        int currCol = (int)Math.Floor((double)(k / (tempHeaderInfo.Columns)));
                        currXIndex = (int)Math.Abs(tempHeaderInfo.RowDir.X) * currRow + (int)Math.Abs(tempHeaderInfo.ColDir.X) * currCol
                                     + (1 - (int)Math.Abs(tempHeaderInfo.RowDir.X) - (int)Math.Abs(tempHeaderInfo.ColDir.X)) * (i + j);;
                        currYIndex = (int)Math.Abs(tempHeaderInfo.RowDir.Y) * currRow + (int)Math.Abs(tempHeaderInfo.ColDir.Y) * currCol
                                     + (1 - (int)Math.Abs(tempHeaderInfo.RowDir.Y) - (int)Math.Abs(tempHeaderInfo.ColDir.Y)) * (i + j);;
                        currZIndex = (int)Math.Abs(tempHeaderInfo.RowDir.Z) * currRow + (int)Math.Abs(tempHeaderInfo.ColDir.Z) * currCol
                                     + (1 - (int)Math.Abs(tempHeaderInfo.RowDir.Z) - (int)Math.Abs(tempHeaderInfo.ColDir.Z)) * (i + j);

                        //Rescale back to actual values
                        dataArray[k] = dataArray[k] * tempHeaderInfo.RescaleSlope + tempHeaderInfo.RescaleSlope;
                        grid.Data[currXIndex, currYIndex, currZIndex] = dataArray[k];
                    }
                }
            }
            return(grid);
            //setGlobalMax();
        }
        /// <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));
            }
        }
        public SliceBasedVoxelDataStructure Load(DicomFile[] files)
        {
            SliceBasedVoxelDataStructure grid = new SliceBasedVoxelDataStructure();

            files = sort(files);

            PixelDataInfo[] headerInfos = GetHeaderInfo(files);

            if (files.Length > 1)
            {
                grid.MatrixA = getMatrixA(files.First(), files.Last(), files.Length);
            }
            else
            {
                grid.MatrixA = getSingleMatrixA(files[0]);
            }

            for (int i = 0; i < files.Length; i++)
            {
                PixelDataInfo  headerInfo     = headerInfos[i];
                DicomPixelData dicomPixelData = DicomPixelData.Create(files[i].Dataset);

                for (int j = 0; j < headerInfo.GridFrameOffsetVector.Length; j++)
                {
                    byte[]  framePixelData = dicomPixelData.GetFrame(j).Data;
                    float[] dataArray      = GetDataArray(framePixelData, dicomPixelData.BitsAllocated, headerInfo.PixelRepresentation);
                    //rescale to proper values
                    for (int k = 0; k < dataArray.Length; k++)
                    {
                        dataArray[k] = dataArray[k] * headerInfo.RescaleSlope + headerInfo.RescaleIntercept;
                    }

                    grid.AddSlice(dataArray, headerInfo.Rows, headerInfo.Columns, headerInfo.PixelSpacing[0], headerInfo.PixelSpacing[1], headerInfo.ImagePositionPatient.X, headerInfo.ImagePositionPatient.Y, headerInfo.ImagePositionPatient.Z + headerInfo.GridFrameOffsetVector[j], headerInfo.RowDir.X, headerInfo.RowDir.Y, headerInfo.RowDir.Z, headerInfo.ColDir.X, headerInfo.ColDir.Y, headerInfo.ColDir.Z);
                }
                files[i] = null;
            }

            //grid.Window = (int)grid.GlobalMax.Value ;
            //grid.Level = (int)(grid.GlobalMax.Value / 2);

            return(grid);
        }
예제 #31
0
        public static IPixelData Create(DicomPixelData pixelData, int frame)
        {
            PhotometricInterpretation pi = pixelData.PhotometricInterpretation;

            if (pi == PhotometricInterpretation.Monochrome1 || pi == PhotometricInterpretation.Monochrome2 || pi == PhotometricInterpretation.PaletteColor)
            {
                if (pixelData.BitsStored <= 8)
                {
                    return(new GrayscalePixelDataU8(pixelData.Width, pixelData.Height, pixelData.GetFrame(frame)));
                }
                else if (pixelData.BitsStored <= 16)
                {
                    if (pixelData.PixelRepresentation == PixelRepresentation.Signed)
                    {
                        return(new GrayscalePixelDataS16(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame)));
                    }
                    else
                    {
                        return(new GrayscalePixelDataU16(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame)));
                    }
                }
                else
                {
                    throw new DicomImagingException("Unsupported pixel data value for bits stored: {0}", pixelData.BitsStored);
                }
            }
            else if (pi == PhotometricInterpretation.Rgb || pi == PhotometricInterpretation.YbrFull)
            {
                var buffer = pixelData.GetFrame(frame);
                if (pixelData.PlanarConfiguration == PlanarConfiguration.Planar)
                {
                    buffer = PixelDataConverter.PlanarToInterleaved24(buffer);
                }
                return(new ColorPixelData24(pixelData.Width, pixelData.Height, buffer));
            }
            else
            {
                throw new DicomImagingException("Unsupported pixel data photometric interpretation: {0}", pi.Value);
            }
        }
예제 #32
0
        /// <summary>
        /// Create <see cref="IPixelData"/> form <see cref="DicomPixelData"/> 
        /// according to the input <paramref name="pixelData"/> <seealso cref="PhotometricInterpretation"/>
        /// </summary>
        /// <param name="pixelData">Input pixel data</param>
        /// <param name="frame">Frame number (0 based)</param>
        /// <returns>Implementation of <seealso cref="IPixelData"/> according to <seealso cref="PhotometricInterpretation"/></returns>
        public static IPixelData Create(DicomPixelData pixelData, int frame)
        {
            PhotometricInterpretation pi = pixelData.PhotometricInterpretation;

            if (pi == null)
            {
                // generally ACR-NEMA
                var samples = pixelData.SamplesPerPixel;
                if (samples == 0 || samples == 1)
                {
                    pi = pixelData.Dataset.Contains(DicomTag.RedPaletteColorLookupTableData)
                        ? PhotometricInterpretation.PaletteColor
                        : PhotometricInterpretation.Monochrome2;
                }
                else
                {
                    // assume, probably incorrectly, that the image is RGB
                    pi = PhotometricInterpretation.Rgb;
                }
            }

            if (pixelData.BitsStored == 1)
            {
                if (pixelData.Dataset.GetSingleValue<DicomUID>(DicomTag.SOPClassUID)
                    == DicomUID.MultiFrameSingleBitSecondaryCaptureImageStorage)
                    // Multi-frame Single Bit Secondary Capture is stored LSB -> MSB
                    return new SingleBitPixelData(
                        pixelData.Width,
                        pixelData.Height,
                        PixelDataConverter.ReverseBits(pixelData.GetFrame(frame)));
                else
                // Need sample images to verify that this is correct
                    return new SingleBitPixelData(pixelData.Width, pixelData.Height, pixelData.GetFrame(frame));
            }
            else if (pi == PhotometricInterpretation.Monochrome1 || pi == PhotometricInterpretation.Monochrome2
                     || pi == PhotometricInterpretation.PaletteColor)
            {
                if (pixelData.BitsAllocated == 8 && pixelData.HighBit == 7 && pixelData.BitsStored == 8)
                    return new GrayscalePixelDataU8(pixelData.Width, pixelData.Height, pixelData.GetFrame(frame));
                else if (pixelData.BitsAllocated <= 16)
                {
                    if (pixelData.PixelRepresentation == PixelRepresentation.Signed)
                        return new GrayscalePixelDataS16(
                            pixelData.Width,
                            pixelData.Height,
                            pixelData.BitDepth,
                            pixelData.GetFrame(frame));
                    else
                        return new GrayscalePixelDataU16(
                            pixelData.Width,
                            pixelData.Height,
                            pixelData.BitDepth,
                            pixelData.GetFrame(frame));
                }
                else if (pixelData.BitsAllocated <= 32)
                {
                    if (pixelData.PixelRepresentation == PixelRepresentation.Signed)
                        return new GrayscalePixelDataS32(
                            pixelData.Width,
                            pixelData.Height,
                            pixelData.BitDepth,
                            pixelData.GetFrame(frame));
                    else
                        return new GrayscalePixelDataU32(
                            pixelData.Width,
                            pixelData.Height,
                            pixelData.BitDepth,
                            pixelData.GetFrame(frame));
                }
                else
                    throw new DicomImagingException(
                        "Unsupported pixel data value for bits stored: {0}",
                        pixelData.BitsStored);
            }
            else if (pi == PhotometricInterpretation.Rgb || pi == PhotometricInterpretation.YbrFull
                     || pi == PhotometricInterpretation.YbrFull422 || pi == PhotometricInterpretation.YbrPartial422)
            {
                var buffer = pixelData.GetFrame(frame);

                if (pixelData.PlanarConfiguration == PlanarConfiguration.Planar) buffer = PixelDataConverter.PlanarToInterleaved24(buffer);

                if (pi == PhotometricInterpretation.YbrFull) buffer = PixelDataConverter.YbrFullToRgb(buffer);
                else if (pi == PhotometricInterpretation.YbrFull422) buffer = PixelDataConverter.YbrFull422ToRgb(buffer, pixelData.Width);
                else if (pi == PhotometricInterpretation.YbrPartial422) buffer = PixelDataConverter.YbrPartial422ToRgb(buffer, pixelData.Width);

                return new ColorPixelData24(pixelData.Width, pixelData.Height, buffer);
            }
            else if (pi == PhotometricInterpretation.YbrFull422)
            {
                var buffer = pixelData.GetFrame(frame);
                if (pixelData.PlanarConfiguration == PlanarConfiguration.Planar) throw new DicomImagingException("Unsupported planar configuration for YBR_FULL_422");
                return new ColorPixelData24(pixelData.Width, pixelData.Height, buffer);
            }
            else
            {
                throw new DicomImagingException(
                    "Unsupported pixel data photometric interpretation: {0}",
                    pi.Value);
            }
        }
예제 #33
0
        public static bool Compare(DicomPixelData pixels1, DicomPixelData pixels2, out string failureDescription)
        {
            failureDescription = string.Empty;
            if (pixels1.BitsAllocated != pixels2.BitsAllocated)
            {
                failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Bits Allocated varies: {0} , {1}", pixels1.BitsAllocated, pixels2.BitsAllocated);
                return false;
            }

            if (pixels1.BitsStored != pixels2.BitsStored)
            {
                failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Bits Stored varies: {0} , {1}", pixels1.BitsStored, pixels2.BitsStored);
                return false;
            }

            if (pixels1.ImageHeight != pixels2.ImageHeight)
            {
                failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Rows varies: {0} , {1}", pixels1.ImageHeight, pixels2.ImageHeight);
                return false;
            }

            if (pixels1.ImageWidth != pixels2.ImageWidth)
            {
                failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Columns varies: {0} , {1}", pixels1.ImageWidth, pixels2.ImageWidth);
                return false;
            }

            if (pixels1.SamplesPerPixel != pixels2.SamplesPerPixel)
            {
                failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Samples per pixel varies: {0} , {1}", pixels1.SamplesPerPixel, pixels2.SamplesPerPixel);
                return false;
            }

            if (pixels1.NumberOfFrames != pixels2.NumberOfFrames)
            {
                failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Number of frames varies: {0} , {1}", pixels1.NumberOfFrames, pixels2.NumberOfFrames);
                return false;
            }

            long pixelsVarying = 0;
            long totalVariation = 0;

            int pixels = pixels1.ImageHeight * pixels1.ImageWidth * pixels1.SamplesPerPixel;

            if (pixels1.BitsAllocated == 8)
            {
                for (int frame = 0; frame < pixels1.NumberOfFrames; frame++)
                {
                    byte[] pixel1 = pixels1.GetFrame(frame);
                    byte[] pixel2 = pixels2.GetFrame(frame);

                    if (pixels1.HighBit != pixels2.HighBit)
                    {
                        // Justify the pixel, if needed
                        if (DicomUncompressedPixelData.RightAlign(pixel1, pixels1.BitsAllocated, pixels1.BitsStored,
                                                                  pixels1.HighBit))
                        {
                            //pixels1.HighBit = (ushort)(pixels1.BitsStored - 1);
                            DicomUncompressedPixelData.ZeroUnusedBits(pixel1, pixels1.BitsAllocated, pixels1.BitsStored,
                                                                      pixels1.BitsStored - 1);
                        }
                        if (DicomUncompressedPixelData.RightAlign(pixel2, pixels2.BitsAllocated, pixels2.BitsStored,
                                                                  pixels2.HighBit))
                        {
                            //pixels2.HighBit = (ushort)(pixels2.BitsStored - 1);
                            DicomUncompressedPixelData.ZeroUnusedBits(pixel2, pixels2.BitsAllocated, pixels2.BitsStored,
                                                                      pixels2.BitsStored - 1);
                        }
                    }

                    int[] intPixels1 = pixels1.IsSigned
                                           ? Convert8BitSigned(pixel1, pixels, (DicomUncompressedPixelData)pixels1)
                                           : Convert8BitUnsigned(pixel1, pixels, (DicomUncompressedPixelData)pixels1);

                    int[] intPixels2 = pixels2.IsSigned
                                           ? Convert8BitSigned(pixel2, pixels, (DicomUncompressedPixelData)pixels2)
                                           : Convert8BitUnsigned(pixel2, pixels, (DicomUncompressedPixelData)pixels2);


                    for (int i = 0; i < pixels; i++)
                        if (intPixels1[i] != intPixels2[i])
                        {
                            pixelsVarying++;
                            totalVariation += Math.Abs(intPixels1[i] - intPixels2[i]);
                        }
                }
                if (pixelsVarying > 0)
                {
                    failureDescription = String.Format(
                            "Tag (7fe0,0010) Pixel Data: {0} of {1} pixels varying, average difference: {2}",
                            pixelsVarying, pixels * pixels1.NumberOfFrames, totalVariation / pixelsVarying);
                    return false;
                }
            }
            else
            {
                for (int frame = 0; frame < pixels1.NumberOfFrames; frame++)
                {
                    byte[] pixel1 = pixels1.GetFrame(frame);
                    byte[] pixel2 = pixels2.GetFrame(frame);

                    if (pixels1.HighBit != pixels2.HighBit)
                    {
                        // Justify the pixel, if needed
                        if (DicomUncompressedPixelData.RightAlign(pixel1, pixels1.BitsAllocated, pixels1.BitsStored,
                                                              pixels1.HighBit))
                        {
                            //pixels1.HighBit = (ushort) (pixels1.BitsStored - 1);
                            DicomUncompressedPixelData.ZeroUnusedBits(pixel1, pixels1.BitsAllocated, pixels1.BitsStored,
                                                                     pixels1.BitsStored - 1);
                        }
                        if (DicomUncompressedPixelData.RightAlign(pixel2, pixels2.BitsAllocated, pixels2.BitsStored,
                                                              pixels2.HighBit))
                        {
                            //pixels2.HighBit = (ushort)(pixels2.BitsStored - 1);

                            DicomUncompressedPixelData.ZeroUnusedBits(pixel2, pixels2.BitsAllocated, pixels2.BitsStored,
                                                    pixels2.BitsStored - 1);
                        }
                    }


                    int[] intPixels1 = pixels1.IsSigned
                                           ? Convert16BitSigned(pixel1, pixels, (DicomUncompressedPixelData)pixels1)
                                           : Convert16BitUnsigned(pixel1, pixels, (DicomUncompressedPixelData)pixels1);

                    int[] intPixels2 = pixels2.IsSigned
                                           ? Convert16BitSigned(pixel2, pixels, (DicomUncompressedPixelData)pixels2)
                                           : Convert16BitUnsigned(pixel2, pixels, (DicomUncompressedPixelData)pixels2);


                    for (int i = 0; i < pixels; i++)
                        if (intPixels1[i] != intPixels2[i])
                        {
                            pixelsVarying++;
                            totalVariation += Math.Abs(intPixels1[i] - intPixels2[i]);
                        }
                }


                if (pixelsVarying > 0)
                {
                    failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: {0} of {1} pixels varying, average difference: {2}", pixelsVarying, pixels, totalVariation / pixelsVarying);
                    return false;
                }
            }

            return true;
        }
예제 #34
0
파일: PixelData.cs 프로젝트: jwake/fo-dicom
 public static IPixelData Create(DicomPixelData pixelData, int frame)
 {
     PhotometricInterpretation pi = pixelData.PhotometricInterpretation;
     if (pi == PhotometricInterpretation.Monochrome1 || pi == PhotometricInterpretation.Monochrome2 || pi == PhotometricInterpretation.PaletteColor) {
         if (pixelData.BitsStored <= 8)
             return new GrayscalePixelDataU8(pixelData.Width, pixelData.Height, pixelData.GetFrame(frame));
         else if (pixelData.BitsStored <= 16) {
             if (pixelData.PixelRepresentation == PixelRepresentation.Signed)
                 return new GrayscalePixelDataS16(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame));
             else
                 return new GrayscalePixelDataU16(pixelData.Width, pixelData.Height, pixelData.BitDepth, pixelData.GetFrame(frame));
         } else
             throw new DicomImagingException("Unsupported pixel data value for bits stored: {0}", pixelData.BitsStored);
     } else if (pi == PhotometricInterpretation.Rgb || pi == PhotometricInterpretation.YbrFull) {
         var buffer = pixelData.GetFrame(frame);
         if (pixelData.PlanarConfiguration == PlanarConfiguration.Planar)
             buffer = PixelDataConverter.PlanarToInterleaved24(buffer);
         return new ColorPixelData24(pixelData.Width, pixelData.Height, buffer);
     } else {
         throw new DicomImagingException("Unsupported pixel data photometric interpretation: {0}", pi.Value);
     }
 }
        public static bool Compare(DicomPixelData pixels1, DicomPixelData pixels2, out string failureDescription)
        {
            failureDescription = string.Empty;
            if (pixels1.BitsAllocated != pixels2.BitsAllocated)
            {
                failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Bits Allocated varies: {0} , {1}", pixels1.BitsAllocated, pixels2.BitsAllocated);
                return(false);
            }

            if (pixels1.BitsStored != pixels2.BitsStored)
            {
                failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Bits Stored varies: {0} , {1}", pixels1.BitsStored, pixels2.BitsStored);
                return(false);
            }

            if (pixels1.ImageHeight != pixels2.ImageHeight)
            {
                failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Rows varies: {0} , {1}", pixels1.ImageHeight, pixels2.ImageHeight);
                return(false);
            }

            if (pixels1.ImageWidth != pixels2.ImageWidth)
            {
                failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Columns varies: {0} , {1}", pixels1.ImageWidth, pixels2.ImageWidth);
                return(false);
            }

            if (pixels1.SamplesPerPixel != pixels2.SamplesPerPixel)
            {
                failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Samples per pixel varies: {0} , {1}", pixels1.SamplesPerPixel, pixels2.SamplesPerPixel);
                return(false);
            }

            if (pixels1.NumberOfFrames != pixels2.NumberOfFrames)
            {
                failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: Number of frames varies: {0} , {1}", pixels1.NumberOfFrames, pixels2.NumberOfFrames);
                return(false);
            }

            long pixelsVarying  = 0;
            long totalVariation = 0;

            int pixels = pixels1.ImageHeight * pixels1.ImageWidth * pixels1.SamplesPerPixel;

            if (pixels1.BitsAllocated == 8)
            {
                for (int frame = 0; frame < pixels1.NumberOfFrames; frame++)
                {
                    byte[] pixel1 = pixels1.GetFrame(frame);
                    byte[] pixel2 = pixels2.GetFrame(frame);

                    if (pixels1.HighBit != pixels2.HighBit)
                    {
                        // Justify the pixel, if needed
                        if (DicomUncompressedPixelData.RightAlign(pixel1, pixels1.BitsAllocated, pixels1.BitsStored,
                                                                  pixels1.HighBit))
                        {
                            //pixels1.HighBit = (ushort)(pixels1.BitsStored - 1);
                            DicomUncompressedPixelData.ZeroUnusedBits(pixel1, pixels1.BitsAllocated, pixels1.BitsStored,
                                                                      pixels1.BitsStored - 1);
                        }
                        if (DicomUncompressedPixelData.RightAlign(pixel2, pixels2.BitsAllocated, pixels2.BitsStored,
                                                                  pixels2.HighBit))
                        {
                            //pixels2.HighBit = (ushort)(pixels2.BitsStored - 1);
                            DicomUncompressedPixelData.ZeroUnusedBits(pixel2, pixels2.BitsAllocated, pixels2.BitsStored,
                                                                      pixels2.BitsStored - 1);
                        }
                    }

                    int[] intPixels1 = pixels1.IsSigned
                                           ? Convert8BitSigned(pixel1, pixels, (DicomUncompressedPixelData)pixels1)
                                           : Convert8BitUnsigned(pixel1, pixels, (DicomUncompressedPixelData)pixels1);

                    int[] intPixels2 = pixels2.IsSigned
                                           ? Convert8BitSigned(pixel2, pixels, (DicomUncompressedPixelData)pixels2)
                                           : Convert8BitUnsigned(pixel2, pixels, (DicomUncompressedPixelData)pixels2);


                    for (int i = 0; i < pixels; i++)
                    {
                        if (intPixels1[i] != intPixels2[i])
                        {
                            pixelsVarying++;
                            totalVariation += Math.Abs(intPixels1[i] - intPixels2[i]);
                        }
                    }
                }
                if (pixelsVarying > 0)
                {
                    failureDescription = String.Format(
                        "Tag (7fe0,0010) Pixel Data: {0} of {1} pixels varying, average difference: {2}",
                        pixelsVarying, pixels * pixels1.NumberOfFrames, totalVariation / pixelsVarying);
                    return(false);
                }
            }
            else
            {
                for (int frame = 0; frame < pixels1.NumberOfFrames; frame++)
                {
                    byte[] pixel1 = pixels1.GetFrame(frame);
                    byte[] pixel2 = pixels2.GetFrame(frame);

                    if (pixels1.HighBit != pixels2.HighBit)
                    {
                        // Justify the pixel, if needed
                        if (DicomUncompressedPixelData.RightAlign(pixel1, pixels1.BitsAllocated, pixels1.BitsStored,
                                                                  pixels1.HighBit))
                        {
                            //pixels1.HighBit = (ushort) (pixels1.BitsStored - 1);
                            DicomUncompressedPixelData.ZeroUnusedBits(pixel1, pixels1.BitsAllocated, pixels1.BitsStored,
                                                                      pixels1.BitsStored - 1);
                        }
                        if (DicomUncompressedPixelData.RightAlign(pixel2, pixels2.BitsAllocated, pixels2.BitsStored,
                                                                  pixels2.HighBit))
                        {
                            //pixels2.HighBit = (ushort)(pixels2.BitsStored - 1);

                            DicomUncompressedPixelData.ZeroUnusedBits(pixel2, pixels2.BitsAllocated, pixels2.BitsStored,
                                                                      pixels2.BitsStored - 1);
                        }
                    }


                    int[] intPixels1 = pixels1.IsSigned
                                           ? Convert16BitSigned(pixel1, pixels, (DicomUncompressedPixelData)pixels1)
                                           : Convert16BitUnsigned(pixel1, pixels, (DicomUncompressedPixelData)pixels1);

                    int[] intPixels2 = pixels2.IsSigned
                                           ? Convert16BitSigned(pixel2, pixels, (DicomUncompressedPixelData)pixels2)
                                           : Convert16BitUnsigned(pixel2, pixels, (DicomUncompressedPixelData)pixels2);


                    for (int i = 0; i < pixels; i++)
                    {
                        if (intPixels1[i] != intPixels2[i])
                        {
                            pixelsVarying++;
                            totalVariation += Math.Abs(intPixels1[i] - intPixels2[i]);
                        }
                    }
                }


                if (pixelsVarying > 0)
                {
                    failureDescription = String.Format("Tag (7fe0,0010) Pixel Data: {0} of {1} pixels varying, average difference: {2}", pixelsVarying, pixels, totalVariation / pixelsVarying);
                    return(false);
                }
            }

            return(true);
        }
예제 #36
0
        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));
                }
            }
        }