Detect gray things with OpenCV
opencv, python
Solution
The fastest method I can find in Python is to use slicing to compare each channel. After a few test runs, this method is upwards of 200 times faster than two nested for-loops.
bg = im[:,:,0] == im[:,:,1] # B == G
gr = im[:,:,1] == im[:,:,2] # G == R
slices = np.bitwise_and(bg, gr, dtype= np.uint8) * 255
This will generate a binary image where gray objects are indicated by white pixels. If you do not need a binary image, but only a logical array where grey pixels are indicated by `True` values, this method gets even faster:
slices = np.bitwise_and(bg, gr)
Omitting the type cast and multiplication yields a method 500 times faster than nested loops.
Running this operation on this test image:
Gives the following result:
As you can see, the gray object is correctly detected.
Problem
I'd like to detect an object using OpenCV that is distinctly different from other elements in the scene as it's gray. This is good because I can just run a test with R == G == B and it allows to be independent of luminosity, but doing it pixel by pixel is slow. Is there a faster way to detect gray things? Maybe there's an OpenCV method that does the R == G == B test... `cv2.inRange` does color thresholding, it's not quite what I'm looking for.