Ejemplo n.º 1
0
        public static WriteableBitmap BuildColorBitmap(CTSliceInfo ct,
                                                       byte[,]     normalizedPixelBuffer)
        {
            byte[] imageDataArray = new byte[ct.RowCount * ct.ColumnCount * 4];

            int i = 0;

            for (int r = 0; r != ct.RowCount; ++r)
            {
                for (int c = 0; c != ct.ColumnCount; ++c)
                {
                    byte aGrayValue = normalizedPixelBuffer[r, c];

                    // Black/White image: all RGB values are set to same value
                    // Alpha value is set to 255
                    imageDataArray[i * 4]     = aGrayValue;
                    imageDataArray[i * 4 + 1] = aGrayValue;
                    imageDataArray[i * 4 + 2] = aGrayValue;
                    imageDataArray[i * 4 + 3] = 255;

                    ++i;
                }
            }

            // Allocate the Bitmap
            WriteableBitmap bitmap = new WriteableBitmap(ct.ColumnCount, ct.RowCount, 96, 96, PixelFormats.Pbgra32, null);

            // Write the Pixels
            Int32Rect imageRectangle = new Int32Rect(0, 0, ct.ColumnCount, ct.RowCount);
            int       imageStride    = ct.ColumnCount * bitmap.Format.BitsPerPixel / 8;

            bitmap.WritePixels(imageRectangle, imageDataArray, imageStride, 0);

            return(bitmap);
        }
Ejemplo n.º 2
0
        public static WriteableBitmap BuildGrey8Bitmap(CTSliceInfo ct,
                                                       byte[,]     normalizedPixelBuffer)
        {
            byte[] imageDataArray = new byte[ct.RowCount * ct.ColumnCount * 1];

            int i = 0;

            for (int r = 0; r != ct.RowCount; ++r)
            {
                for (int c = 0; c != ct.ColumnCount; ++c)
                {
                    byte grayValue = normalizedPixelBuffer[r, c];

                    imageDataArray[i] = grayValue;

                    ++i;
                }
            }

            // Allocate the Bitmap
            WriteableBitmap bitmap = new WriteableBitmap(ct.ColumnCount, ct.RowCount, 96, 96, PixelFormats.Gray8, null);

            // Write the Pixels
            Int32Rect imageRectangle = new Int32Rect(0, 0, ct.ColumnCount, ct.RowCount);
            int       imageStride    = ct.ColumnCount * bitmap.Format.BitsPerPixel / 8;

            bitmap.WritePixels(imageRectangle, imageDataArray, imageStride, 0);

            return(bitmap);
        }
Ejemplo n.º 3
0
        // build bitmap directly from Hounsfield map, shifted by 1024
        public static WriteableBitmap BuildGrey16Bitmap(CTSliceInfo ct,
                                                        byte[,]     normalizedPixelBuffer)
        {
            byte[] imageDataArray = new byte[ct.RowCount * ct.ColumnCount * 2];

            int i = 0;

            for (int r = 0; r != ct.RowCount; ++r)
            {
                for (int c = 0; c != ct.ColumnCount; ++c)
                {
                    ushort grayValue = (ushort)(ct[r, c] + 1024);

                    imageDataArray[i * 2 + 0] = (byte)((grayValue >> 8) & 0x00FF);
                    imageDataArray[i * 2 + 1] = (byte)(grayValue & 0x00FF);

                    ++i;
                }
            }

            // Allocate the Bitmap
            WriteableBitmap bitmap = new WriteableBitmap(ct.ColumnCount, ct.RowCount, 96, 96, PixelFormats.Gray16, null);

            // Write the Pixels
            Int32Rect imageRectangle = new Int32Rect(0, 0, ct.ColumnCount, ct.RowCount);
            int       imageStride    = ct.ColumnCount * bitmap.Format.BitsPerPixel / 8;

            bitmap.WritePixels(imageRectangle, imageDataArray, imageStride, 0);

            return(bitmap);
        }
