예제 #1
0
        public void SetBitmap()
        {
            if (_bitmap == null)
            {
                _bitmap = CTSliceHelpers.GetPixelBufferAsBitmap(_ct);
                _bitmap.Freeze();

                _imageBrush             = new ImageBrush();
                _imageBrush.ImageSource = _bitmap;

                _ModelGroup = new Model3DGroup();
                _ModelGroup.Children.Add(new GeometryModel3D(Tessellate(), new DiffuseMaterial(_imageBrush)));
                this.Content = _ModelGroup;

                _3DModel.Children.Add(this);
            }
        }
예제 #2
0
        private void ButtonLungs_Click(object sender, RoutedEventArgs e)
        {
            bool rc = _scol.BuildSortedSlicesArray();

            if (!rc)
            {
                System.Windows.MessageBox.Show("There are skips in CTs!");
                return;
            }

            CTSliceInfo[] slices = _scol.Slices;

            // Step 1: find the couch
            int sr = SelectStartSlice(slices);

            CTSliceInfo ct = slices[sr];

            int sc       = Couch.DetectCouchInOneSlice(ct.HounsfieldPixelBuffer, ct.RowCount, ct.ColumnCount);
            int scBefore = Couch.DetectCouchInOneSlice(slices[sr + 10].HounsfieldPixelBuffer, slices[sr + 10].RowCount, slices[sr + 10].ColumnCount);
            int scAfter  = Couch.DetectCouchInOneSlice(slices[sr - 10].HounsfieldPixelBuffer, slices[sr - 10].RowCount, slices[sr - 10].ColumnCount);

            sc = Math.Max(Math.Max(sc, scBefore), scAfter);

            // Step 2: Gaussian blur

            GaussBlur gb = new GaussBlur((float)ct.PixelSpacing_X, (float)ct.PixelSpacing_X, 5);

            for (int k = 0; k != slices.Length; ++k)
            {
                ct          = slices[k];
                short[,] bm = CTSliceHelpers.Apply(ct, gb);
                ct.HounsfieldPixelBuffer = bm;
            }

            // Step 3: clear below the couch
            for (int k = 0; k != slices.Length; ++k)
            {
                ct = slices[k];

                short[,] hb = ct.HounsfieldPixelBuffer;

                for (int r = ct.RowCount - 1; r > sc; --r)
                {
                    for (int c = 0; c != ct.ColumnCount; ++c)
                    {
                        hb[r, c] = -1024;
                    }
                }
            }

            // Step 4: gray level thresholding
            for (int k = 0; k != slices.Length; ++k)
            {
                ct = slices[k];

                Couch.GLThresholding(ct, sc, -499, 0, -499);
            }

            // Step 5: Flool fill
            for (int k = 0; k != slices.Length; ++k)
            {
                ct = slices[k];

                short[,] ret = Couch.FloodFill(ct.HounsfieldPixelBuffer, ct.RowCount, ct.ColumnCount,
                                               3, 3, -499, 0);
                ct.HounsfieldPixelBuffer = ret;
            }

            // Step 6: Contours via Moore Neighbour
            for (int k = slices.Length - 1; k >= slices.Length - 2; --k)
            {
                ct = slices[k];
                int nr = ct.RowCount;
                int nc = ct.ColumnCount;

                int    z  = ct.SliceLoc;
                double zz = ct.UpperLeft_Z;

                short[,] bm = ct.HounsfieldPixelBuffer;

                bool[,] image = new bool[nr, nc];

                for (int r = 0; r != nr; ++r)
                {
                    for (int c = 0; c != nc; ++c)
                    {
                        image[r, c] = false;
                        if (bm[r, c] < 0)
                        {
                            image[r, c] = true;
                        }
                    }
                }

                System.Drawing.Point[] contour = MooreContour.Trace(image, nr, nc);


                foreach (var pt in contour)
                {
                    int r = pt.Y;
                    int c = pt.X;

                    bm[r, c] = 500;
                }
            }
        }
예제 #3
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;
            }
        }