如何在 OpenCV(Python)中将灰度图像转换为 RGB?

新手上路,请多包涵

我正在学习使用 OpenCV 进行实时应用程序的图像处理。我对图像进行了一些阈值处理,并希望将轮廓标记为绿色,但它们没有以绿色显示,因为我的图像是黑白的。

在程序的早期,我使用 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 从 RGB 转换为灰度,但返回时我很困惑,函数 backtorgb = cv2.cvtColor(gray,cv2.CV_GRAY2RGB) 给出:

AttributeError:“模块”对象没有属性“CV_GRAY2RGB”。

下面的代码似乎没有以绿色绘制轮廓。这是因为它是灰度图像吗?如果是这样,我可以将灰度图像转换回 RGB 以显示绿色轮廓吗?

 import numpy as np
import cv2
import time

cap = cv2.VideoCapture(0)
while(cap.isOpened()):

    ret, frame = cap.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    ret, gb = cv2.threshold(gray,128,255,cv2.THRESH_BINARY)

    gb = cv2.bitwise_not(gb)

    contour,hier = cv2.findContours(gb,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)

    for cnt in contour:
        cv2.drawContours(gb,[cnt],0,255,-1)
    gray = cv2.bitwise_not(gb)

    cv2.drawContours(gray,contour,-1,(0,255,0),3)

    cv2.imshow('test', gray)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

原文由 user391339 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.2k
2 个回答

我正在将我的评论推广到一个答案:

简单的方法是:

您可以绘制原始“框架”本身,而不是使用灰色图像。

艰难的方式(您尝试实施的方法):

 backtorgb = cv2.cvtColor(gray,cv2.COLOR_GRAY2RGB)

是正确的语法。

原文由 Anoop K. Prabhu 发布,翻译遵循 CC BY-SA 4.0 许可协议

或者, cv2.merge() 可用于通过将同一层与新图像的蓝色、绿色和红色层合并在一起,将单通道二进制掩模层转换为三通道彩色图像。我们传入一个包含三个颜色通道层的列表 - 在本例中都是相同的 - 该函数返回具有这些颜色通道的单个图像。这有效地将形状为 (height, width, 1) 的灰度图像转换为 (height, width, 3)

解决你的问题

我对图像做了一些阈值处理,想用绿色标记轮廓,但它们没有显示为绿色,因为我的图像是黑白的。

这是因为您正试图在单个通道图像上显示三个通道。要解决这个问题,您可以简单地合并三个单通道

image = cv2.imread('image.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray_three = cv2.merge([gray,gray,gray])


例子

我们创建一个尺寸为 (200,200,3) 的彩色图像

在此处输入图像描述

 image = (np.random.standard_normal([200,200,3]) * 255).astype(np.uint8)

接下来我们将其转换为灰度并使用 cv2.merge() 创建另一个具有三个灰色通道的图像

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray_three = cv2.merge([gray,gray,gray])

我们现在在形状为 (200,200,1) 的单通道灰度图像(左)和形状为 (200,200,3) (右)的三通道灰度图像上绘制填充轮廓。左图展示了您在尝试在单个通道图像上显示三个通道时遇到的问题。将灰度图像合并为三个通道后,我们现在可以将颜色应用到图像上

在此处输入图像描述在此处输入图像描述

 contour = np.array([[10,10], [190, 10], [190, 80], [10, 80]])
cv2.fillPoly(gray, [contour], [36,255,12])
cv2.fillPoly(gray_three, [contour], [36,255,12])

完整代码

import cv2
import numpy as np

# Create random color image
image = (np.random.standard_normal([200,200,3]) * 255).astype(np.uint8)

# Convert to grayscale (1 channel)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Merge channels to create color image (3 channels)
gray_three = cv2.merge([gray,gray,gray])

# Fill a contour on both the single channel and three channel image
contour = np.array([[10,10], [190, 10], [190, 80], [10, 80]])
cv2.fillPoly(gray, [contour], [36,255,12])
cv2.fillPoly(gray_three, [contour], [36,255,12])

cv2.imshow('image', image)
cv2.imshow('gray', gray)
cv2.imshow('gray_three', gray_three)
cv2.waitKey()

原文由 nathancy 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题