我有一个图像为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.
如何从单值更改为三值?有没有我找不到的功能?
谢谢!
答案 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()