opencv python 检测物体颜色是否为白色或黑色

1 投票
2 回答
5541 浏览
提问于 2025-04-18 00:18

我刚接触opencv,已经成功检测到物体并在周围画了一个区域,但我还不知道怎么判断这个物体是黑色还是白色。我找到了一些东西,但不确定这是否是正确的解决办法。这个函数应该返回真或假,表示它是黑色还是白色。有没有人有经验可以分享一下?

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)

2 个回答

1

如果你确定感兴趣的区域(ROI)要么是黑色,要么是白色,并且不担心会把东西搞错,那么你可以简单地计算这个区域里面所有像素的平均值,然后看看这个平均值是高于还是低于某个标准值。

在下面的代码中,当你使用更新的numpy方法设置好一个感兴趣的区域后,你可以把这个区域的图像像传递完整图像一样传递给方法。

复制粘贴示例

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
-1

我不知道这是不是正确的方法,但对我来说有效。

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

这个方法对我有效,但正如我所说的,我不确定这是不是对的做法。这个方法需要很多处理能力,所以我定义了一个小得多的区域(ROI)。目前的阈值是写死在代码里的...

撰写回答