protected override byte[] CreateNormalizedPixelData() { string photometricInterpretation; byte[] pixelData = _framePixelData.GetUncompressedPixelData(out photometricInterpretation); string photometricInterpretationCode = photometricInterpretation ?? Parent[DicomTags.PhotometricInterpretation].ToString(); PhotometricInterpretation pi = PhotometricInterpretation.FromCodeString(photometricInterpretationCode); if (pi.IsColor) { pixelData = ToArgb(this.Parent, pixelData, pi); } else { var overlayPlaneModuleIod = new OverlayPlaneModuleIod(Parent); foreach (var overlayPlane in overlayPlaneModuleIod) { if (!overlayPlane.HasOverlayData && _overlayData[overlayPlane.Index] == null) { // if the overlay is embedded in pixel data and we haven't cached it yet, extract it now before we normalize the frame pixel data var overlayData = OverlayData.UnpackFromPixelData(overlayPlane.OverlayBitPosition, Parent[DicomTags.BitsAllocated].GetInt32(0, 0), false, pixelData); _overlayData[overlayPlane.Index] = overlayData; } } NormalizeGrayscalePixels(this.Parent, pixelData); } return(pixelData); }
public void TestUnpackFromPixelData_16BitsAllocated() { // 1 frame, 7x3 // 1111111 // 1001011 // 0000011 // continuous bit stream: 11111111 00101100 00011xxx xxxxxxxx const string expectedResult = "111111110010110000011"; // 16 bits allocated // some pixel data: 1st col is a random "pixel", 2nd col creates room for overlay bit, 3rd col is the overlay // 4th col moves the overlay to bit position 14, 5th col is the lower byte of the random pixel var pixelData = SwapBytes(new byte[] // written in big endian form for ease of reading :P { (0xC5 & 0x0F) | (1 << 6), 0x93, (0x2D & 0x0F) | (1 << 6), 0x9C, (0x5B & 0x0F) | (1 << 6), 0x78, (0xB3 & 0x0F) | (1 << 6), 0x17, (0xFC & 0x0F) | (1 << 6), 0x0c, (0xBC & 0x0F) | (1 << 6), 0xc4, (0x0B & 0x0F) | (1 << 6), 0x4c, (0x74 & 0x0F) | (1 << 6), 0xe5, (0x4d & 0x0F) | (0 << 6), 0x45, (0xbf & 0x0F) | (0 << 6), 0xcd, (0x86 & 0x0F) | (1 << 6), 0xAE, (0x75 & 0x0F) | (0 << 6), 0xA9, (0x51 & 0x0F) | (1 << 6), 0xbe, (0x71 & 0x0F) | (1 << 6), 0x7e, (0xA8 & 0x0F) | (0 << 6), 0x29, (0x19 & 0x0F) | (0 << 6), 0x11, (0xAC & 0x0F) | (0 << 6), 0xDD, (0xD4 & 0x0F) | (0 << 6), 0x01, (0x79 & 0x0F) | (0 << 6), 0xF0, (0xA0 & 0x0F) | (1 << 6), 0xe2, (0xBA & 0x0F) | (1 << 6), 0x98 }); // little endian { var extractedBits = OverlayData.UnpackFromPixelData(14, 16, false, pixelData); var actualResult = FormatNonZeroBytes(extractedBits); Assert.AreEqual(expectedResult, actualResult, "Error in extracted bits from pixel data (16-bit pixels, little endian)"); } // big endian { var extractedBits = OverlayData.UnpackFromPixelData(14, 16, true, SwapBytes(pixelData)); var actualResult = FormatNonZeroBytes(extractedBits); Assert.AreEqual(expectedResult, actualResult, "Error in extracted bits from pixel data (16-bit pixels, big endian)"); } }
private void ExtractOverlayFrames(byte[] rawPixelData, int bitsAllocated) { // if any overlays have embedded pixel data, extract them now or forever hold your peace var overlayPlaneModuleIod = new OverlayPlaneModuleIod(Parent); foreach (var overlayPlane in overlayPlaneModuleIod) { if (!overlayPlane.HasOverlayData && _overlayCache[overlayPlane.Index] == null) { // if the overlay is embedded in pixel data and we haven't cached it yet, extract it now before we normalize the frame pixel data var overlayData = OverlayData.UnpackFromPixelData(overlayPlane.OverlayBitPosition, bitsAllocated, false, rawPixelData); _overlayCache[overlayPlane.Index] = overlayData; } } }
protected override byte[] CreateNormalizedPixelData() { byte[] pixelData = _framePixelData.GetUncompressedPixelData(); string photometricInterpretationCode = this.Parent[DicomTags.PhotometricInterpretation].ToString(); PhotometricInterpretation pi = PhotometricInterpretation.FromCodeString(photometricInterpretationCode); TransferSyntax ts = TransferSyntax.GetTransferSyntax(this.Parent.TransferSyntaxUid); if (pi.IsColor) { if (ts == TransferSyntax.Jpeg2000ImageCompression || ts == TransferSyntax.Jpeg2000ImageCompressionLosslessOnly || ts == TransferSyntax.JpegExtendedProcess24 || ts == TransferSyntax.JpegBaselineProcess1) { pi = PhotometricInterpretation.Rgb; } pixelData = ToArgb(this.Parent, pixelData, pi); } else { OverlayPlaneModuleIod opmi = new OverlayPlaneModuleIod(this.Parent); foreach (OverlayPlane overlayPlane in opmi) { if (IsOverlayEmbedded(overlayPlane) && _overlayData[overlayPlane.Index] == null) { byte[] overlayData = OverlayData.UnpackFromPixelData(overlayPlane.OverlayBitPosition, this.Parent[DicomTags.BitsAllocated].GetInt32(0, 0), false, pixelData); _overlayData[overlayPlane.Index] = overlayData; } else if (!overlayPlane.HasOverlayData) { Platform.Log(LogLevel.Warn, "The image {0} appears to be missing OverlayData for group 0x{1:X4}.", this.Parent.SopInstanceUid, overlayPlane.Group); } } NormalizeGrayscalePixels(this.Parent, pixelData); } return(pixelData); }
protected override byte[] CreateNormalizedPixelData() { byte[] pixelData = _framePixelData.GetUncompressedPixelData(); string photometricInterpretationCode = this.Parent[DicomTags.PhotometricInterpretation].ToString(); PhotometricInterpretation pi = PhotometricInterpretation.FromCodeString(photometricInterpretationCode); TransferSyntax ts = TransferSyntax.GetTransferSyntax(this.Parent.TransferSyntaxUid); if (pi.IsColor) { if (ts == TransferSyntax.Jpeg2000ImageCompression || ts == TransferSyntax.Jpeg2000ImageCompressionLosslessOnly || ts == TransferSyntax.JpegExtendedProcess24 || ts == TransferSyntax.JpegBaselineProcess1) { pi = PhotometricInterpretation.Rgb; } pixelData = ToArgb(this.Parent, pixelData, pi); } else { var overlayPlaneModuleIod = new OverlayPlaneModuleIod(Parent); foreach (var overlayPlane in overlayPlaneModuleIod) { if (!overlayPlane.HasOverlayData && _overlayData[overlayPlane.Index] == null) { // if the overlay is embedded in pixel data and we haven't cached it yet, extract it now before we normalize the frame pixel data var overlayData = OverlayData.UnpackFromPixelData(overlayPlane.OverlayBitPosition, Parent[DicomTags.BitsAllocated].GetInt32(0, 0), false, pixelData); _overlayData[overlayPlane.Index] = overlayData; } } NormalizeGrayscalePixels(this.Parent, pixelData); } return(pixelData); }
public void TestUnpackFromPixelData_8BitsAllocated() { // 1 frame, 5x3 // 11111 // 10010 // 00000 // continuous bit stream: 11111100 1000000x // continuous LE byte stream: 00111111 x0000001 const string expectedResult = "111111001000000"; // 8 bits allocated // some pixel data: 1st col is a random "pixel", 2nd col creates room for overlay bit, 3rd col is the overlay var pixelData = new byte[] { (0xC5 & 0xFE) | 1, (0x2D & 0xFE) | 1, (0x5B & 0xFE) | 1, (0xB3 & 0xFE) | 1, (0xFC & 0xFE) | 1, (0xBC & 0xFE) | 1, (0x4d & 0xFE) | 0, (0xbf & 0xFE) | 0, (0x86 & 0xFE) | 1, (0x75 & 0xFE) | 0, (0xA8 & 0xFE) | 0, (0x19 & 0xFE) | 0, (0xAC & 0xFE) | 0, (0xD4 & 0xFE) | 0, (0x79 & 0xFE) | 0 }; var extractedBits = OverlayData.UnpackFromPixelData(0, 8, false, pixelData); var actualResult = FormatNonZeroBytes(extractedBits); Assert.AreEqual(expectedResult, actualResult, "Error in extracted bits from pixel data (8-bit pixels)"); }