简体   繁体   中英

opencv python detecting color of object is white or black

I'm new to opencv, I've managed to detect the object and place a ROI around it but I can't managed it so detect if the object is black or white. I've found something i think but i don't know if this is the right solution. The function should return True of False if it's black or white. Anyone experience with this?

def filter_color(img):
        hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
        lower_black = np.array([0,0,0])
        upper_black = np.array([350,55,100])
        black = cv2.inRange(hsv, lower_black, upper_black)

If you are certain that the ROI is going to be basically black or white and not worried about misidentifying something, then you should be able to just average the pixels in the ROI and check if it is above or below some threshold.

In the code below, after you set an ROI using the newer numpy method , you can pass the roi/image into the method as if you were passing a full image.

Copy-Paste Sample

import cv2
import numpy as np


def is_b_or_w(image, black_max_bgr=(40, 40, 40)):
    # use this if you want to check channels are all basically equal
    # I split this up into small steps to find out where your error is coming from
    mean_bgr_float = np.mean(image, axis=(0,1))
    mean_bgr_rounded = np.round(mean_bgr_float)
    mean_bgr = mean_bgr_rounded.astype(np.uint8)
    # use this if you just want a simple threshold for simple grayscale
    # or if you want to use an HSV (V) measurement as in your example
    mean_intensity = int(round(np.mean(image)))
    return 'black' if np.all(mean_bgr < black_max_bgr) else 'white'

# make a test image for ROIs
shape = (10, 10, 3)  # 10x10 BGR image
im_blackleft_white_right = np.ndarray(shape, dtype=np.uint8)
im_blackleft_white_right[:, 0:4] = 10
im_blackleft_white_right[:, 5:9] = 255

roi_darkgray = im_blackleft_white_right[:,0:4]
roi_white = im_blackleft_white_right[:,5:9]


# test them with ROI
print 'dark gray image identified as: {}'.format(is_b_or_w(roi_darkgray))
print 'white image identified as: {}'.format(is_b_or_w(roi_white))

# output
# dark gray image identified as: black
# white image identified as: white

I don't know if this is the right approach but it worked for me.

black = [0,0,0]
Thres = 50
h,w = img.shape[:2]
black = 0
not_black = 0
for y in range(h):
    for x in range(w):
        pixel = img[y][x]
        d = math.sqrt((pixel[0]-0)**2+(pixel[1]-0)**2+(pixel[2]-0)**2)
        if d<Thres:
            black = black + 1
        else:
            not_black = not_black +1

This one worked for me but like i said, don't know if this is the right approach. It's ask a lot of processing power therefore i defined a ROI which is much smaller. The Thres is currently hard-coded...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM