i am working on a single cell image to detect the nucleus.
Logic used-
1. i am detecting the darkest pixel in the cell(which in most cases belongs to the nucleus)
2. using canny edge detection to detect the edges.(low threshold=0, high threshold=0, sigma=3)
3. threshold with a value of 1 and make all the edges white in colour.
4. Starting from the darkest pixel, i traverse all the neighbours till i reach the nearest edge.

This works for most cases and detects the nucleus well.
But, sometimes, the edge detection does not form a fully closed curve around the nucleus and leaves a gap at few areas. so when i traverse thru neighbor pixels, the pointer crosses the required area thru the small gaps and goes into other parts of the image.

i want a solution that will form closed curves, i.e fill up the gaps in the edges.
i tried the dilating the image and then eroding it. it closes some curves but not all.

unsafe public Bitmap execute2(Bitmap inputImage, Bitmap temp)
        {
            BitmapData inputImageData = inputImage.LockBits(new Rectangle(0, 0, inputImage.Width, inputImage.Height),
                                            ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
            byte* inputImagePtr = (byte*)(void*)inputImageData.Scan0.ToPointer();
            
            BitmapData tempData = temp.LockBits(new Rectangle(0, 0, inputImage.Width, inputImage.Height),
                                            ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
            byte* tempPtr = (byte*)(void*)tempData.Scan0.ToPointer();
            int i, j;
            Point maxIntensity = new Point();
            Point curr = new Point();
            Point neigh = new Point();
            Byte max = 255;
            
            Stack<Point> points = new Stack<Point>();
            Stack<Point> check = new Stack<Point>();
            for (i = 0; i < temp.Height; i++)
            {
                for (j = 0; j < temp.Width; j++)
                {
                    if (inputImagePtr[i * temp.Width + j] != 255)
                    {
                        if (inputImagePtr[i * temp.Width + j] < max && tempPtr[i * temp.Width + j]!=255)
                        {
                            max = inputImagePtr[i * temp.Width + j];
                            maxIntensity.X = j;
                            maxIntensity.Y = i;
                        }   
                    }
                }
            }
            
            int width = temp.Width;
            int height = temp.Height;
            points.Push(maxIntensity);

            while (points.Count != 0)
            {
                curr = points.Pop();
                if (tempPtr[curr.Y * width + curr.X] != 255 && curr.X > 0 && curr.X < width - 1 && curr.Y > 0 && curr.Y < height - 1)
                {
                    neigh.X = curr.X - 1;
                    neigh.Y = curr.Y;
                    if (check.Contains(neigh) == false)
                    {
                        points.Push(neigh);
                        check.Push(neigh);
                        inputImagePtr[neigh.Y * width + neigh.X] = 0;
                    }
                    neigh.X = curr.X + 1;
                    neigh.Y = curr.Y;
                    if (check.Contains(neigh) == false)
                    {
                        points.Push(neigh);
                        check.Push(neigh);
                        inputImagePtr[neigh.Y * width + neigh.X] = 0;
                    }

                    neigh.X = curr.X;
                    neigh.Y = curr.Y - 1;
                    if (check.Contains(neigh) == false)
                    {
                        points.Push(neigh);
                        check.Push(neigh);
                        inputImagePtr[neigh.Y * width + neigh.X] = 0;
                    }

                    neigh.X = curr.X;
                    neigh.Y = curr.Y + 1;
                    if (check.Contains(neigh) == false)
                    {
                        points.Push(neigh);
                        check.Push(neigh);
                        inputImagePtr[neigh.Y * width + neigh.X] = 0;
                    }
                }
            }
            inputImage.UnlockBits(inputImageData);
            temp.UnlockBits(tempData);
            return inputImage;
        }

inputImage- original grayscale image with white background
temp- after canny, dilation, erosion (black background, white edges)

Edited 7 Years Ago by vikram89: n/a

works well for 1.
does not for 24.

24-canny is after canny edge detection
as u can see, there is a small gap in the curve.. i want to close that

not able to upload.. says png image has incorrect file extension

Ryshad, I think there is some problem. I tried uploading theimage for him, but am unable to

This article has been dead for over six months. Start a new discussion instead.