慕的地10843
更新现在,您的实际预期处理已经变得更加清晰,OpenCV功能可能会更好地为您服务。喜欢这个:inRange()#!/usr/local/bin/python3 import cv2 as cv import numpy as np # Load the image and convert to HLS image = cv.imread("image.jpg") hls = cv.cvtColor(image,cv.COLOR_BGR2HLS) # Define lower and uppper limits for each component lo = np.array([50,0,0]) hi = np.array([70,255,255]) # Mask image to only select filtered pixels mask = cv.inRange(hls,lo,hi) # Change image to white where we found our colour image[mask>0]=(255,255,255) cv.imwrite("result.png",image) 因此,如果我们使用此图像:我们选择 50-70 范围内的色调,并将它们设置为白色:如果你去这里一个颜色转换器,你可以看到“绿色”是Hue=120,但是OpenCV将Hue除以2,这样360度就变成了180,并且仍然适合uint8。因此,我们在代码中的60表示在线颜色转换器中的120。OpenCV用于uint8图像的范围是:色相 0..180亮度 0..255饱和度 0..255正如我之前所说,您应该养成在调试器中查看数据类型,形状和范围的习惯。要查看 、和最大色相、亮度和饱和度,请使用:shapedtypeprint(hls.dtype, hls.shape) print(hls[...,0].max())print(hls[...,1].max())print(hls[...,2].max())原始答案有几种方法可以做到这一点。性能最高的可能是OpenCV函数,StackOverflow上有很多关于此的答案。cv2.inRange()这是一个Numpy的方式。如果您阅读注释并查看打印的值,则可以了解如何将逻辑 AND 与逻辑 OR 等组合在一起,以及如何解决特定通道问题。#!/usr/bin/env python3from random import randint, seed import numpy as np# Generate a repeatable random HSV imagenp.random.seed(42)h, w = 4, 5HSV = np.random.randint(1,100,(h,w,3),dtype=np.uint8)print('Initial HSV\n',HSV)# Create mask of all pixels with acceptable Hue, i.e. H > 50HueOK = HSV[...,0] > 50print('HueOK\n',HueOK)# Create mask of all pixels with acceptable Saturation, i.e. S > 20 AND S < 80SatOK = np.logical_and(HSV[...,1]>20, HSV[...,1]<80)print('SatOK\n',SatOK)# Create mask of all pixels with acceptable value, i.e. V < 20 OR V > 60ValOK = np.logical_or(HSV[...,2]<20, HSV[...,2]>60)print('ValOK\n',ValOK)# Combine maskscombinedMask = HueOK & SatOK & ValOKprint('Combined\n',combinedMask)# Now, if you just want to set the masked pixels to 255HSV[combinedMask] = 255print('Result1\n',HSV)# Or, if you want to set the masked pixels to one value and the others to another valueHSV = np.where(combinedMask,255,0)print('Result2\n',HSV)示例输出Initial HSV [[[93 98 96] [52 62 76] [93 4 99] [15 22 47] [60 72 85]] [[26 72 61] [47 66 26] [21 45 76] [25 87 40] [25 35 83]] [[66 40 87] [24 26 75] [18 95 15] [75 86 18] [88 57 62]] [[94 86 45] [99 26 19] [37 24 63] [69 54 3] [33 33 39]]]HueOK [[ True True True False True] [False False False False False] [ True False False True True] [ True True False True False]]SatOK [[False True False True True] [ True True True False True] [ True True False False True] [False True True True True]]ValOK [[ True True True False True] [ True False True False True] [ True True True True True] [False True True True False]]Combined [[False True False False True] [False False False False False] [ True False False False True] [False True False True False]]Result1 [[[ 93 98 96] [255 255 255] [ 93 4 99] [ 15 22 47] [255 255 255]] [[ 26 72 61] [ 47 66 26] [ 21 45 76] [ 25 87 40] [ 25 35 83]] [[255 255 255] [ 24 26 75] [ 18 95 15] [ 75 86 18] [255 255 255]] [[ 94 86 45] [255 255 255] [ 37 24 63] [255 255 255] [ 33 33 39]]]Result2 [[ 0 255 0 0 255] [ 0 0 0 0 0] [255 0 0 0 255] [ 0 255 0 255 0]]备注:1) 您还可以使用否定访问蒙版未选择的像素:# All unmasked pixels become 3HSV[~combinedMask] = 32)省略号()只是一个快捷方式,意思是“我没有打扰列出的所有其他维度”,所以与...HSV[...,1]HSV[:,:,1]3)如果您不喜欢为Hue和饱和度写作,则可以拆分通道HSV[...,0]HSV[...,1]H, S, V = cv2.split(HSV)然后,您可以使用 代替 .完成后,如果要将通道重新组合回 3 通道映像,可以执行以下操作:HHSV[...,0]HSV = cv2.merge((H,S,V))或HSV = np.dstack((H,S,V))