【问题标题】:Change colors that do not match specific color(s) to white using opencv使用opencv将与特定颜色不匹配的颜色更改为白色
【发布时间】:2022-01-02 04:17:31
【问题描述】:

我正在尝试使用 opencv 从图像中抓取特定元素。到目前为止,我所做的是减少了图像中的颜色数量,并得到了一个颜色字典及其计数。我现在要做的是将所有与此特定颜色不匹配的颜色替换为白色,以便我可以遍历图像并创建不同的图像,其中每个图像只有一个特定颜色的对象。

这是我到目前为止所做的:

def showOnlyOneColor(img, rgb_key):
    print("Getting only one color")
    rgb_key = rgb_key.split("-")
    r = int(rgb_key[0])
    g = int(rgb_key[1])
    b = int(rgb_key[2])

    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    rgb_low = np.array([r,g,b])
    rgb_high = np.array([r,g,b])
    mask = cv2.inRange(hsv, rgb_low, rgb_high)
    contours = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contours = contours[0] if len(contours) == 2 else contours[1]
    cv2.fillPoly(mask, contours, (255, 255, 255))
    result = cv2.bitwise_and(img,img,mask=mask)


    return result

第二次尝试:

def showOnlyOneColor(img, rgb_key):
    print("Getting only one color")
    rgb_key = rgb_key.split("-")
    r = int(rgb_key[0])
    g = int(rgb_key[1])
    b = int(rgb_key[2])

    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    rgb_low = np.array([r,g,b])
    rgb_high = np.array([r,g,b])
    mask = cv2.inRange(hsv, rgb_low, rgb_high)

    img[mask!=255] = (255, 255, 255)

    return img

这会在所有迭代中生成白色图像

这是我用来减少图像中颜色数量的方法:

def reduceNumberOfColors(img):
    div = 128
    return img // div * div + div // 2

最新尝试:

def showOnlyOneColor(img, rgb_key):
    print("Getting only one color")
    rgb_key = rgb_key.split("-")
    r = int(rgb_key[0])
    g = int(rgb_key[1])
    b = int(rgb_key[2])
    hsv_color = colorsys.rgb_to_hsv(r,g,b)

    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    rgb_low = np.array(hsv_color)
    rgb_high = np.array(hsv_color)
    mask = cv2.inRange(hsv, rgb_low, rgb_high)

    img[mask!=255] = (255, 255, 255)

    return img

其中一张图片显示了一些东西,其余的图片是白色的

我如何组织 rgb:

def getColorCount(img):
    color_dict = {}
    print("Getting color count")
    for i in tqdm(range(img.shape[0])):
        for j in range(img.shape[1]):
            color = img[i,j]
            r = color[0]
            g = color[1]
            b = color[2]
            rgb_askey = str(r)+"-"+str(g)+"-"+str(b)
            if rgb_askey not in color_dict.keys():
                color_dict[rgb_askey] = 1
            else:
                color_dict[rgb_askey] += 1
    return color_dict

【问题讨论】:

  • 为您想要保留的理想颜色设置阈值。然后使用蒙版将所有其他像素更改为白色。假设您的输入图像为image,掩码为mask,请执行以下操作:image[mask!=255] = (255, 255, 255)
  • @fmw42 如果我按照你刚才指定的方式实现蒙版,我只会得到一张白色图像
  • 你的面具是什么样子的?它是否显示一些白色和一些黑色?您的面罩是 1 通道还是 3 通道?如果是 3 个频道,则设为 1 个频道。
  • 请出示您输入的图片
  • 为什么要转换为 HSV,但使用 RGB 值?

标签: python numpy opencv


【解决方案1】:

这是在 Python/OpenCV 中执行所需操作的一种方法。注意颜色的顺序是 B、G、R。

输入:

import cv2
import numpy as np

# read image
img = cv2.imread('corn.jpg')

# do simple color reduction
imgcopy = img.copy()
div = 128
imgcopy = div * ( imgcopy // div ) + div // 2

# get list of unique colors
list_bgr_colors = np.unique(imgcopy.reshape(-1, imgcopy.shape[2]), axis=0)
print(list_bgr_colors)
print(list_bgr_colors[1])

# save reduced color image
cv2.imwrite("corn_reduced_colors.png", imgcopy)

# display reduced color image
cv2.imshow("reduced_colors", imgcopy)
cv2.waitKey(0)   

# loop over colors in list and change all non-specified colors to white
i = 1
for color in list_bgr_colors:

    # threshold on the specified color
    lower=np.array((color))
    upper=np.array((color))
    mask = cv2.inRange(imgcopy, lower, upper)

    # change all non-specified color to white
    result = imgcopy.copy()
    result[mask!=255] = (255, 255, 255)

    # save results
    cv2.imwrite("corn_color_{0}.png".format(i), result)

    # display result
    cv2.imshow("result", result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    # increment
    i += 1

减色列表:

[[ 64  64  64]
 [ 64  64 192]
 [ 64 192  64]
 [ 64 192 192]
 [192 192 192]]

减少彩色图像:

单独的彩色图像:

【讨论】:

    【解决方案2】:

    OpenCV 中的颜色顺序为 B、G、R。

    所以在 Python/OpenCV 中试试这个。

    def showOnlyOneColor(img, bgr_key):
        print("Getting only one color")
        bgr_key = bgr_key.split("-")
        b = int(bgr_key[0])
        g = int(bgr_key[1])
        r = int(bgr_key[2])
        bgr_low = np.array((b,g,r))
        bgr_high = np.array((b,g,r))
        mask = cv2.inRange(img, bgr_low, bgr_high)
    
        img[mask!=255] = (255, 255, 255)
    
        return img
    

    添加

    我认为您的问题在于您假设您在使用 colorsys 从 RGB 转换为 HSV 时具有 RGB 颜色。您的颜色实际上是 B、G、R。因此,要使用 colorsys,您需要先将图像转换为 RGB,或者在使用 colorsys 之前最好将您从 B、G、R 提取的颜色顺序反转为 R、G、B。

    您的字典颜色实际上是 B、G、R,而不是 R、G、B。所以在使用 colorsys 时反转它们或稍后反转它们。

    【讨论】:

    • 所以第一张图片不是全白的,它把白色图片中的物体显示为灰色。但是对于其他所有颜色,图像都是完全白色的。 bgr_low 和 bgr_high 也有错别字。它们需要是 np.array((b,g,r))
    • 是的,很抱歉有错别字。请在我的回答中查看我的补充。
    • 感谢您的输入,但我的图像仍未根据颜色过滤掉对象。第一张图像(它找到的第一种颜色)显示了一张白色图像,其中有灰色物体,但其余图像完全是白色的。
    • 张贴您的减少彩色图像。颜色看起来合适吗?
    【解决方案3】:

    这在 Python/OpenCV 中适用于我。请注意,OpenCV 颜色的顺序是 B、G、R。

    import cv2
    import numpy as np
    
    # read image
    img = cv2.imread('corn.jpg')
    
    # threshold on yellow color
    lower=(0,170,215)
    upper=(70,255,255)
    mask = cv2.inRange(img, lower, upper)
    
    # change all non-yellow to white
    result = img.copy()
    result[mask!=255] = (255, 255, 255)
    
    # save results
    cv2.imwrite('corn_yellow.jpg',result)
    
    # display result
    cv2.imshow("mask", mask)
    cv2.imshow("result", result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-11
      • 2012-05-14
      • 1970-01-01
      • 2015-12-21
      • 1970-01-01
      • 2023-02-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多