0

I've got this image that I can't think of a better way to draw just the contours in an image aside. This image was a result of segmentation cells after labeled with tools from the scikit image I tried to draw just (the colored) contours to pass this to the original image.

Does anyone know a good tool from OpenCV, Scikit-Image, or PIL that does this in a simple way?

enter image description here

  • not sure what special requirement you have about your problem. But I think you can follow this hhttps://www.geeksforgeeks.org/find-and-draw-contours-using-opencv-python/ to get the contour out. – Dr Yuan Shenghai Nov 04 '20 at 23:28
  • Dr Yuan Shenghai- The requirement is the contours owns the same color that the object has. The find_countours from OpenCV need thresholding which is a problem to separate every object. – Bruno Miguel Gonçalves Nov 05 '20 at 01:23
  • ok. there is no existing function that does that, but can be done easily. are you familiar with OpenCV masking? When you draw each boundary. use the the boundary as mask on the orinal image. and iteratively copy out. check this https://stackoverflow.com/questions/10469235/opencv-apply-mask-to-a-color-image – Dr Yuan Shenghai Nov 05 '20 at 05:08
  • Dr Yuan Shenghai- Thanks for the insight I will separate each object segmented and apply what you suggest to get the contours and then paste this to a new image with the coordinates from the original. – Bruno Miguel Gonçalves Nov 06 '20 at 03:45

2 Answers2

0

I don't know if I interpreted your question right, but you want to contour all colored semi-circle things on screen right?

What I'd do is use opencv to convert to gray, then threshold it, then use that to find and draw contours. You could also fill those contours, then you'd have white semi-circles on a black background. Like this:

image= cv2.imread(r"./colors.png")
imgray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)

ret, thresh = cv.threshold(imgray, 127, 255, 0)
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
image = cv2.drawContours(image, contours, -1, (255, 255, 255), 2)
cv.imshow("cont", image)
cv.waitKey(2000)

img_pl = np.zeros((1000,1000))
cv2.fillPoly(img_pl,pts=contours,color=(255,255,255))
cv2.imshow("polyfilled", img_pl)

Now, you'll have to play around with the thresholding as I see it does not detect everything. I did this very quick befre work so I diddled some, my apologies for that.

KVG
  • 59
  • 8
0

The best I could do was with felzenszwalb module from skimage. I think it's a simple code and get what I want, even though isn't with colored boundaries.

from skimage.segmentation import felzenszwalb
from skimage.segmentation import mark_boundaries

image= cv.imread(r"segmented.png")

def draw_boundaries(image):

    """
    Takes a color image and mark all boundaries of the colored objects.
    Args:
        image : 3D numpy array
    Returns:
        new   : 2D numpy array   
    """
    segments_fz = felzenszwalb(image, scale=1, sigma=0.000001, min_size=1)
    marked = mark_boundaries(image, segments_fz, color= (255, 255, 255), mode='outer')
    iy , ix, _ = np.where( marked == (255, 255, 255) )
    new = np.zeros((image.shape[:2]))
    new[iy,ix] = 255
    return new

The resulting image is:

enter image description here