Python openCV:当我使用cvtColor时,我得到一个未更改的图像

时间:2014-04-10 14:08:49

标签: python opencv numpy

我有一个图像为numpy数组,其形状(480,640)为灰度。

我想在图像上放置一个彩色遮罩,需要将图像设置为相同的形状,即(480,640,3)。

以下是我的尝试:

print str(img.shape) +' '+ str(type(img)) +' '+ str(img.dtype)
# prints: (480, 640) <type 'numpy.ndarray'> uint8

cv2.cvtColor(img, cv2.COLOR_GRAY2BGR, img, 3)
# this line seems to have no effect although I set it to 3 channels

print str(img.shape) +' '+ str(type(img)) +' '+ str(img.dtype)
# prints: (480, 640) <type 'numpy.ndarray'> uint8

rowCounter = 0
while rowCounter < img.shape[0]:
    columnCounter = 0
    while columnCounter < img.shape[1]:
        if img[rowCounter, columnCounter] == 0:
            img[rowCounter, columnCounter] = [0, 0, 0]
        else:
            img[rowCounter, columnCounter] = [255, 255, 255]
        columnCounter += 1
    rowCounter += 1

好的,代码在我要分配三个值([0,0,0])而不是单个值(0)的行上停止。错误消息如下所示:

ValueError: setting an array element with a sequence.

如何从单值更改为三值?有没有我找不到的功能?

谢谢!

1 个答案:

答案 0 :(得分:1)

主要是您需要将转换后的图像分配给新名称。

我不确定使用提供目标图像作为参数的c ++格式是否有效。我只是按照通常的python(cv2)方式分配给一个名字(同名很好)。

此外,您不需要分配频道数。转换类型可以解决这个问题。

#            cv2.cvtColor(img, cv2.COLOR_GRAY2BGR, img, 3)
color_mask = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

这能为您提供所需的图像吗?

顺便说一句,只要您使用numpy / opencv,您可能想要研究如何提高它的效率。如果你对整个图像/ numpy数组进行单独的像素访问,那就是红旗(对于python中的opencv)。

下面是显示转换的代码,但后来忽略了该转换并显示(据我所知)如何应用更高效的掩码。

复制 - 粘贴工作(和更高效)示例

import cv2
import numpy as np

# setup an original image (this will work for anyone without needing to load one)
shape = (480, 640)
img_gray = np.ndarray(shape, dtype=np.uint8)
img_gray.fill(127)
img_gray[0:40, 100:140] = 0  # some "off" values
cv2.imshow('original grayscale image', img_gray)
cv2.waitKey(0)  # press any key to continue

# convert the gray image to color (not used. just to demonstrate)
img_color = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2BGR)
cv2.imshow('color converted grayscale image (not used. just to show how to use cvtColor)', img_color)
cv2.waitKey(0)  # press any key to continue

# a simplified version of what your code did to apply a mask
# make a white image.
# and then set it to black wherever the original grayscale image is 0
img_color = np.ndarray(img_gray.shape + (3,), dtype=np.uint8)
img_color.fill(255)
cv2.imshow('base color image', img_color)
cv2.waitKey(0)  # press any key to continue

# this is not the fastest way, but I think it's more logical until you need more speed
# the fastest way specifically to black out parts of the image would
# be np.bitwise_and(...)
black_points = np.where(img_gray == 0)
print('found {} points to mask'.format(len(black_points[0])))
img_color[black_points] = (0, 0, 0)

# a more efficient and still straightforward method you could use:
img_color[img_gray==0] = (0, 0, 0)
cv2.imshow('masked color image', img_color)
cv2.waitKey(0)  # press any key to continue

# clean up explicitly
cv2.destroyAllWindows()