【问题标题】:Obtaining pixel values within CV2 contours获取 CV2 轮廓内的像素值
【发布时间】:2016-04-16 16:54:57
【问题描述】:

我正在尝试获取轮廓内的像素值。我已经跟进了类似问题的答案,但我的结果不正确。

此代码块查找图像的轮廓,然后遍历它们以找到包含最大区域的轮廓。我添加了结尾 if 语句,如果它是在白天,它会尝试获取代码的 RGB 值。原始图像(视频帧)与轮廓一起传递给我编写的函数(grab_rgb)

    thresh = cv2.dilate(thresh, None, iterations=2)
    (_, cnts, _) = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    # look for motion
    motion_found = False
    biggest_area = 0

    # examine the contours, looking for the largest one
    for c in cnts:
        (x, y, w, h) = cv2.boundingRect(c)
        # get an approximate area of the contour
        found_area = w * h
        # find the largest bounding rectangle
        if (found_area > MIN_AREA) and (found_area > biggest_area):
            biggest_area = found_area
            motion_found = True

            if not is_nighttime():
                rgb = grab_rgb(image, c)
            else:
               rgb = 'nighttime'

这是我写的函数:

def grab_rgb(image, c):
    pixels = []

    # TODO: Convert to real code
    # Detect pixel values (RGB)
    mask = np.zeros_like(image)
    cv2.drawContours(mask, c, -1, color=255, thickness=-1)

    points = np.where(mask == 255)

    for point in points:
        pixel = (image[point[1], point[0]])
        pixel = pixel.tolist()
        pixels.append(pixel)

    pixels = [tuple(l) for l in pixels]
    car_color = (pixels[1])

    r = car_color[0]
    g = car_color[1]
    b = car_color[2]

    pixel_string = '{0},{1},{2}'.format(r, g, b)

    return pixel_string

代码运行,但只返回三个 RGB 值,只有第二个值包含任何有意义的值(值 0 和 2 是 [0,0,0],[0,0,0]。肯定应该超过轮廓内的三个像素,所以我不确定我哪里出错了。

编辑:我意识到在变量中包含实际存储的内容可能会有所帮助。

面具:

[[[  0   0   0]
  [  0   0   0]
  [  0   0   0]
  ...,
  [  0   0   0]
  [  0   0   0]
  [  0   0   0]]

 [[  0   0   0]
  [255   0   0]
  [  0   0   0]
  ...,
  [  0   0   0]
  [  0   0   0]
  [  0   0   0]]

 [[  0   0   0]
  [  0   0   0]
  [  0   0   0]
  ...,
  [  0   0   0]
  [  0   0   0]
  [  0   0   0]]

 ...,
 [[  0   0   0]
  [  0   0   0]
  [  0   0   0]
  ...,
  [  0   0   0]
  [  0   0   0]
  [  0   0   0]]

 [[  0   0   0]
  [  0   0   0]
  [  0   0   0]
  ...,
  [  0   0   0]
  [  0   0   0]
  [  0   0   0]]

 [[  0   0   0]
  [  0   0   0]
  [  0   0   0]
  ...,
  [  0   0   0]
  [  0   0   0]
  [  0   0   0]]]

点数:

(array([ 1,  1,  3,  5, 10, 11, 11, 12, 12, 13, 13, 14, 14], dtype=int32), array([ 1, 22, 22, 24, 24, 21, 23, 16, 20,  9, 15,  1,  8], dtype=int32), array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], dtype=int32))

像素:

[0, 0, 0] [136, 89, 96] [0, 0, 0]

像素:

[(0, 0, 0), (136, 89, 96), (0, 0, 0)]

汽车颜色:

(136, 89, 96)

【问题讨论】:

    标签: python opencv image-processing


    【解决方案1】:

    您要求代码返回的似乎是传递给grab_rgb的每个轮廓中的点的像素值列表(此处称为“像素”)中第二个点的RGB值,

    car_color = (像素[1])

    r = car_color[0]
    
    g = car_color[1]
    
    b = car_color[2]
    

    所以输出应该意味着您的图像至少有三个检测到的轮廓满足您的区域约束,并且轮廓点列表中第二个点的 RGB 值就是您提到的([0,0,0],[ x,y,z] 和 [0,0,0])。

    【讨论】:

    • 我在原帖中添加了更多信息 - 但出于某种原因,np.where 只返回三分。我假设我提供的面具有问题。有趣的是,第一个和最后一个像素值都是 0,0,0。我从像素中提取了第二个像素值,因为它是唯一一个值发生变化的像素值,我试图看看它是否以某种方式在做我想要的——但事实并非如此。所以我就是想不通为什么 np.where 只返回三分。
    • 不要认为它应该有所作为,但现在你的面具是 (width x height x 3) 当你想要的时候 (width x height x 1) 。不要做 zeros_like 因为它给你的面具你的“图像”的形状,它有三个通道,你不需要三个通道。而是使用 zeros() 初始化零掩码,给它图像的宽度和高度你自己。此外,您的 points 数组似乎有 11-12 个点,这就是 np.where 返回的内容。
    • 修复掩码,并检查此链接以了解如何迭代 np.where 的输出。 stackoverflow.com/questions/21887138/…
    猜你喜欢
    • 2013-04-02
    • 1970-01-01
    • 2012-07-04
    • 2019-07-19
    • 2020-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多