/// <summary>
        /// Execute segmentation process of inner structures.
        /// </summary>
        public void Execute()
        {
            if (image != null)
            {
                Image <Bgr, byte> maskedImage = new Image <Bgr, byte>(image.Width, image.Height, new Bgr(255, 255, 255));
                CvInvoke.cvCopy(image, maskedImage, particleMask);

                Console.WriteLine("Image dimensions: " + image.Width + " / " + image.Height);
                Console.WriteLine("Masked Image dimensions: " + maskedImage.Width + " / " + maskedImage.Height);

                UMat temp = SegmentationUtils.IncreaseContrast(maskedImage.ToUMat(), 5.0, 8);
                temp = SegmentationUtils.Blur(temp, 3, 1.0);
                temp = SegmentationUtils.Sharp(temp);
                Image <Bgr, byte> tempImage = new Image <Bgr, byte>(temp.Bitmap);
                UMat uMatChannel            = SegmentationUtils.GetColorChannelAsUMat(segmentationParameters.Colorspace, tempImage, segmentationParameters.Channel);

                if (segmentationParameters.UseKmeans)
                {
                    KmeansSegmentation(uMatChannel);
                }
                else
                {
                    StandardSegmentation(uMatChannel);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Execute segmentation process.
        /// </summary>
        public void Execute()
        {
            if (image != null)
            {
                UMat temp = SegmentationUtils.IncreaseContrast(image.ToUMat(), 5.0, 8);
                temp = SegmentationUtils.Blur(temp, 3, 1.0);
                temp = SegmentationUtils.Sharp(temp);
                Image <Bgr, byte> tempImage = new Image <Bgr, byte>(temp.Bitmap);
                UMat uMatChannel            = SegmentationUtils.GetColorChannelAsUMat(segmentationParameters.Colorspace, tempImage, segmentationParameters.Channel);

                UMat thresholded = null;
                using (UMat copy = uMatChannel.Clone())
                {
                    if (segmentationParameters.UseOtsu)
                    {
                        thresholded = SegmentationUtils.ThresholdOtsu(copy);
                    }
                    else
                    {
                        thresholded = SegmentationUtils.Threshold(copy, segmentationParameters.Threshold);
                    }
                }

                UMat closed = SegmentationUtils.Closing(thresholded, 5);
                //UMat eroded = SegmentationUtils.Erode(closed, 15);
                UMat dilated = SegmentationUtils.Dilate(closed, 10);
                //ReadWriteUtils.WriteUMatToFile(ApplicationContext.OutputPath + "\\dilated.png", dilated);

                VectorOfVectorOfPoint contours         = new VectorOfVectorOfPoint();
                VectorOfVectorOfPoint contoursRelevant = new VectorOfVectorOfPoint();
                CvInvoke.FindContours(dilated, contours, null, RetrType.External, ChainApproxMethod.ChainApproxSimple);

                int autoMaxPixelSize = ImageUtils.GetPercentualImagePixelCount(image, 0.03f);
                for (int i = 0; i < contours.Size; i++)
                {
                    double area = CvInvoke.ContourArea(contours[i]);

                    if (IsContourRelevant(area, autoMaxPixelSize, segmentationParameters))
                    {
                        contoursRelevant.Push(contours[i]);
                    }
                }

                CvInvoke.DrawContours(image, contoursRelevant, -1, new MCvScalar(0, 0, 255));

                mask = new Image <Gray, Byte>(image.Width, image.Height, new Gray(0.0));
                CvInvoke.DrawContours(mask, contoursRelevant, -1, new MCvScalar(255.0), thickness: -1);
            }
        }
        /// <summary>
        /// Kmeans segmentation of given image.
        /// 1. Do a kmeans clustering
        /// 2. Find contours
        /// 3. Classification of clusters (?)
        /// </summary>
        /// <param name="uMatChannel"></param>
        private void KmeansSegmentation(UMat uMatChannel)
        {
            if (false)
            {
                Image <Bgr, byte> newImage       = new Image <Bgr, byte>(uMatChannel.Bitmap);
                Image <Bgr, byte> clusteredImage = SegmentationUtils.KMeansClustering <Bgr, byte, byte>(newImage.Clone(), 3, SegmentationUtils._clusterColors);

                ReadWriteUtils.WriteUMatToFile(@"D:\testdata\_temp\kmeans.png", clusteredImage.ToUMat());

                // TODO
                // Find contours
                // Classificate contours
            }

            throw new NotImplementedException();
        }
        /// <summary>
        /// Standard segmentation of given image.
        /// 1. Thresholding
        /// 2. Morphological operations
        /// 3. Find contours
        /// 4. Calculate coefficients and classificate contours
        /// </summary>
        /// <param name="uMatChannel">image in UMat format</param>
        private void StandardSegmentation(UMat uMatChannel)
        {
            // thresholding
            UMat thresholded = null;

            using (UMat copy = uMatChannel.Clone())
            {
                if (segmentationParameters.UseOtsu)
                {
                    thresholded = SegmentationUtils.ThresholdOtsu(copy);
                }
                else
                {
                    thresholded = SegmentationUtils.Threshold(copy, segmentationParameters.Threshold);
                }
            }

            // morphological operations (todo: make kernel generic or depending on image size)
            UMat opened  = SegmentationUtils.Opening(thresholded, 5);
            UMat dilated = SegmentationUtils.Dilate(opened, 5);
            //ReadWriteUtils.WriteUMatToFile(ApplicationContext.OutputPath + "\\dilated.png", dilated);
            UMat inverted = new UMat();

            CvInvoke.BitwiseNot(dilated, inverted);
            //ReadWriteUtils.WriteUMatToFile(ApplicationContext.OutputPath + "\\inverted.png", inverted);

            VectorOfVectorOfPoint contours         = new VectorOfVectorOfPoint();
            VectorOfVectorOfPoint contoursRelevant = new VectorOfVectorOfPoint();

            CvInvoke.FindContours(inverted, contours, null, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple);

            int nonRelevantPixelSize = ImageUtils.GetPercentualImagePixelCount <UMat>(inverted, 0.005f);

            Console.WriteLine("Non relevant pixel size: " + nonRelevantPixelSize);
            Console.WriteLine("Number of contours: " + contours.Size);

            ClassifyContours(uMatChannel, ref contours, ref contoursRelevant, nonRelevantPixelSize);

            // debug: show image with found contours
            //CvInvoke.DrawContours(image, contoursRelevant, -1, new MCvScalar(0, 255, 0));
            //ReadWriteUtils.WriteUMatToFile(ApplicationContext.OutputPath + "\\image_with_contours.png", image.ToUMat());

            // creat mask with rigid structures
            Image <Gray, byte> mask = new Image <Gray, byte>(image.Width, image.Height, new Gray(0.0));

            CvInvoke.DrawContours(mask, contoursRelevant, -1, new MCvScalar(255.0), thickness: -1);
            //ReadWriteUtils.WriteUMatToFile(ApplicationContext.OutputPath + "\\mask.png", mask.ToUMat());
            UMat inv1 = new UMat();

            CvInvoke.BitwiseNot(mask, inv1);
            UMat convertedMask = new UMat();

            inv1.ConvertTo(convertedMask, DepthType.Cv32F);

            // create mask with non rigid structures
            Image <Gray, byte> convMask = new Image <Gray, byte>(convertedMask.Bitmap);
            Image <Gray, byte> mask2    = new Image <Gray, byte>(image.Width, image.Height, new Gray(255.0));

            CvInvoke.Subtract(particleMask, convMask, mask2);
            //ReadWriteUtils.WriteUMatToFile(ApplicationContext.OutputPath + "\\INV_mask.png", mask2.ToUMat());
            UMat inv2 = new UMat();

            //CvInvoke.BitwiseNot(mask2, inv2);
            CvInvoke.BitwiseAnd(mask2, mask, inv2);
            inv2 = SegmentationUtils.Dilate(inv2, 10);
            UMat convertedMask2 = new UMat();

            inv2.ConvertTo(convertedMask2, DepthType.Cv32F);

            //ReadWriteUtils.WriteUMatToFile(ApplicationContext.OutputPath + "\\_mask1.png", convertedMask);
            //ReadWriteUtils.WriteUMatToFile(ApplicationContext.OutputPath + "\\_mask2.png", convertedMask2);

            // add masks to list
            masks.Add(convertedMask);
            masks.Add(convertedMask2);
        }