Detect if there is gray color in image by opencv Python

Question:

I’m new to cv2 library and I want to make a program that will detect if there is gray color in an image at real time.
Until now I took a code that will show me the screen in real time

import numpy as np
import cv2
import pyautogui
from mss import mss
from PIL import Image

mon = {'top': 268, 'left': 968, 'width': 931, 'height': 599}

sct = mss()

while 1:
    sct.get_pixels(mon)
    img = Image.frombytes('RGB', (sct.width, sct.height), sct.image)
    cv2.imshow('test', np.array(img))
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break

But I have no idea how to detect if gray color appear in the screen(The other questions is about if all the picture is gray and not if gray appear in the screen)

Asked By: aviel ovadiya

||

Answers:

The better way is to change the colour space into HSV and find the Hue value range for colour.

  • Take each frame of the video
  • Convert from BGR to HSV color-space
  • Threshold the HSV image for a range of blue colour

Below code is from OpenCV official site to detect the blue colour object

import cv2 as cv
import numpy as np
cap = cv.VideoCapture(0)
while(1):
    # Take each frame
    _, frame = cap.read()
    # Convert BGR to HSV
    hsv = cv.cvtColor(frame, cv.COLOR_BGR2HSV)
    # define range of blue color in HSV
    lower_blue = np.array([110,50,50])
    upper_blue = np.array([130,255,255])
    # Threshold the HSV image to get only blue colors
    mask = cv.inRange(hsv, lower_blue, upper_blue)
    # Bitwise-AND mask and original image
    res = cv.bitwise_and(frame,frame, mask= mask)
    cv.imshow('frame',frame)
    cv.imshow('mask',mask)
    cv.imshow('res',res)
    k = cv.waitKey(5) & 0xFF
    if k == 27:
        break
cv.destroyAllWindows()

For Live screen Gray colour Detection

the range will be in HSV is

lower_blue = np.array([0,0,0])
upper_blue = np.array([255,10,255])

In HSV/HSL colourspace, the grey pixels are characterized by having a Saturation of very close to zero. Then the Value channel will tell you how far along the scale from black to white they actually are, low Lightness/Value is dark grey whereas high Lightness/Value means light grey.

So for the grey colour, your code is as below

import numpy as np
from PIL import Image
from mss import mss
import cv2 as cv
import cv2
mon = {'top': 268, 'left': 968, 'width': 931, 'height': 599}
sct = mss()
while (1):
  # Take each
  sct.get_pixels(mon)
  img = Image.frombytes('RGB', (sct.width, sct.height), sct.image)
  img = np.array(img)
  # Convert RGB to HSV
  hsv = cv.cvtColor(img, cv.COLOR_RGB2HSV)
  # define range of gray color in HSV
  lower_gray = np.array([0, 0, 0])
  upper_gray = np.array([255, 10, 255])
  # Threshold the HSV image to get only gray colors
  mask = cv.inRange(hsv, lower_gray, upper_gray)
  # Bitwise-AND mask and original image
  res = cv.bitwise_and(img, img, mask=mask)
  cv.imshow('original', img)
  cv.imshow('mask', mask)
  cv.imshow('res', res)
  k = cv.waitKey(5) & 0xFF
  if k == 27:
    break
cv.destroyAllWindows()

The following code can be used for static images

import cv2
import numpy as np
image_path ="trail.jpg"
img = cv2.imread(image_path)
# Convert BGR to HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# define range of gray color in HSV
lower_gray = np.array([0,0,0])
upper_gray = np.array([255,10,255])
# Threshold the HSV image to get only gray colors
mask = cv2.inRange(hsv, lower_gray, upper_gray)
# Bitwise-AND mask and original image
res = cv2.bitwise_and(img,img, mask= mask)
cv2.imwrite("output.png",res)
Answered By: RCvaram
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.