Ejemplo n.º 4
0
        public static byte[,] BuildNormalizedPixelBuffer(CTSliceInfo ct,
                                                         int windowCenter,
                                                         int windowWidth,
                                                         int windowLeftBorder)
        {
            Debug.Assert(windowWidth > 0);

            byte[,] normalizedPixelBuffer = new byte[ct.RowCount, ct.ColumnCount];

            // Normalize the Pixel value to [0,255]
            for (int r = 0; r != ct.RowCount; ++r)
            {
                for (int c = 0; c != ct.ColumnCount; ++c)
                {
                    short aPixelValue           = ct[r, c];
                    int   aPixelValueNormalized = (255 * (aPixelValue - windowLeftBorder)) / windowWidth;

                    if (aPixelValueNormalized <= 0)
                    {
                        normalizedPixelBuffer[r, c] = 0;
                    }
                    else
                    if (aPixelValueNormalized >= 255)
                    {
                        normalizedPixelBuffer[r, c] = 255;
                    }
                    else
                    {
                        normalizedPixelBuffer[r, c] = Convert.ToByte(aPixelValueNormalized);
                    }
                }
            }
            return(normalizedPixelBuffer);
        }
Ejemplo n.º 5
0
        // true if value is replaced
        public bool Add(CTSliceInfo ct)
        {
            string fname    = ct.FileName;
            int    sliceloc = ct.SliceLoc;

            bool rc = _slices_by_locn.ContainsKey(sliceloc);

            _slices_by_name[fname]    = ct;
            _slices_by_locn[sliceloc] = ct;

            return(true);
        }
Ejemplo n.º 6
0
        public CTSliceInfo Clone()
        {
            CTSliceInfo ct = new CTSliceInfo(this);

            if (_HounsfieldPixelBuffer != null)
            {
                // make deep copy
                ct._HounsfieldPixelBuffer = new short[_RowCount, _ColumnCount];
                Buffer.BlockCopy(_HounsfieldPixelBuffer, 0, ct._HounsfieldPixelBuffer, 0, _HounsfieldPixelBuffer.Length);
            }

            return(ct);
        }
Ejemplo n.º 7
0
        // Helper method, which returns the pixel data of a CT slice as gray-scale bitmap.
        public static WriteableBitmap GetPixelBufferAsBitmap(CTSliceInfo ct)
        {
            int windowLeftBorder = ct.WindowCenter - (ct.WindowWidth / 2);

            /*
             * GaussBlur gb = new GaussBlur(1.0f, (float)ct.PixelSpacing_X, 5);
             *
             * short[,] bm = Apply(ct, gb);
             *
             * ct.HounsfieldPixelBuffer = bm;
             */

            byte[,] normalizedPixelBuffer = BuildNormalizedPixelBuffer(ct, ct.WindowCenter, ct.WindowWidth, windowLeftBorder);

            WriteableBitmap bitmap = BuildGrey16Bitmap(ct, normalizedPixelBuffer);

            return(bitmap);
        }
Ejemplo n.º 8
0
 // build slice list for a given patient
 private void ProcessAllCTs(string aPatientName, IODRepository mIODRepository)
 {
     foreach (string SOPClass in mIODRepository.GetSOPClassNames(aPatientName))
     {
         foreach (string Study in mIODRepository.GetStudies(aPatientName, SOPClass))
         {
             foreach (string Series in mIODRepository.GetSeries(aPatientName, SOPClass, Study))
             {
                 foreach (IOD IOD in mIODRepository.GetIODs(aPatientName, SOPClass, Study, Series))
                 {
                     if (IOD.IsPixelDataProcessable())
                     {
                         CTSliceInfo aCTSliceInfo = new Helper.CTSliceInfo(IOD.XDocument, IOD.FileName);
                         _scol.Add(aCTSliceInfo);
                     }
                 }
             }
         }
     }
 }
