0

As the title suggests, the image consists of solid color blocks. I want to extract all the color blocks from the image and separate them individually. I've made many attempts, but the results haven't been very satisfactory:

  1. Extracting by automatically calculating the threshold, unfortunately, doesn't work for all color blocks.
t, _ = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
_, target = cv2.threshold(img, t, 255, cv2.THRESH_BINARY_INV)
cnts, hierarchys = cv2.findContours(target, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
  1. After edge detection and a series of morphological operations for contour extraction, there are still many unwanted extra parts.
gray_temp = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = 255 - cv2.Canny(gray_temp, 25, 50)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
edges = cv2.erode(edges, kernel, iterations=1)
cnts, hierarchys = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

So, what I've been thinking is whether I could first extract all the colors from the image and then use the color information to extract the blocks.

Ready to give it a try, I attempted to use numpy to retrieve color information, but the obtained color information surprised me. Pixels that appear to be the same color don't have identical RGB values.

I felt a bit disheartened. I searched Google again and found a promising library called "extcolors." I was excited, as if I had glimpsed a ray of hope. However, reality dealt me a blow - it requires setting a tolerance. The frustrating part is that this tolerance varies for each image, and different values yield vastly different results.

So, my question is, is there any effective method that could allow me to obtain all the colors, or are there alternative ways to extract the color blocks with high quality?

enter image description here

HamGuy
  • 916
  • 1
  • 7
  • 18
  • 3
    "appear to be the same color don't have identical RGB values" -- consider that 24bit RGB can represent ~16.8 million distinct colours. On the other hand, we don't have anywhere as many unique names for what we consider different colours. This is something that lossy compression takes advantage of. | There is also anti-aliasing in play -- open that image in some image editor and zoom in as much as you can, so that you see the individual pixels as big squares. Notice that there aren't abrupt changes where different coloured areas meet, but there is a gradient blending the two colours. – Dan Mašek Aug 23 '23 at 13:49
  • 3
    Seems to me that "all the colors" is not actually what you want, since you were unsatisfied when you actually got those. So, what is it that you actually desire? What should the result of analysis of the picture you provided look like? How many distinct colours does that contain in your opinion? – Dan Mašek Aug 23 '23 at 13:52
  • 2
    check [this](https://stackoverflow.com/a/35482205/5008845) – Miki Aug 23 '23 at 14:19
  • Well, What I want is, just from the naked eye, I think there are only 5 colors on this picture: beige background, black eyes and some lashes, red lashes, nose mouth etc., white eyeballs as well as blue snot – HamGuy Aug 23 '23 at 16:23
  • 1
    throw all that code away. the answer to your question is "clustering" or posterization. – Christoph Rackwitz Aug 23 '23 at 16:31
  • It's over, just visit this site https://vectorizer.ai – HamGuy Aug 24 '23 at 08:23

0 Answers0