基于Python优化模特穿搭图中产品与背景颜色提取精度的技术问询
产品与背景颜色提取精度优化方案
问题背景
我需要从模特穿戴产品(如连衣裙)的图片中提取产品颜色与背景颜色。目前采用先遮罩皮肤和头发颜色,再用KMeans聚类提取主色调的方法,但结果精度不稳定——当产品颜色与背景、模特肤色/发色相近时,容易出现提取颜色偏浅或误提取背景色的问题。
当前实现代码
import cv2 import numpy as np from sklearn.cluster import KMeans import matplotlib.pyplot as plt def mask_human_colors(image): # Convert the image to HSV hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV) # Define a range for skin colors in HSV lower_skin = np.array([0, 20, 70], dtype=np.uint8) upper_skin = np.array([20, 255, 255], dtype=np.uint8) skin_mask = cv2.inRange(hsv, lower_skin, upper_skin) # Define a range for common hair colors in HSV (This is a rough estimate and might need adjustments) lower_hair = np.array([0, 0, 0], dtype=np.uint8) upper_hair = np.array([180, 255, 60], dtype=np.uint8) hair_mask = cv2.inRange(hsv, lower_hair, upper_hair) # Combine the skin and hair masks human_mask = cv2.bitwise_or(skin_mask, hair_mask) # Mask the image to remove human colors masked_image = cv2.bitwise_and(image, image, mask=~human_mask) return masked_image def extract_top_colors(image, k=2): pixels = image.reshape(-1, 3) pixels = pixels[np.any(pixels != [0, 0, 0], axis=1)] # Removing black pixels kmeans = KMeans(n_clusters=k, n_init=10) kmeans.fit(pixels) sorted_labels = np.argsort(np.bincount(kmeans.labels_))[::-1] colors = [kmeans.cluster_centers_[label].astype(int).tolist() for label in sorted_labels] return colors # Usage: image_path = '/content/white_dress.JPG' image = cv2.imread(image_path) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # Mask human colors masked_image = mask_human_colors(image) # Extract top colors dominant_colors = extract_top_colors(masked_image, k=2) print(f"1st Dominant Color (RGB): {dominant_colors[0]}") print(f"2nd Dominant Color (RGB): {dominant_colors[1]}") fig, ax = plt.subplots(1, 3, figsize=(20, 5)) ax[0].imshow(image) ax[0].set_title("Original Image") ax[1].imshow(masked_image) ax[1].set_title("Image after Masking Human Colors") ax[2].imshow([dominant_colors]) ax[2].set_title("Top 2 Dominant Colors") plt.tight_layout() plt.show()
示例与当前结果
- 示例图片:

- 当前提取结果:

改进建议与替代技术
1. 精准化人体区域遮罩
- 替换固定阈值为深度学习分割模型:使用MediaPipe Selfie Segmentation或Mask R-CNN,直接分割出完整的人体区域(含皮肤、头发、衣物外的身体部分),彻底排除人体像素干扰,无需手动调参。
- 多颜色空间联合皮肤检测:结合HSV+YCrCb颜色空间的皮肤阈值,覆盖不同人种、光照下的肤色,提升遮罩准确率。
2. 预处理优化
- 形态学去噪:对遮罩后的图像执行开运算(
cv2.morphologyEx(masked_image, cv2.MORPH_OPEN, kernel)),消除零散噪点像素,避免干扰聚类。 - 饱和度过滤:过滤掉饱和度低于阈值的像素(在HSV空间中筛选
s > 20的像素),减少背景阴影、灰度区域的影响。
3. 聚类策略升级
- 先定位产品ROI再聚类:用目标检测模型(如YOLOv8轻量版)定位连衣裙等产品区域,只在ROI范围内提取颜色,从根源上隔离背景。
- 改用密度聚类DBSCAN:无需预设聚类数,自动识别紧密的颜色簇,能有效区分相近但不同的颜色(如浅灰产品与白色背景)。
- Lab空间聚类:将图像转换到Lab颜色空间后再聚类,该空间更贴合人眼色彩感知,聚类结果更符合视觉主色调。
4. 后处理筛选
- 颜色特征过滤:计算每个聚类颜色的饱和度、亮度,结合产品属性(如纯色连衣裙饱和度不会过低)筛选有效颜色簇。
- 加权聚类:给面积较大的连通区域更高权重,让聚类结果更偏向占比大的真实产品/背景颜色。
内容的提问来源于stack exchange,提问作者sdave
相关产品推荐
相关产品推荐