Ejemplo n.º 9
0
        public static short[,] Apply(CTSliceInfo ct, GaussBlur gb)
        {
            short[,] hmap = ct.HounsfieldPixelBuffer;

            int nr = ct.RowCount;
            int nc = ct.ColumnCount;

            int br = gb.br;
            int bc = gb.bc;

            float[,] blur = gb.blur;

            short[,] bm = new short[nr, nc];
            int l = bm.Length;

            Array.Clear(bm, 0, bm.Length);

            for (int r = br; r != nr - br; ++r)
            {
                for (int c = bc; c != nc - bc; ++c)
                {
                    float s = 0.0f;

                    for (int ir = -br; ir <= br; ++ir)
                    {
                        int sr = r + ir;
                        for (int ic = -bc; ic <= bc; ++ic)
                        {
                            int sc = c + ic;

                            s += (float)hmap[sr, sc] * blur[ir + br, ic + bc];
                        }
                    }

                    bm[r, c] = (short)(s + 0.5f);
                }
            }

            return(bm);
        }
Ejemplo n.º 10
0
        public CTSliceInfo(CTSliceInfo ct)
        {
            _XDocument = ct._XDocument;
            _FileName  = ct._FileName;

            _ColumnCount = ct._ColumnCount;
            _RowCount    = ct._RowCount;
            _SliceLoc    = ct._SliceLoc;

            _UpperLeft_X = ct._UpperLeft_X;
            _UpperLeft_Y = ct._UpperLeft_Y;
            _UpperLeft_Z = ct._UpperLeft_Z;

            _PixelSpacing_X = ct._PixelSpacing_X;
            _PixelSpacing_Y = ct._PixelSpacing_Y;

            _windowCenter = ct._windowCenter;
            _windowWidth  = ct._windowWidth;

            // no deep copy
            _HounsfieldPixelBuffer = ct._HounsfieldPixelBuffer;
        }
Ejemplo n.º 11
0
        // Helper method to handle the selection change event of the IOD Tree.
        // a) In case the selected tree node represents only group information (Patient, SOPClass, Study, Series), the detailed view is cleared.
        // b) In case the selected tree node represents an IOD, the DICOM Metainformation is displayed in the DICOM Tag Tree.
        // c) In case the selected tree node represents a CT Slice, in addition to the DICOM Metainformation,
        //    the ImageFlow button, the volume buttons and the bitmap is shown.
        private void mIODTree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs <object> e)
        {
            TreeViewItem aSelectedNode = _IODTree.SelectedItem as TreeViewItem;

            if (aSelectedNode == null)
            {
                return;
            }

            // Clear old content
            _DICOMTagTree.Items.Clear();
            _Grid.RowDefinitions.First().Height = new GridLength(0);
            _Grid.RowDefinitions.Last().Height  = new GridLength(0);

            IOD anIOD = aSelectedNode.Tag as IOD;

            if (anIOD == null)
            {
                return;
            }

            // Set the FileName as root node

            string aFileName = Path.GetFileName(anIOD.FileName);

            TreeViewItem rootNode = new TreeViewItem()
            {
                Header = string.Format("File: {0}", aFileName)
            };

            _DICOMTagTree.Items.Add(rootNode);

            // Expand the root node
            rootNode.IsExpanded = true;

            // Add all DICOM attributes to the tree
            foreach (XElement xe in anIOD.XDocument.Descendants("DataSet").First().Elements("DataElement"))
            {
                AddDICOMAttributeToTree(rootNode, xe);
            }

            // In case the IOD does have a processable pixel data, the ImageFlow button, the volume buttons and the bitmap is shown.
            // Otherwise, only the DICOM attributes are shown and the first and last grid row is hided.
            if (anIOD.IsPixelDataProcessable())
            {
                CTSliceInfo ct = _scol.Retrieve(anIOD.FileName);
                if (ct == null)
                {
                    ct = new Helper.CTSliceInfo(anIOD.XDocument, anIOD.FileName);
                    _scol.Add(ct);
                }
                _Grid.RowDefinitions.First().Height = new GridLength(30);
                _Grid.RowDefinitions.Last().Height  = new GridLength(ct.RowCount + 16);

                _Image.Source = CTSliceHelpers.GetPixelBufferAsBitmap(ct);
                _curCT        = ct;
            }
            else
            {
                _Grid.RowDefinitions.First().Height = new GridLength(0);
                _Grid.RowDefinitions.Last().Height  = new GridLength(0);

                _curCT = null;
            }
        }