4

I wrote the code bellow to detect 3D shapes in an image and it works correctly.

Now I need to detect the colors inside the shapes and calculate them.

Could anyone point me where should I start with color detection?

Code for shape detection below, maybe it will be of use:

import cv2
import numpy as np

cv2.imshow('Original Image',rawImage) 
cv2.waitKey(0)

hsv = cv2.cvtColor(rawImage, cv2.COLOR_BGR2HSV)
cv2.imshow('HSV Image',hsv)
cv2.waitKey(0)

hue ,saturation ,value = cv2.split(hsv)
cv2.imshow('Saturation Image',saturation)
cv2.waitKey(0)

retval, thresholded = cv2.threshold(saturation, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
cv2.imshow('Thresholded Image',thresholded)
cv2.waitKey(0)

medianFiltered = cv2.medianBlur(thresholded,5)
cv2.imshow('Median Filtered Image',medianFiltered)
cv2.waitKey(0) 

cnts, hierarchy = cv2.findContours(medianFiltered, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

for c in cnts:
# compute the center of the contour
M = cv2.moments(c)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])


first = cv2.drawContours(rawImage, [c], -1, (0, 255, 0), 2)
second =cv2.circle(rawImage, (cX, cY),1 , (255, 255, 255), -1)


cv2.imshow('Objects Detected',rawImage)
cv2.waitKey(0)

Centers of shapes founded as we can see, when we do print(second) we get a output of all pixels But I need output just from the pixel inside contour,with this method is that imposible to get values from pixel inside in contour?

Erdal.J
  • 51
  • 1
  • 6
  • What do you mean by `calculate them`? Represent them as `RGB` values, as HTML hex-codes? – Szymon Maszke Feb 11 '19 at 10:41
  • I think you mean calculating the dominant color. [This answer](https://stackoverflow.com/a/43111221/10699171) shows an implementation. – J.D. Feb 11 '19 at 11:32
  • @SzymonMaszke I mean,for example; If in the input image there are totally 5 cubes with three different colors I need output like 2 cubes are red,2 cubes yellow and 1 red. – Erdal.J Feb 11 '19 at 12:51
  • @J.D. I mean calculating the colors which are inside in the shapes.For example if we have an image with 6 circles composed of tree colors(blue,white,yellow),I need to recognize the colors and get output like 2 circles are blue,2 white and 2 yellow. – Erdal.J Feb 11 '19 at 12:59
  • I can't help feeling it would help if we could see your image... – Mark Setchell Feb 11 '19 at 13:48
  • just check pixel value for example in the middle of your shape. It is safe to assume that a pixel in the middle represents your shape color. – Sane_or_not Feb 11 '19 at 13:54
  • @MarkSetchell I uploaded the image also.Can you see now? – Erdal.J Feb 11 '19 at 14:09
  • Yes. For each contour, find the minimum and maximum `x` and `y` coordinates and average those to find the centre of the shape. Use Numpy slicing to take a, say, 5x5 pixel square centred on that point. Now take the mean of the red, green and blue channels in that square as the ball's colour. – Mark Setchell Feb 11 '19 at 15:00
  • You state in a comment above that the output you want is '2 circles are blue, 2 are yellow'. First use the center of shape method to get the colors. Next you have to associate the colors with words / categories. This is easiest if to convert the found colors to HSV colorspace [(How to)](https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_colorspaces/py_colorspaces.html#how-to-find-hsv-values-to-track). You can then associate a range of hue with a word / category. For example Hue 50-70 is green [(graph)](https://i.stack.imgur.com/TSKh8.png). – J.D. Feb 11 '19 at 15:52
  • @MarkSetchell thanks for advice.I get the center of shapes with the code bellow : `M = cv2.moments(c) cX = int(M["m10"] / M["m00"]) cY = int(M["m01"] / M["m00"])`... Then we drowe the contours, and circles in the center of shapes - `first = cv2.drawContours(rawImage, [c], -1, (0, 255, 0), 2) second =cv2.circle(rawImage, (cX, cY),1 , (255, 255, 255), -1)` .. – Erdal.J Feb 12 '19 at 14:11
  • @MarkSetchell As you can see I give the variables (first and second) just because I thought that if I do print(first) or (second) I will get output just from pixels inside in contours.But I was wrong and I get output from all pixels in the image. Really Iam blocked at this step, I tried to do something with cv2.mean() but I was unsuccessful..Can you give me simple explanation or example how can I take the mean of the colors..Thanks again – Erdal.J Feb 12 '19 at 14:16
  • @J.D.thanks for youre advice.I followed mr Marks and yours explanation to find the center of shapes.I did it with the code above. But now as I wrote above, when I print(first or second) variables Iam getting output of all pixels not from pixels which are inside contour.. İs that method impossible to take the value of pixel inside contour? I mean finding center of shapes-Giving variable to this and print this variable? thanks again **Main code above and detected centers of shapes image updated ** – Erdal.J Feb 12 '19 at 14:33
  • @Sane_or_not I find the centers of each shape,I get bgr values of each shape center but now I dont know ho to convert BGR values to color names..I tried with cv2.inRange() function lower and upper but I was unsuccessful.İf you know the main thing how to convert,can you give me a example according my code? – Erdal.J Feb 15 '19 at 14:22

1 Answers1

3

Basic idea:

(1) Convert the image to HSV color space;
(2) Threahold the `S` to find color regions;
(3) Calculate average hsv for each color-region-maskin HSV, then convert into BGR.

For the image:

enter image description here

(1) Convert the image to HSV color space:

enter image description here

(2) Threahold the `S` to find color regions:

enter image description here

(3) Calculate average hsv for each color-region-maskin HSV, then convert into BGR.

enter image description here


Some links maybe useful:

1. just detect color regions: 

(1) How to detect colored patches in an image using OpenCV?

(2) OpenCV C++/Obj-C: Detecting a sheet of paper / Square Detection

2. detect specific color in HSV:

(1) for green: How to define a threshold value to detect only green colour objects in an image :Opencv

(2) for orange: Choosing the correct upper and lower HSV boundaries for color detection with`cv::inRange` (OpenCV)

(3) take of the H of the red: How to find the RED color regions using OpenCV?

3. If you want to crop polygon mask:

(1) Cropping Concave polygon from Image using Opencv python

Kinght 金
  • 14,440
  • 4
  • 49
  • 62
  • thanks for explanation,but this method is not useless for me.I must did detection with code and steps above. I updated the main code and Image.Last step I find the centers of shapes so now I get the center coordinates of each shape.Now I need to access to pixels with these coordinates..Do you have any idea,how can I access? thanks again – Erdal.J Feb 13 '19 at 14:51