Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect black and gray from an image

I am trying to get a program to detect any hue of black (and some slight gray), but am currently having difficulties trying to find a good upper hue vector (the upper_hue variable) that would allow me extract most hues of black with out extracting other colors. It seems to work well with pictures like the black shoes or umbrella, but there it has problems with photos of roads where the brightness varies.

I am trying to find a good upper hue range that would allow the program to be robust against this, however it risks getting non-black colors.

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

What would be a good upper hue vector of values for black and gray. If that isn't the issue, what would be a good way to solve this?

Code:

import cv2
import numpy as np
import imutils

def color_seg(choice):
    if choice == 'blue':
        lower_hue = np.array([100,30,30])
        upper_hue = np.array([150,148,255])
    elif choice == 'white':
        lower_hue = np.array([0,0,0])
        upper_hue = np.array([0,0,255])
    elif choice == 'black':
        lower_hue = np.array([0,0,0])
        upper_hue = np.array([50,50,100])
    return lower_hue, upper_hue


# Take each frame
frame = cv2.imread('images/black0.jpg')
#frame = cv2.imread('images/road_1.jpg')

frame = imutils.resize(frame, height = 300)
chosen_color = 'black'


# Convert BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

# define range of a color in HSV
lower_hue, upper_hue = color_seg(chosen_color)


# Threshold the HSV image to get only blue colors
mask = cv2.inRange(hsv, lower_hue, upper_hue)


cv2.imshow('frame',frame)
cv2.imshow('mask',mask)

cv2.waitKey(0)
like image 425
user3377126 Avatar asked Oct 29 '15 01:10

user3377126


1 Answers

In hsv color space, it's pretty simple.

img = cv2.imread(img_path)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_gray = np.array([0, 5, 50], np.uint8)
upper_gray = np.array([179, 50, 255], np.uint8)
mask_gray = cv2.inRange(hsv, lower_gray, upper_gray)
img_res = cv2.bitwise_and(img, img, mask = mask_gray)

H is the hue, so the gray detector needs all the H values(0 -> 360°, represented by OpenCV in the integer range 0 to 179 to fit in 8 bits). S is the saturation (0 -> 255). The gray scales are between 0 and 50. If we don't want to keep the white values we can take 5 as minimal value. V is the brightness value (0=dark -> 255=bright).

like image 104
user11369072 Avatar answered Sep 22 '22 13:09

user11369072