简体   繁体   English

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

[英]How does one convert a grayscale image to RGB in OpenCV (Python)?

I'm learning image processing using OpenCV for a realtime application.我正在学习使用 OpenCV 进行实时应用程序的图像处理。 I did some thresholding on an image and want to label the contours in green, but they aren't showing up in green because my image is in black and white.我对图像做了一些阈值处理,想用绿色标记轮廓,但它们没有显示为绿色,因为我的图像是黑白的。

Early in the program I used gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) to convert from RGB to grayscale, but to go back I'm confused, and the function backtorgb = cv2.cvtColor(gray,cv2.CV_GRAY2RGB) is giving:在程序早期我使用gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)从 RGB 转换为灰度,但回去我很困惑,函数backtorgb = cv2.cvtColor(gray,cv2.CV_GRAY2RGB)是给予:

AttributeError: 'module' object has no attribute 'CV_GRAY2RGB'. AttributeError: 'module' 对象没有属性 'CV_GRAY2RGB'。

The code below does not appear to be drawing contours in green.下面的代码似乎没有以绿色绘制轮廓。 Is this because it's a grayscale image?这是因为它是灰度图像吗? If so, can I convert the grayscale image back to RGB to visualize the contours in green?如果是这样,我可以将灰度图像转换回 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()

I am promoting my comment to an answer:我正在将我的评论推广到一个答案:

The easy way is:简单的方法是:

You could draw in the original 'frame' itself instead of using gray image.您可以绘制原始“框架”本身,而不是使用灰色图像。

The hard way (method you were trying to implement):艰难的方式(您试图实施的方法):

backtorgb = cv2.cvtColor(gray,cv2.COLOR_GRAY2RGB) is the correct syntax. backtorgb = cv2.cvtColor(gray,cv2.COLOR_GRAY2RGB)是正确的语法。

Alternatively, cv2.merge() can be used to turn a single channel binary mask layer into a three channel color image by merging the same layer together as the blue, green, and red layers of the new image.或者,可以使用cv2.merge()通过将与新图像的蓝色、绿色和红色图层相同的图层合并在一起,将单通道二值蒙版图层转换为三通道彩色图像。 We pass in a list of the three color channel layers - all the same in this case - and the function returns a single image with those color channels.我们传入三个颜色通道层的列表 - 在这种情况下都是相同的 - 并且该函数返回具有这些颜色通道的单个图像。 This effectively transforms a grayscale image of shape (height, width, 1) into (height, width, 3)这有效地将形状为(height, width, 1)的灰度图像转换为(height, width, 3)

To address your problem解决您的问题

I did some thresholding on an image and want to label the contours in green, but they aren't showing up in green because my image is in black and white.我对图像做了一些阈值处理,想用绿色标记轮廓,但它们没有显示为绿色,因为我的图像是黑白的。

This is because you're trying to display three channels on a single channel image.这是因为您试图在单个通道图像上显示三个通道。 To fix this, you can simply merge the three single channels要解决此问题,您可以简单地合并三个单通道

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

Example例子

We create a color image with dimensions (200,200,3)我们创建一个尺寸为(200,200,3)的彩色图像

在此处输入图片说明

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

Next we convert it to grayscale and create another image using cv2.merge() with three gray channels接下来我们将其转换为灰度并使用cv2.merge()与三个灰度通道创建另一个图像

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

We now draw a filled contour onto the single channel grayscale image (left) with shape (200,200,1) and the three channel grayscale image with shape (200,200,3) (right).现在我们绘制填充轮廓到单通道灰度级图像(左)与形状(200,200,1)并与形状三个信道的灰度图像(200,200,3)右)。 The left image showcases the problem you're experiencing since you're trying to display three channels on a single channel image.左图展示了您遇到的问题,因为您试图在单个通道图像上显示三个通道。 After merging the grayscale image into three channels, we can now apply color onto the 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])

Full code完整代码

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()

Try this:尝试这个:

import cv2
import cv

color_img = cv2.cvtColor(gray_img, cv.CV_GRAY2RGB)

I discovered, while using opencv, that some of the constants are defined in the cv2 module, and other in the cv module.我发现,在使用 opencv 时,一些常量是在 cv2 模块中定义的,而其他常量是在 cv 模块中定义的。

One you convert your image to gray-scale you cannot got back.一个你将你的图像转换为灰度,你无法恢复。 You have gone from three channel to one, when you try to go back all three numbers will be the same.你已经从三个通道变成了一个通道,当你尝试返回时,所有三个数字都将是相同的。 So the short answer is no you cannot go back.所以简短的回答是不,你不能回去。 The reason your backtorgb function this throwing that error is because it needs to be in the format:您的 backtorgb 函数抛出该错误的原因是它需要采用以下格式:

CvtColor(input, output, CV_GRAY2BGR)

OpenCV use BGR not RGB, so if you fix the ordering it should work, though your image will still be gray. OpenCV 使用 BGR 而不是 RGB,因此如果您修复顺序,它应该可以工作,尽管您的图像仍然是灰色的。

rgb_image = cv2.cvtColor(binary_image, cv2.COLOR_GRAY2RGB) * 255

There can be a case when you think that your image is a gray-scale one, but in reality, it is a binary image.可能有一种情况,您认为您的图像是灰度图像,但实际上它是二值图像。 In such a case you have an array of 0's and 1's where 1 is white and 0 is black (for example).在这种情况下,您有一个由 0 和 1 组成的数组,其中 1 是白色,0 是黑色(例如)。

In RGB space, pixel values are between 0 and 255. Therefore it is necessary to multiply by 255 your converted image.在 RGB 空间中,像素值介于 0 和 255 之间。因此需要转换后的图像乘以 255 If not, you will receive an almost blank image, because pixels with value 0 are almost the same as the ones with value 1, when the values of pixels varies between <0, 255>如果不是,您将收到一个几乎空白的图像,因为当像素值在 <0, 255> 之间变化时,值为 0 的像素与值为 1 的像素几乎相同

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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