4

I'm trying to write code to detect the color of a particular area of an image.

So far I have come across is using OpenCV, we can do this, But still haven't found any particular tutorial to help with this.

I want to do this with javascript, but I can also use python OpenCV to get the results. can anyone please help me with sharing any useful link or can explain how can I achieve detecting the color of the particular area in the image.

For eg. enter image description here

The box in red will show a different color. I need to figure out which color it is showing.

What I have tried:

I have tried OpenCV canny images, though I am successful to get area separated with canny images, how to detect the color of that particular canny area is still a challenge.

Also, I tried it with inRange method from OpenCV which works perfect

# find the colors within the specified boundaries and apply
# the mask
mask = cv2.inRange(image, lower, upper)
output = cv2.bitwise_and(image, image, mask = mask)

# show the images
cv2.imshow("images", np.hstack([image, output]))

It works well and extracts the color area from the image But is there any callback which responds if the image has particular color so that it can be all done automatically?

11
  • 1
    if this is a challenge for you you might want to start with reading a book... oldschool but very effective. if you want help on processing an image post that image, provide your code, explain what you expect to happen and what happens instead. just asking for general advice will get your question closed for being too broad. Commented Nov 16, 2017 at 17:07
  • Yes, I am updating the question Commented Nov 16, 2017 at 17:10
  • Please show a sample image and which area is of interest. Commented Nov 16, 2017 at 23:11
  • @Piglet updated question with image and code Commented Nov 17, 2017 at 8:31
  • the approach to this problem would highly depend on the images. is it always just two different colours? is the smaller region always a square in the center? there are many ways to fully automate that but which one to use would depend on the images. if your're just curious which colours are present you could simply create a histogram. Commented Nov 17, 2017 at 9:02

3 Answers 3

3
+50

So I am assuming here that, you already know the location of the rect which is going to be dynamically changed and need to find out the single most dominant color in the desired ROI. There are a lot of ways to do the same, one is by getting the average, of all the pixels in the ROI, other is to count all the distinct pixel values in the given ROI, with some tolerance difference.

Method 1:

import cv2
import numpy as np

img = cv2.imread("path/to/img.jpg")
region_of_interest = (356, 88, 495, 227) # left, top, bottom, right

cropped_img = img[region_of_interest[1]:region_of_interest[3], region_of_interest[0]:region_of_interest[2]]

print cv2.mean(cropped_img)
>>> (53.430516018839604, 41.05708814243569, 244.54991977640907, 0.0)

Method 2:

To find out the various dominant clusters in the given image you can use cv2.kmeans() as:

import cv2
import numpy as np

img = cv2.imread("path/to/img.jpg")
region_of_interest = (356, 88, 495, 227)

cropped_img = img[region_of_interest[1]:region_of_interest[3], region_of_interest[0]:region_of_interest[2]]
Z = cropped_img.reshape((-1, 3))

Z = np.float32(Z)

criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 4
ret, label, center = cv2.kmeans(Z, K, None, criteria, 10, cv2.KMEANS_RANDOM_CENTERS)

# Sort all the colors, as per their frequencies, as:
print center[sorted(range(K), key=lambda x: np.count_nonzero(label == [x]), reverse=True)[0]]
>>> [  52.96525192   40.93861389  245.02325439]
Sign up to request clarification or add additional context in comments.

Comments

0

@Prateek... nice to have the question narrowed down to the core. The code you provided does not address this issue at hand and remains just a question. I'll hint you towards a direction but you have to code it yourself.

steps that guide you towards a scripting result:

1) In your script add two (past & current) pixellists to store values (pixeltype + occurance).

2) Introduce a while-loop with an action true/stop statement (link to "3") for looping purpose because then it becomes a dynamic process.

3) Write a GUI with a flashy warning banner.

4) compare the pixellist with current_pixellist for serious state change (threshhold).

5) If the delta state change at "4" meets threshold throw the alert ("3").

When you've got written the code and enjoyed the trouble of tracking the tracebacks... then edit your question, update it with the code and reshape your question (i can help wiht that if you want). Then we can pick it up from there. Does that sound like a plan?

Comments

0

I am not sure why you need callback in this situation, but maybe this is what you mean?

def test_color(image, lower, upper):
    mask = cv2.inRange(image, lower, upper)
    return np.any(mask == 255)

Explanations:

  • cv2.inRange() will return 255 when pixel is in range (lower, upper), 0 otherwise (see docs)
  • Use np.any() to check if any element in the mask is actually 255

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.