Beispiel #1
0
 private void toolStripMenuItem2_Click(object sender, EventArgs e)
 {
     try
     {
         if (imgInput == null)
         {
             MessageBox.Show("please select an image.");
             return;
         }
         var img  = new Bitmap(pictureBox1.Image).ToImage <Bgr, byte>();
         var mask = img.Convert <Gray, byte>().ThresholdBinaryInv(new Gray(150), new Gray(255));
         Mat distanceTransform = new Mat();
         CvInvoke.DistanceTransform(mask, distanceTransform, null, Emgu.CV.CvEnum.DistType.L2, 3);
         CvInvoke.Normalize(distanceTransform, distanceTransform, 0, 255, Emgu.CV.CvEnum.NormType.MinMax);
         var markers = distanceTransform.ToImage <Gray, byte>().ThresholdBinary(new Gray(50), new Gray(255));
         CvInvoke.ConnectedComponents(markers, markers);
         var finalmarkers = markers.Convert <Gray, Int32>();
         CvInvoke.Watershed(img, finalmarkers);
         Image <Gray, byte> boundaaries = finalmarkers.Convert <byte>(delegate(Int32 x)
         {
             return((byte)(x == -1 ? 255 : 0));
         });
         boundaaries._Dilate(1);
         img.SetValue(new Bgr(0, 255, 0), boundaaries);
         // AddImage(img, "");
         pictureBox2.Image    = img.ToBitmap();
         pictureBox2.SizeMode = PictureBoxSizeMode.StretchImage;
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.Message);
     }
 }
        private void processToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (imageInput == null)
            {
                return;
            }

            try
            {
                //  Convert img to grayscale -> convert img to binary using max threshold of 100
                //  (if value is more than 100, set it to the max value [255]) -> close effects
                //  using dilation then erosion
                var temp = imageInput.Convert <Gray, byte>().ThresholdBinary(new Gray(100), new Gray(255))
                           .Dilate(1).Erode(1);

                // Matrix to store the labels from the image
                Mat labels = new Mat();

                // Find the number of connected components
                int nLabels = CvInvoke.ConnectedComponents(temp, labels);

                //  Konvesi labels menjadi sebuah image
                connectedComponents = labels.ToImage <Gray, byte>();

                // connectedComponents can not be shown because it is a value between 1 - 0
                rightPictureBox.Image = temp.Bitmap;
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
            }
        }
Beispiel #3
0
        private void processToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (imgInput == null)
            {
                return;
            }

            try
            {
                var temp = imgInput.Convert <Gray, byte>().ThresholdBinary(new Gray(100), new Gray(255))
                           .Dilate(1).Erode(1);
                Mat labels  = new Mat();
                int nLabels = CvInvoke.ConnectedComponents(temp, labels);
                CC = labels.ToImage <Gray, byte>();
                pictureBox2.Image = temp.Bitmap;
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message);
            }
        }
