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

如何使用PIL模块替换图片指定色域(如整片天空)的像素颜色

解决方案

问题根源

你当前的代码仅对RGB值完全相等的像素做替换,而自然场景下的天空存在渐变、光影差异,存在大量和你提取的基准色接近但数值不完全一致的像素,因此只能替换部分区域。

优化方法1:RGB颜色容差匹配

通过计算当前像素和目标替换色的色彩欧氏距离,设置合理的容差阈值,只要距离小于阈值就判定为需要替换的天空像素:

from PIL import Image, ImageColor
import math

im = Image.open("iphone.jpg", "r")
to_be_replaced = ImageColor.getcolor("#5f86c9", "RGB")
newcolor = ImageColor.getcolor("#c9bb5f", "RGB")
# 容差阈值,可根据实际效果调整,数值越大匹配的颜色范围越广
threshold = 30

pix = im.load()
width, height = im.size
for w in range(width):
    for h in range(height):
        r, g, b = pix[(w, h)]
        # 计算RGB色彩欧氏距离
        color_diff = math.sqrt((r - to_be_replaced[0])**2 + (g - to_be_replaced[1])**2 + (b - to_be_replaced[2])**2)
        if color_diff < threshold:
            pix[w, h] = newcolor
im.save('test.png', 'PNG')

优化方法2:HSV色彩空间匹配(推荐)

RGB空间的色彩距离和人眼感知的颜色相似度匹配度较低,你可以将图片转为HSV(色相、饱和度、亮度)空间,只匹配天空蓝色对应的色相范围,不受亮度、饱和度差异影响,识别精度更高:

from PIL import Image, ImageColor
import colorsys

im = Image.open("iphone.jpg", "r")
newcolor = ImageColor.getcolor("#c9bb5f", "RGB")
# 天空蓝色对应的色相范围,可根据实际场景调整,蓝色色相一般在0.55~0.7区间(HSV色相取值0~1)
h_low, h_high = 0.55, 0.7
# 饱和度下限,避免把灰白色的云也误判为天空
s_low = 0.2

pix = im.load()
width, height = im.size
for w in range(width):
    for h in range(height):
        r, g, b = pix[(w, h)]
        # 转HSV,取值都归一化到0~1区间
        h_val, s_val, v_val = colorsys.rgb_to_hsv(r/255, g/255, b/255)
        if h_low <= h_val <= h_high and s_val >= s_low:
            pix[w, h] = newcolor
im.save('test.png', 'PNG')

参数调整说明

  • 容差类参数可以先给一个中间值,再根据生成的效果上下调整:如果还有天空没替换完就调大匹配范围,如果有非天空区域被误替换就调小匹配范围。
  • 如果图片中的天空有大量云朵,可以额外增加亮度判断逻辑,避免云朵被一同替换。

内容的提问来源于stack exchange,提问作者Asad Kareem

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 01:45:03