0

I know here already some questions were asked but they did't help me to solve my problem. I will appreciate any help to solve my problem. I'm new to opencv.

I have an image and apply some code to get contours from image. Now i want to get the RGB color values from detected contours. How can i do that?

I do research on it and find that it could be solved by using contours so i try to implement contours and now finally i want to get the color values of the contours.

Here is my Code:

import cv2
import numpy as np

img = cv2.imread('C:/Users/Rizwan/Desktop/example_strip1.jpg')

img_hsv = cv2.cvtColor(255-img, cv2.COLOR_BGR2HSV)

lower_red = np.array([40, 20, 0])
upper_red = np.array([95, 255, 255])

mask = cv2.inRange(img_hsv, lower_red, upper_red)

contours, _ = cv2.findContours(mask, cv2.RETR_TREE, 
cv2.CHAIN_APPROX_SIMPLE)
color_detected_img = cv2.bitwise_and(img, img, mask=mask)
print(len(contours))
for c in contours:
    area = cv2.contourArea(c)
    x, y, w, h = cv2.boundingRect(c)
    ax = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 0), 2)
    rect = cv2.minAreaRect(c)
    box = cv2.boxPoints(rect)
    box = np.int0(box)
    im = cv2.drawContours(color_detected_img, [box], -1, (255, 0, 0), 2)


cv2.imshow("Cropped", color_detected_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

I expect the output should be the RGB values of the detected color inside the contours.

rizwan
  • 51
  • 1
  • 11
  • 1) Why do you "invert" the input image before converting to HSV color space: `img_hsv = cv2.cvtColor(255-img, cv2.COLOR_BGR2HSV)`? 2) What do you expect the output to look like? Like some kind of histogram? Pixel specific RGB values (like **JUST** the pixels)? – HansHirse Sep 30 '19 at 10:07
  • i invert the image to detect two colored lines as shown in image(two red lines). If it is not a good way then please help me to better it. and i want the pixel specific RGB values like [183, 172, 167] – rizwan Sep 30 '19 at 10:17
  • 1
    For selecting "proper" HSV color ranges: There's a short introduction on that in [one of my answers to an earlier question](https://stackoverflow.com/a/55827176/11089932). Looking at your input image, I'm quite sceptical, that you can extract the second, lighter stripe with good precision and maintaining at least some code generalizability. The first, more present stripe can be found, if you set up a proper red color range, maybe at the "violet end" of the hue spectrum (see link for further explanation). – HansHirse Sep 30 '19 at 10:47
  • Ok that's good, Can you please provide the solution of my question like how can i get the rgb values from inside of a contour in opencv? Thanks – rizwan Sep 30 '19 at 10:54

1 Answers1

0

As asked in the comments, here's a possible solution to extract the BGR(!) values from the pixels of an image inside a before found contour. The proper detecting of the desired, colored stripes is omitted here as also discussed in the comments.

Having an image and a filled mask of a contour, for example from cv2.drawContours, we can simply use NumPy's boolean array indexing by converting the (most likely uint8) mask to an bool_ array.

Here's a short code snippet, that uses NumPy's savetxt to store all values in some txt file:

import cv2
import numpy as np

# Some dummy image
img = np.zeros((100, 100, 3), np.uint8)
img = cv2.rectangle(img, (0, 0), (49, 99), (255, 0, 0), cv2.FILLED)
img = cv2.rectangle(img, (50, 0), (99, 49), (0, 255, 0), cv2.FILLED)
img = cv2.rectangle(img, (50, 50), (99, 99), (0, 0, 255), cv2.FILLED)

# Mask of some dummy contour
mask = np.zeros((100, 100), np.uint8)
mask = cv2.fillPoly(mask, np.array([[[20, 20], [30, 70], [70, 50], [20, 20]]]), 255)

# Show only for visualization purposes
cv2.imshow('img', img)
cv2.imshow('mask', mask)

# Convert mask to boolean array
mask = np.bool_(mask)

# Use boolean array indexing to get all BGR values from img within mask
values = img[mask]

# For example, save values to txt file
np.savetxt('values.txt', values)

cv2.waitKey(0)
cv2.destroyAllWindows()

The dummy image looks like this:

Dummy image

The dummy contour mask looke like this:

Dummy contour mask

The resulting values.txt has some >1000 entries, please check yourself. Attention: Values are BGR values; e.g. prior converting the image to RGB is needed to get RGB values.

Hope that helps!

HansHirse
  • 18,010
  • 10
  • 38
  • 67
  • can you please make it easy for me to detect the two lines shown in image properly by giving me the exact lower and upper values? Thanks – rizwan Sep 30 '19 at 12:42