Ask Your Question

How to draw contour lines between every colour?

asked 2020-01-14 07:14:22 -0600

OTapio gravatar image

updated 2020-10-10 20:41:02 -0600

I have a Numpy array that contains values between 0 and 255. How can I get contour lines between every color and not just 0 and non-zero?

My situation is the following

image description

It should be more like

image description

In theory I could loop over the array and setting everything to zero except single color and find contours for that, but that would be incredible tedious and I was hoping there was a more elegant solution.

edit retag flag offensive close merge delete


for my curiosity, what do the original images represent?

LBerger gravatar imageLBerger ( 2020-01-15 06:47:16 -0600 )edit

These are biological cells. I'm doing cell segmentation.

OTapio gravatar imageOTapio ( 2020-01-15 09:54:23 -0600 )edit

3 answers

Sort by ยป oldest newest most voted

answered 2020-01-20 08:34:33 -0600

supra56 gravatar image

updated 2020-01-20 08:36:02 -0600

Try this:

#OpenCV 4.2.0, Raspberry pi 3/3b/4b, Buster v10
#Date: 20th January, 2020

import cv2

img = cv2.imread('bio.png')
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 50, 255, 0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
print("Number of contours = {}".format(str(len(contours))))
print('contours {}'.format(contours[0]))

cv2.drawContours(img, contours, -1, (0, 255, 0), 2)
cv2.drawContours(imgray, contours, -1, (0, 255, 0), 3)

cv2.imshow('Image', img)
cv2.imshow('Image GRAY', imgray)


image description

edit flag offensive delete link more

answered 2020-01-20 06:52:45 -0600

BadMachine gravatar image

Also try to use Canny edge detector before findContours

edit flag offensive delete link more

answered 2020-01-15 06:38:42 -0600

You could use OpenCV's inrange function that will threshold based on color channel ranges.

image description

In this screen capture, the 2nd image from the left is the result of inrange on the background color. The 3rd image is the result of inrange on one of the yellow colors. The 4th image is the result of inrange on one of the blue colors. You would need a loop to find a foreground region, get its color, use inrange to find contours/blobs of this color, then remove those foreground regions. Continue the loop until there are no more foreground regions. You can try this tool for yourself at

edit flag offensive delete link more


Thanks. I'll have to try this out.

OTapio gravatar imageOTapio ( 2020-01-15 09:54:48 -0600 )edit

Question Tools

1 follower


Asked: 2020-01-14 07:14:22 -0600

Seen: 7,671 times

Last updated: Jan 20 '20