使用OpenCV inRange()创建掩码报错:边界参数不匹配问题求助
解决K-Means图像分割中cv2.inRange的参数不匹配错误
错误原因
res是扁平化后的像素数组(shape为(总像素数, 3)),而cv2.inRange要求输入的源图像是二维+通道的格式(shape为(高度, 宽度, 通道数)),维度不匹配导致参数校验失败。- 虽然
center是符合通道数的数组,但输入源的维度不符合OpenCV对图像数据的预期结构。
解决方案
方法1:修复inRange的输入源
改用已经恢复原图像尺寸的result_image作为输入,它的shape和原始图像一致(HxWx3),符合cv2.inRange的要求:
import numpy as np import matplotlib.pyplot as plt import cv2 sample_image = cv2.imread('island.jpg') img = cv2.cvtColor(sample_image,cv2.COLOR_BGR2RGB) twoDimage = img.reshape((-1,3)) twoDimage = np.float32(twoDimage) criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0) K = 3 attempts=10 ret,label,centers=cv2.kmeans(twoDimage,K,None,criteria,attempts,cv2.KMEANS_RANDOM_CENTERS) centers = np.uint8(centers) res = centers[label.flatten()] result_image = res.reshape((img.shape)) k = 0 for center in centers: print(center) # [ 82 135 57] # 使用result_image替代res作为inRange的输入源 mask = cv2.inRange(result_image, center, center) # 可添加掩码处理逻辑,比如显示 # plt.imshow(mask, cmap='gray') # plt.show() k += 1
方法2:直接利用K-Means的label生成掩码(更高效准确)
K-Means已经输出了每个像素的聚类标签,直接用标签生成掩码可以避免颜色匹配的误差,计算效率也更高:
import numpy as np import matplotlib.pyplot as plt import cv2 sample_image = cv2.imread('island.jpg') img = cv2.cvtColor(sample_image,cv2.COLOR_BGR2RGB) twoDimage = img.reshape((-1,3)) twoDimage = np.float32(twoDimage) criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0) K = 3 attempts=10 ret,label,centers=cv2.kmeans(twoDimage,K,None,criteria,attempts,cv2.KMEANS_RANDOM_CENTERS) centers = np.uint8(centers) res = centers[label.flatten()] result_image = res.reshape((img.shape)) # 遍历每个聚类索引生成掩码 for cluster_idx in range(K): # 将label重塑为原图像尺寸,生成二值掩码 mask = (label.reshape(img.shape[:2]) == cluster_idx).astype(np.uint8) * 255 print(f"聚类中心: {centers[cluster_idx]}") # 可添加掩码处理逻辑 # plt.imshow(mask, cmap='gray') # plt.show()
说明
方法2的优势在于:K-Means的标签是像素聚类的直接结果,无需通过颜色值匹配,完全避免了uint8转换或颜色精度带来的匹配误差,同时计算步骤更少,性能更优。
内容的提问来源于stack exchange,提问作者Hamza Radouan
相关产品推荐
相关产品推荐