Beispiel #4
0
        private void processToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (imgInput == null)
            {
                return;
            }

            try
            {
                var tempImg = imgInput.Convert <Gray, byte>().ThresholdBinary(new Gray(65), new Gray(255)).Dilate(1).Erode(1);

                Mat mLabel  = new Mat();
                int nLabels = CvInvoke.ConnectedComponents(tempImg, mLabel);
                cc = mLabel.ToImage <Gray, byte>();

                pictureBox2.Image = tempImg.ToBitmap();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        static void Main(string[] args)
        {
            // Read image
            Mat img = CvInvoke.Imread(@"C:\EMT\Image\EMT_Lab2\ConnectImage3.png", ImreadModes.Grayscale);

            // Create window and show image
            CvInvoke.NamedWindow("Original", NamedWindowType.KeepRatio);
            CvInvoke.Imshow("Original", img);

            // Create new cv image same size as img
            Mat imglabel = new Mat(img.Rows, img.Cols, DepthType.Cv16U, 1);

            // Count number of connected components
            int label = CvInvoke.ConnectedComponents(img, imglabel, LineType.FourConnected, DepthType.Cv16U);

            // Create new cv image with unsigned 8 bit
            Mat imglabelscale = new Mat(img.Rows, img.Cols, DepthType.Cv8U, 1);

            // Find max and min values in cv image array
            CvInvoke.MinMaxIdx(imglabel, out double minVal, out double maxVal, null, null);

            // Scale image to follow min and max
            CvInvoke.ConvertScaleAbs(imglabel, imglabelscale, 255 / (maxVal - minVal), 0);

            // Write image to path as png
            CvInvoke.Imwrite(@"C:\EMT\Image\EMT_Lab2\Results1.png", imglabelscale);


            String imgtitle = "Connected Objects = " + Convert.ToString(label - 1);

            CvInvoke.NamedWindow(imgtitle, NamedWindowType.KeepRatio);
            CvInvoke.Imshow(imgtitle, imglabelscale);

            CvInvoke.WaitKey(0);
            CvInvoke.DestroyAllWindows();
        }
        private Bitmap Processar(string Caminho, string NomeImagem)
        {
            if (pictureBox1.Image == null)
            {
                return(null);
            }
            CelulasMicronucleadas = 0;
            CelulasCariolise      = 0;
            CelulasBinucleadas    = 0;
            CelulasNormais        = 0;
            CelulasIgnoradas      = 0;
            CelulasTotais         = 0;
            Background            = 0;
            int PosicaoThresh2 = 0;
            int PosicaoNucleo2 = 0;

            SimpleBlobDetector param    = new SimpleBlobDetector();
            VectorOfKeyPoint   keypoint = new VectorOfKeyPoint();

            Camera       = new Image <Hsv, Byte>(Caminho);
            CameraResult = new Image <Rgb, Byte>(Caminho);

            Image <Gray, Byte> ImageSave  = new Image <Gray, Byte>(Camera.Cols, Camera.Rows);
            Image <Rgb, Byte>  ImageSave2 = new Image <Rgb, Byte>(Camera.Cols, Camera.Rows);

            Image <Gray, Byte> Cellthresh        = new Image <Gray, Byte>(Camera.Cols, Camera.Rows);
            Image <Gray, Byte> ThreshSet         = new Image <Gray, Byte>(Camera.Cols, Camera.Rows);
            Image <Gray, Byte> ThreshSet2        = new Image <Gray, Byte>(Camera.Cols, Camera.Rows);
            Image <Rgb, Byte>  separateCellRGB   = new Image <Rgb, Byte>(Camera.Cols, Camera.Rows);
            Image <Hsv, Byte>  separateCell      = new Image <Hsv, Byte>(Camera.Cols, Camera.Rows);
            Image <Hsv, Byte>  separateNuclei    = new Image <Hsv, Byte>(Camera.Cols, Camera.Rows);
            Image <Gray, Byte> MaskContourNuclei = new Image <Gray, Byte>(Camera.Cols, Camera.Rows);
            Image <Gray, Byte> MaskContourCell   = new Image <Gray, Byte>(Camera.Cols, Camera.Rows);
            Image <Hsv, Byte>  maskCell          = new Image <Hsv, Byte>(Camera.Cols, Camera.Rows);
            Image <Gray, Byte> ContourCompare    = new Image <Gray, Byte>(Camera.Cols, Camera.Rows);
            Image <Gray, Byte> Cellthresh2       = new Image <Gray, Byte>(Camera.Cols, Camera.Rows);
            Image <Hsv, Byte>  nothing           = new Image <Hsv, Byte>(Camera.Cols, Camera.Rows);

            Mat           EllipseKernel = new Mat();
            Matrix <byte> kernel1       = new Matrix <byte>(new Byte[3, 3] {
                { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 }
            });
            var mask = Camera[0];

            //ImageSave = mask;
            //ImageSave.Save("met_hsv.png");
            EllipseKernel = CvInvoke.GetStructuringElement(ElementShape.Ellipse, new Size(5, 5), new Point(-1, -1));
            CvInvoke.MorphologyEx(mask, mask, MorphOp.Open, EllipseKernel, new Point(-1, -1), 1, BorderType.Default, new MCvScalar());
            CvInvoke.MorphologyEx(mask, mask, MorphOp.Close, EllipseKernel, new Point(-1, -1), 1, BorderType.Default, new MCvScalar());
            //ImageSave = mask;
            //ImageSave.Save("met_openclose.png");
            CvInvoke.Threshold(mask, mask, 50, 255, ThresholdType.Otsu);
            //ImageSave = mask;
            //ImageSave.Save("met_otsu.png");
            Mat distanceTransform = new Mat();

            CvInvoke.DistanceTransform(mask, distanceTransform, null, Emgu.CV.CvEnum.DistType.L2, 5);
            CvInvoke.Normalize(distanceTransform, distanceTransform, 0, 255, NormType.MinMax);
            var markers = distanceTransform.ToImage <Gray, byte>();

            //ImageSave = markers;
            //ImageSave.Save("met_distancetransform.png");
            markers = markers.ThresholdBinary(new Gray(100), new Gray(255));
            CvInvoke.ConnectedComponents(markers, markers);
            var finalMarkers = markers.Convert <Gray, Int32>();

            CvInvoke.Watershed(Camera, finalMarkers);
            Image <Gray, byte> boundaries = finalMarkers.Convert <byte>(delegate(Int32 x)
            {
                return((byte)(x == -1 ? 255 : 0));
            });

            boundaries._Dilate(1);
            //ImageSave = boundaries;
            //ImageSave.Save("met_watershed.png");
            CvInvoke.Threshold(boundaries, boundaries, 0, 255, ThresholdType.BinaryInv);
            Image <Gray, Byte> CellsBoundaries = new Image <Gray, Byte>(Camera.Cols, Camera.Rows);

            CellsBoundaries.SetZero();
            CellsBoundaries = boundaries & mask;
            //ImageSave = CellsBoundaries;
            //ImageSave.Save("met_segmentado.png");

            ////////////////////////////////////////
            // aqui cria o contorno do watershed e separa o nucleo de cada celula encontrada
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            Mat hierarchy = new Mat();

            CvInvoke.FindContours(CellsBoundaries, contours, hierarchy, RetrType.External, ChainApproxMethod.ChainApproxNone);
            for (int i = 0; i < contours.Size; i++)
            {
                maskCell.SetZero();
                separateCell.SetZero();
                separateCellRGB.SetZero();
                separateNuclei.SetZero();
                MaskContourNuclei.SetZero();
                MaskContourCell.SetZero();
                nothing.SetZero();
                double area      = CvInvoke.ContourArea(contours[i]);
                double perimeter = CvInvoke.ArcLength(contours[i], true);
                //cria a mascara para separar cada célula e seus núcleos
                //caso o contorno for a area total da foto, ignora
                if (area < 400)
                {
                    Background += 1;
                    continue;
                }
                //se a celula for muito grande é uma célula a ser ignorada
                else if (area > 4000 || area < 1000 || perimeter > 250 || perimeter < 100)
                {
                    CvInvoke.DrawContours(CameraResult, contours, i, new MCvScalar(255, 255, 255));
                    CelulasIgnoradas += 1;
                    continue;
                }
                //se tudo estiver correto, realiza a análise do núcleo da célula
                else
                {
                    CvInvoke.DrawContours(maskCell, contours, i, new MCvScalar(255, 255, 255), -1);
                    separateCell = Camera & maskCell;
                    ImageSave    = separateCell[0].Convert <Gray, Byte>();
                    ImageSave.Save("met_mascaracelula.png");
                    var    teste2         = separateCell.Convert <Gray, Byte>();
                    Double intensity      = 0.0;
                    double pixelintensity = 0;
                    for (int cols = 0; cols < teste2.Cols; cols++)
                    {
                        for (int rows = 0; rows < teste2.Rows; rows++)
                        {
                            intensity += teste2.Data[rows, cols, 0];
                            if (teste2.Data[rows, cols, 0] > 0)
                            {
                                pixelintensity++;
                            }
                        }
                    }
                    intensity = intensity / pixelintensity;
                    // verifica a intensidade de pixels na celula
                    if (intensity < 40)
                    {
                        CvInvoke.DrawContours(CameraResult, contours, i, new MCvScalar(255, 0, 255));
                        CelulasCariolise++;
                        break;
                    }
                    else if (intensity < 55)
                    {
                        thresh = 120;
                    }
                    else
                    {
                        thresh = 110;
                    }

                    int    AchouNucleo                 = 0;
                    int    PosicaoThresh               = 0;
                    int    PosicaoNucleo               = 0;
                    int    Nucleos                     = 0;
                    int    Micronucleada               = 0;
                    int    Binucleada                  = 0;
                    int    Normal                      = 0;
                    double AreaNucleo1                 = 0;
                    double AreaNucleo2                 = 0;
                    int    OutroNucleo                 = 0;
                    double AreaOutroNucleo             = 0;
                    int    PosicaoOutroNucleo          = 0;
                    VectorOfVectorOfPoint Nucleithresh = new VectorOfVectorOfPoint();
                    for (int k = thresh; k > 95; k--)
                    {
                        Mat NucleihierarchyThresh = new Mat();
                        Mat MorphStructuring      = new Mat();
                        Cellthresh       = separateCell[0];
                        MorphStructuring = CvInvoke.GetStructuringElement(ElementShape.Ellipse, new Size(5, 5), new Point(-1, -1));
                        CvInvoke.Threshold(Cellthresh, Cellthresh, k, 255, ThresholdType.Binary);
                        CvInvoke.MorphologyEx(Cellthresh, Cellthresh, MorphOp.Dilate, MorphStructuring, new Point(-1, -1), 1, BorderType.Default, new MCvScalar());
                        CvInvoke.FindContours(Cellthresh, Nucleithresh, NucleihierarchyThresh, RetrType.Tree, ChainApproxMethod.ChainApproxSimple);
                        Nucleos     = 0;
                        AchouNucleo = 0;
                        AreaNucleo1 = 0;
                        AreaNucleo2 = 0;
                        OutroNucleo = 0;
                        if (Nucleithresh.Size > 0 && Nucleithresh.Size < 3)
                        {
                            for (int j = 0; j < Nucleithresh.Size; j++)
                            {
                                ContourCompare.SetZero();
                                MaskContourCell.SetZero();
                                MaskContourNuclei.SetZero();
                                double AreaNucleiThresh      = CvInvoke.ContourArea(Nucleithresh[j]);
                                double PerimeterNucleiThresh = CvInvoke.ArcLength(Nucleithresh[j], true);
                                CvInvoke.DrawContours(MaskContourCell, contours, i, new MCvScalar(255, 255, 255));
                                CvInvoke.DrawContours(MaskContourNuclei, Nucleithresh, j, new MCvScalar(255, 255, 255));
                                ContourCompare = MaskContourCell & MaskContourNuclei;
                                int pixel = 0;
                                for (int cols = 0; cols < ContourCompare.Cols; cols++)
                                {
                                    for (int rows = 0; rows < ContourCompare.Rows; rows++)
                                    {
                                        pixel += ContourCompare.Data[rows, cols, 0];
                                    }
                                }

                                if (AreaNucleiThresh > 100 || pixel > 0)
                                {
                                    break;
                                }

                                if (AreaNucleiThresh < 100 && AreaNucleiThresh > 25 && pixel == 0 && AchouNucleo == 0 && PerimeterNucleiThresh < 31)
                                {
                                    AchouNucleo   = 1;
                                    PosicaoThresh = k;
                                    PosicaoNucleo = j;
                                    ThreshSet     = Cellthresh;
                                    AreaNucleo1   = AreaNucleiThresh;
                                }
                                if (AreaNucleiThresh < 25 && pixel == 0 && AchouNucleo == 0 && OutroNucleo == 0)
                                {
                                    OutroNucleo        = 1;
                                    AreaOutroNucleo    = AreaNucleiThresh;
                                    PosicaoOutroNucleo = j;
                                }

                                if (AchouNucleo == 1 && OutroNucleo == 1 && pixel == 0)
                                {
                                    Nucleos++;
                                    if (Math.Abs(AreaNucleo1 - AreaOutroNucleo) > 20)
                                    {
                                        Micronucleada = 1;
                                    }
                                    else
                                    {
                                        Binucleada = 1;
                                    }
                                    continue;
                                }

                                if ((AchouNucleo == 1 && OutroNucleo == 0 && pixel == 0))
                                {
                                    Nucleos++;
                                    AreaNucleo2 = AreaNucleiThresh;
                                    if (Nucleos > 1)
                                    {
                                        if (Math.Abs(AreaNucleo1 - AreaNucleo2) > 20)
                                        {
                                            Micronucleada = 1;
                                        }
                                        else
                                        {
                                            Binucleada = 1;
                                        }
                                        continue;
                                    }
                                    else if (Nucleos == 1)
                                    {
                                        Normal = 1;
                                    }
                                }
                            }
                        }
                        if (AchouNucleo == 1)
                        {
                            break;
                        }
                    }

                    // CONTABILIZA E PINTA A CÉLULA
                    if (AchouNucleo == 1)
                    {
                        int check = 0;
                        for (int j = 0; j < Nucleithresh.Size; j++)
                        {
                            if (Nucleos == 2 && Binucleada == 1)
                            {
                                if (check == 0) // conta somente uma vez!
                                {
                                    check = 1;
                                    CelulasBinucleadas++;
                                }
                                CvInvoke.DrawContours(CameraResult, Nucleithresh, j, new MCvScalar(255, 0, 0));
                                CvInvoke.DrawContours(CameraResult, contours, i, new MCvScalar(255, 0, 0));
                            }
                            else if (Nucleos == 2 && Micronucleada == 1)
                            {
                                if (check == 0) //checa somente uma vez!
                                {
                                    check = 1;
                                    CelulasMicronucleadas++;
                                }
                                CvInvoke.DrawContours(CameraResult, Nucleithresh, j, new MCvScalar(255, 128, 0));
                                CvInvoke.DrawContours(CameraResult, Nucleithresh, PosicaoOutroNucleo, new MCvScalar(255, 128, 0));
                                CvInvoke.DrawContours(CameraResult, contours, i, new MCvScalar(255, 128, 0));
                            }
                            else if (Nucleos == 1 && Normal == 1)
                            {
                                VectorOfVectorOfPoint NucleithreshFinal = new VectorOfVectorOfPoint();
                                //VERIFICA A PRESENÇA DE OUTRO NUCLEO DENTRO DA CELULA!
                                for (int k = PosicaoThresh; k > 95; k--)
                                {
                                    VectorOfVectorOfPoint Nucleithresh2 = new VectorOfVectorOfPoint();
                                    int AchouNucleo2           = 0;
                                    Mat NucleihierarchyThresh2 = new Mat();
                                    Mat MorphStructuring       = new Mat();
                                    Mat MorphStructuring2      = new Mat();
                                    Cellthresh        = separateCell[0];
                                    Cellthresh2       = separateCell[0];
                                    MorphStructuring  = CvInvoke.GetStructuringElement(ElementShape.Ellipse, new Size(5, 5), new Point(-1, -1));
                                    MorphStructuring2 = CvInvoke.GetStructuringElement(ElementShape.Ellipse, new Size(9, 9), new Point(-1, -1));
                                    CvInvoke.Threshold(Cellthresh, Cellthresh, PosicaoThresh, 255, ThresholdType.Binary);
                                    //MessageBox.Show(PosicaoThresh.ToString());
                                    CvInvoke.Threshold(Cellthresh2, Cellthresh2, k, 255, ThresholdType.Binary);
                                    CvInvoke.MorphologyEx(Cellthresh, Cellthresh, MorphOp.Dilate, MorphStructuring2, new Point(-1, -1), 1, BorderType.Default, new MCvScalar());
                                    CvInvoke.MorphologyEx(Cellthresh2, Cellthresh2, MorphOp.Dilate, MorphStructuring, new Point(-1, -1), 1, BorderType.Default, new MCvScalar());
                                    CvInvoke.MorphologyEx(Cellthresh2, Cellthresh2, MorphOp.Erode, MorphStructuring, new Point(-1, -1), 1, BorderType.Default, new MCvScalar());
                                    Cellthresh2 = Cellthresh2 - Cellthresh;
                                    CvInvoke.FindContours(Cellthresh2, Nucleithresh2, NucleihierarchyThresh2, RetrType.Tree, ChainApproxMethod.ChainApproxSimple);
                                    if (Nucleithresh2.Size > 0 && Nucleithresh2.Size < 10)
                                    {
                                        for (int z = 0; z < Nucleithresh2.Size; z++)
                                        {
                                            ContourCompare.SetZero();
                                            MaskContourCell.SetZero();
                                            MaskContourNuclei.SetZero();
                                            double perimeter2        = CvInvoke.ArcLength(Nucleithresh2[z], true);
                                            double AreaNucleiThresh2 = CvInvoke.ContourArea(Nucleithresh2[z]);
                                            CvInvoke.DrawContours(MaskContourCell, contours, i, new MCvScalar(255, 255, 255));
                                            CvInvoke.DrawContours(MaskContourNuclei, Nucleithresh2, z, new MCvScalar(255, 255, 255));
                                            ContourCompare = MaskContourCell & MaskContourNuclei;
                                            int pixel2 = 0;

                                            for (int cols = 0; cols < ContourCompare.Cols; cols++)
                                            {
                                                for (int rows = 0; rows < ContourCompare.Rows; rows++)
                                                {
                                                    pixel2 += ContourCompare.Data[rows, cols, 0];
                                                }
                                            }

                                            if (AreaNucleiThresh2 < 50 && AreaNucleiThresh2 > 30 && pixel2 == 0 && AchouNucleo2 == 0 && perimeter2 < 27)
                                            {
                                                AchouNucleo2      = 1;
                                                PosicaoThresh2    = k;
                                                PosicaoNucleo2    = z;
                                                ThreshSet2        = Cellthresh;
                                                NucleithreshFinal = Nucleithresh2;
                                                AreaNucleo2       = AreaNucleiThresh2;
                                                break;
                                            }
                                        }
                                    }
                                    if (AchouNucleo2 == 1 && Math.Abs(AreaNucleo1 - AreaNucleo2) > 20)
                                    {
                                        Nucleos++;
                                        Micronucleada = 1;
                                        Normal        = 0;
                                        break;
                                    }
                                    else if (AchouNucleo2 == 1 && Math.Abs(AreaNucleo1 - AreaNucleo2) < 20)
                                    {
                                        Nucleos++;
                                        Binucleada = 1;
                                        Normal     = 0;
                                        break;
                                    }
                                }

                                if (Normal == 1)
                                {
                                    if (check == 0) //checa somente uma vez!
                                    {
                                        check = 1;
                                        CelulasNormais++;
                                    }
                                    CvInvoke.DrawContours(CameraResult, Nucleithresh, j, new MCvScalar(0, 255, 0));
                                    CvInvoke.DrawContours(CameraResult, contours, i, new MCvScalar(0, 255, 0));
                                    break;
                                }
                                else if (Binucleada == 1)
                                {
                                    if (check == 0) //checa somente uma vez!
                                    {
                                        check = 1;
                                        CelulasBinucleadas++;
                                    }
                                    CvInvoke.DrawContours(CameraResult, Nucleithresh, PosicaoNucleo, new MCvScalar(255, 0, 0));
                                    CvInvoke.DrawContours(CameraResult, NucleithreshFinal, PosicaoNucleo2, new MCvScalar(255, 0, 0));
                                    CvInvoke.DrawContours(CameraResult, contours, i, new MCvScalar(255, 0, 0));
                                    break;
                                }
                                else if (Micronucleada == 1)
                                {
                                    if (check == 0) //checa somente uma vez!
                                    {
                                        check = 1;
                                        CelulasMicronucleadas++;
                                    }
                                    CvInvoke.DrawContours(CameraResult, Nucleithresh, PosicaoNucleo, new MCvScalar(255, 128, 0));
                                    CvInvoke.DrawContours(CameraResult, NucleithreshFinal, PosicaoNucleo2, new MCvScalar(255, 128, 0));
                                    CvInvoke.DrawContours(CameraResult, contours, i, new MCvScalar(255, 128, 0));
                                    break;
                                }
                            }
                        }
                    }
                    if (AchouNucleo == 0)
                    //provavelmente a célula não possui núcleo -- cariólise
                    {
                        CvInvoke.DrawContours(CameraResult, contours, i, new MCvScalar(255, 0, 255));
                        CelulasCariolise++;
                    }
                }
            }
            NomeImagemSaida        = Path.GetFileName(Caminho);
            CelulasNormais2        = CelulasNormais;
            CelulasMicronucleadas2 = CelulasMicronucleadas;
            CelulasBinucleadas2    = CelulasBinucleadas;
            CelulasCariolise2      = CelulasCariolise;
            CelulasTotais2         = CelulasNormais2 + CelulasBinucleadas2 + CelulasCariolise2 + CelulasMicronucleadas2;
            return(CameraResult.ToBitmap());
        }
        private void watershedToolStripMenuItem_Click(object sender, EventArgs e)
        {
            // Segmentation - watershed
            if (ActiveMdiChild is ImageView)
            {
                Mat src            = ((ImageView)ActiveMdiChild).Mat;
                Mat gray           = new Mat();
                Mat thresh         = new Mat();
                Mat kernel         = new Mat();
                Mat opening        = new Mat();
                Mat item_bg        = new Mat();
                Mat item_fg        = new Mat();
                Mat dist_transform = new Mat();
                Mat unknown        = new Mat();
                Mat markers        = new Mat();
                Mat dst            = src.Clone();

                // Converting to Gray
                CvInvoke.CvtColor(src, gray, ColorConversion.Bgra2Gray);
                // Thresholding with Otsu
                CvInvoke.Threshold(gray, thresh, 0, 255, ThresholdType.BinaryInv | ThresholdType.Otsu);
                // Morphology operations
                kernel = CvInvoke.GetStructuringElement(ElementShape.Ellipse, new Size(3, 3), new Point(-1, -1));
                CvInvoke.MorphologyEx(thresh, opening, MorphOp.Open, kernel, new Point(-1, -1), 1, BorderType.Default, new MCvScalar(1, 0));
                CvInvoke.Dilate(opening, item_bg, kernel, new Point(-1, -1), 4, BorderType.Default, new MCvScalar(1, 0));
                // Distance transformation
                CvInvoke.DistanceTransform(opening, dist_transform, null, DistType.L2, 5);
                // Enhancing visibility
                CvInvoke.Threshold(dist_transform, item_fg, 0.5, 255, ThresholdType.Binary);
                CvInvoke.MorphologyEx(item_fg, item_fg, MorphOp.Erode, kernel, new Point(-1, -1), 10, BorderType.Default, new MCvScalar(1, 0));

                item_fg.ConvertTo(item_fg, DepthType.Cv8U);
                // Subtraction foreground from background
                CvInvoke.Subtract(item_bg, item_fg, unknown);
                // Getting markers
                CvInvoke.ConnectedComponents(item_fg, markers);
                // Converting to appropriate types for watershed
                dst.ConvertTo(dst, DepthType.Cv8U);
                markers.ConvertTo(markers, DepthType.Cv32S);
                // Calling Watershed from cvInvoke
                CvInvoke.Watershed(dst, markers);
                // Converting dst to Image to perform subscription directly without pointers
                Image <Bgr, byte> outputImage = dst.ToImage <Bgr, byte>(false);

                // Draw distinct objects red
                for (int i = 0; i < markers.Rows; ++i)
                {
                    for (int j = 0; j < markers.Cols; ++j)
                    {
                        outputImage.Data[i, j, 2] = 255;
                    }
                }

                ((ImageView)ActiveMdiChild).setImage(outputImage.Mat);
                ((ImageView)ActiveMdiChild).Refresh();
            }
            else
            {
                MessageBox.Show("Image shold be selected!", "Watershed Error", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }
        }
        public void ApplyWatershed()
        {
            var image = GetBitmap().ToImage <Bgr, byte>();

            var bg = GetClone();

            bg.GradeTrans(254);
            var msk = bg.GetClone();

            msk.ApplyNegative();

            bg.Erosion(3, 3);
            var bgImage = bg.GetBitmap().ToImage <Bgr, byte>().Convert <Gray, byte>();

            bgImage.ToBitmap().Save("1-bgImage.jpg");

            //Search for ~local minimums
            var localMinimums = GetClone();

            localMinimums.MarkLocalMinimums();
            localMinimums.Dilatation(3, 3);
            localMinimums.ApplyMask(msk);

            var minimums = localMinimums.GetBitmap().ToImage <Bgr, byte>().Convert <Gray, byte>();

            minimums.ToBitmap().Save("2-minimums.jpg");

            //Markers
            CvInvoke.ConnectedComponents(minimums, minimums);

            minimums.ToBitmap().Save("3-minimums.jpg");

            var output = minimums.Convert <Gray, int>();

            output.ToBitmap().Save("4-output.jpg");
            var max = int.MinValue;

            for (var i = 0; i < image.Height; i++)
            {
                for (var j = 0; j < image.Width; j++)
                {
                    max = Math.Max(output.Data[i, j, 0] + 1, max);
                }
            }

            for (var i = 0; i < image.Height; i++)
            {
                for (var j = 0; j < image.Width; j++)
                {
                    if (bgImage.Data[i, j, 0] == 255)
                    {
                        output.Data[i, j, 0] = max;
                    }
                }
            }

            output.ToBitmap().Save("5-output.jpg");

            //Do watershed
            CvInvoke.Watershed(image, output);

            //Load image
            var newData = new List <PointPairList>();
            var height  = output.Data.GetLength(0);
            var width   = output.Data.GetLength(1);

            for (var i = 0; i < height; i++)
            {
                var ppl = new PointPairList();
                for (var j = 0; j < width; j++)
                {
                    var color = output.Data[i, j, 0];
                    ppl.Add(0, (color == max || color == 0) ? -1 : output.Data[i, j, 0]);
                }
                newData.Add(ppl);
            }

            Data = newData;
        }