如何根据图像RGB值获取对应像素的(h,w)坐标?
如何根据RGB值/范围获取图像像素的(h,w)坐标?
我们可以通过像素的(h,w)坐标获取RGB值,比如用OpenCV读取图像后,img[50,50]能得到对应像素的RGB值[80 80 80]。但现在需要反向操作:根据指定RGB值(如[80 80 80])或RGB范围([70,70,70]至[98,98,98])获取对应像素的(h,w)坐标。
尝试过的无效方法
方法1:使用
np.where()
代码:import cv2 import numpy as np img = cv2.imread('Hi.PNG') lst = np.where((img > [70, 70, 70]) & (img < [98, 98, 98])) print(lst)返回结果:
(array([111, 111, 111, ..., 242, 242, 242], dtype=int64), array([123, 123, 124, ..., 135, 135, 135], dtype=int64), array([0, 2, 0, ..., 0, 1, 2], dtype=int64))问题:返回的是三个数组,分别对应高度、宽度、通道索引,并非直接的(h,w)坐标数组,数据拆解后杂乱。
方法2:使用双重循环
代码:pos = [] for i in range(0, len(img)): for j in range(0, len(img[0])): if img[i, j] > [70, 70, 70] and img[i, j] < [98, 98, 98]: pos.append((i,j))问题:抛出错误
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all(),因为直接对数组做比较会返回布尔数组,无法直接判断真假,需要指定all()或any()。
有效解决方案
1. 精确匹配指定RGB值
要找到所有RGB值完全等于目标值的像素坐标,需确保三个通道数值都匹配:
import cv2 import numpy as np img = cv2.imread('Hi.PNG') # 注意:OpenCV默认读取图像为BGR顺序,若需匹配RGB需先转换: # img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) target_rgb = [80, 80, 80] # 生成二维布尔掩码,标记每个像素是否满足所有通道匹配 mask = np.all(img == target_rgb, axis=2) # 获取满足条件的(h,w)坐标,结果为N×2的数组 coords = np.argwhere(mask) print(coords)
2. 匹配RGB范围(区间匹配)
要找到所有RGB值在指定区间内的像素,需确保三个通道数值都落在对应区间:
import cv2 import numpy as np img = cv2.imread('Hi.PNG') # 同样注意BGR/RGB通道顺序问题 lower_bound = np.array([70, 70, 70]) upper_bound = np.array([98, 98, 98]) # 生成二维布尔掩码,标记每个像素是否所有通道都在区间内 mask = np.all((img >= lower_bound) & (img <= upper_bound), axis=2) # 获取满足条件的(h,w)坐标 coords = np.argwhere(mask) print(coords)
问题根源说明
np.where()原方法问题:未通过axis=2合并通道维度的判断,导致返回的是每个通道单独满足条件的坐标,包含通道索引。先通过np.all(..., axis=2)生成二维掩码,再用np.argwhere()直接提取(h,w)坐标更高效直观。- 双重循环问题:直接对像素数组做比较会返回长度为3的布尔数组,无法用
and直接判断。即使改成np.all((img[i,j] >= lower_bound) & (img[i,j] <= upper_bound))能运行,双重循环的效率也远低于numpy的向量化操作,不推荐使用。
内容的提问来源于stack exchange,提问作者Joon
相关产品推荐
相关产品推荐

