我使用 RGBA色彩空间在python中读取了一个图像。图像的大小 640 x 960 ,并存储到名为 img_array 的数组中。现在,数组中的每个元素都包含[R,G,B,A],例如[21,34,53,255]。我想通过将像素转换为黑色[0,0,0,255]来过滤我的图像像素,这不符合下面的条件。
R > 95 and G > 40 and B > 20 and R > G and R > B and | R - G | > 15 and A > 15
我将如何在python中执行此操作?我所知道的是使用cv2.inrange()将像素设置为黑色,这不在下边界和上边界内。以下是我的示例代码:
#import the necessary packages
import imutils
import numpy as np
import argparse
import cv2
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image",help = "path to the image file")
args = vars(ap.parse_args())
#read image with alpha channel
img_array = cv2.imread(args["image"], -1)
rgba_lower_bound = np.array([0, 59, 59,2], dtype = "uint8")
rgba_upper_bound = np.array([20, 255, 255,255], dtype = "uint8")
skinMask = cv2.inRange(img_array, rgb_lower_bound, rgb_upper_bound)
skin = cv2.bitwise_and(img_array, img_array, mask = skinMask)
cv2.imshow("images", skin)
请帮我解决这个问题。
答案 0 :(得分:4)
假设R, G, B, A
都是具有相同形状的numpy数组,由以下内容创建:
R, G, B, A = cv2.split(img_array)
使用相同的条件简单地创建一个掩码;由于他们是numpy
数组,请使用&
代替and
:
mask = (R > 95) & (G > 40) & (B > 20) & (R > G) & (R > B) & (abs(R - G) > 15) & (A > 15)
然后将不的所有内容设置为满足条件为黑色:
img_array[~mask] = [0, 0, 0, 255]
请注意,mask
将是双频道,并将广播到img_array
中的所有频道。另请注意~
反转一个numpy布尔数组,所以这是mask
False
所在的索引,这就是你想要的。
关于透明度的更多信息:如果alpha通道为0,则表示完全透明,如果它为255(对于无符号8位图像),则表示不透明。如果您希望图像在那些位置透明而不是黑色,您可以反转蒙版,将其转换为uint8
数组,然后将其合并回一个图像,如这样:
R, G, B, A = cv2.split(img_array)
mask = (R > 95) & (G > 40) & (B > 20) & (R > G) & (R > B) & (abs(R - G) > 15) & (A > 15)
new_A = 255*(~mask).astype(np.uint8)
new_img_array = cv2.merge([R, G, B, new_A])
这样,如果你想保留它,你就不会丢失R,G,B中的任何颜色信息。
答案 1 :(得分:1)
你可以这样做:
def set_to_black(T, image):
# grab the image dimensions
h = image.shape[0]
w = image.shape[1]
# loop over the image, pixel by pixel
for y in range(0, h):
for x in range(0, w):
if (conditional) # I couldn't be bothered to write it all out
# Set the pixel to black
image[y, x] = [0, 0, 0, 255]
# return the thresholded image
return image