You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用OpenCV或CSS/JS修改图像中沙发的目标颜色?已尝试蒙版与色调调整未成功

如何精准修改沙发颜色(保留背景)

我想修改下图中沙发的颜色,背景保持不变:
原始沙发图

目标颜色参考这张图:
目标颜色样图

我试过蒙版技术和OpenCV调色调,但都没法得到想要的颜色。有没有简便的定制方法?用CSS+JavaScript实现也可以,感谢帮助。

以下是我尝试的OpenCV代码:

import cv2
import numpy as np
from google.colab.patches import cv2_imshow
 
image = cv2.imread('/content/bluesofa.jpg')
cv2_imshow(image)
 
result = image.copy()
 
image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
 
# lower boundary Blue color range values; Hue (100 - 110)
lower1 = np.array([90, 100, 20])
upper1 = np.array([100, 255, 255])
 
# upper boundary Blue color range values; Hue (120 - 130)
lower2 = np.array([100,100,20])
upper2 = np.array([120,255,255])
 
lower_mask = cv2.inRange(image, lower1, upper1)
upper_mask = cv2.inRange(image, lower2, upper2)
 
full_mask = lower_mask + upper_mask;
 
result = cv2.bitwise_and(result, result, mask=full_mask)
 
cv2_imshow(full_mask)
cv2.imwrite('masked_object.jpg',result)

img= cv2.imread('/content/masked_object.jpg')

img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# extract the hue channel from the hsv image
hue = img_hsv[:,:,0]

# increment the hue values by 60(random number,could be any number)
hue = hue  + 60


# if pixel values become > 180, subtract 180 
cond_h = hue[:, :] > 180
hue[cond_h] = hue[cond_h] - 180

# assign the modified hue channel to hsv image

img_hsv[:,:,0] = hue


im = cv2.cvtColor(img_hsv, cv2.COLOR_HSV2BGR)

result = cv2.bitwise_or(original_img,im)

cv2_imshow(result)

一、OpenCV优化方案

你的问题核心是蒙版精度不足和单纯偏移色相无法匹配目标色的饱和度、亮度特征。可以通过提取目标色的HSV参数,精准替换沙发区域的颜色同时保留原纹理:

  1. 提取目标色样图的平均HSV值
  2. 优化蒙版范围,用形态学操作去除噪点、填充沙发空隙
  3. 替换沙发区域的色相、饱和度,保留原亮度通道以维持纹理

优化后代码:

import cv2
import numpy as np
from google.colab.patches import cv2_imshow

# 读取原始图和目标色样图
original_img = cv2.imread('/content/bluesofa.jpg')
target_color_img = cv2.imread('/content/vduYV.jpg')

# 提取目标颜色的平均HSV值
target_hsv = cv2.cvtColor(target_color_img, cv2.COLOR_BGR2HSV)
target_h, target_s, target_v = np.mean(target_hsv, axis=(0,1)).astype(np.int32)

# 处理原始图
hsv_img = cv2.cvtColor(original_img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv_img)

# 生成精准沙发蒙版:扩大蓝色范围+形态学去噪
lower_blue = np.array([80, 50, 50])
upper_blue = np.array([130, 255, 255])
mask = cv2.inRange(hsv_img, lower_blue, upper_blue)
# 形态学操作修复蒙版
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)

# 替换沙发区域的色相和饱和度,保留原亮度
h[mask>0] = target_h
s[mask>0] = target_s

# 合并通道并输出结果
new_hsv = cv2.merge([h, s, v])
result = cv2.cvtColor(new_hsv, cv2.COLOR_HSV2BGR)

cv2_imshow(result)
cv2.imwrite('colored_sofa.jpg', result)

二、前端CSS+JavaScript方案

如果需要在网页实时修改沙发颜色,可以用Canvas结合颜色识别实现:

<!DOCTYPE html>
<html>
<head>
    <style>
        canvas {border:1px solid #ccc;}
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    <button onclick="changeSofaColor('#8B4513')">改为目标棕色</button>

    <script>
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        let originalImg;

        // 加载图片
        const img = new Image();
        img.crossOrigin = 'anonymous';
        img.src = 'https://i.sstatic.net/qCycV.jpg';
        img.onload = function() {
            canvas.width = img.width;
            canvas.height = img.height;
            ctx.drawImage(img, 0, 0);
            originalImg = ctx.getImageData(0, 0, canvas.width, canvas.height);
        };

        function changeSofaColor(targetHex) {
            if (!originalImg) return;
            const data = originalImg.data;
            // 十六进制转RGB
            const r = parseInt(targetHex.slice(1,3),16);
            const g = parseInt(targetHex.slice(3,5),16);
            const b = parseInt(targetHex.slice(5,7),16);

            // 遍历像素识别蓝色沙发并替换颜色
            for (let i=0; i<data.length; i+=4) {
                const pixelR = data[i];
                const pixelG = data[i+1];
                const pixelB = data[i+2];
                // 蓝色沙发判断条件(可根据实际调整)
                if (pixelB > pixelR && pixelB > pixelG && pixelB > 80) {
                    // 保留原亮度,适配目标色
                    const brightness = 0.299*pixelR + 0.587*pixelG + 0.114*pixelB;
                    const factor = brightness / (0.299*r + 0.587*g + 0.114*b);
                    data[i] = Math.min(r * factor, 255);
                    data[i+1] = Math.min(g * factor, 255);
                    data[i+2] = Math.min(b * factor, 255);
                }
            }
            ctx.putImageData(originalImg, 0, 0);
        }
    </script>
</body>
</html>

内容的提问来源于stack exchange,提问作者Priya KS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 03:40:32