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

地板图像分割后阴影丢失,如何添加人工阴影?替换L通道无效

问题描述

对带有不同纹理的地板图像进行分割后,地板上物体的阴影被去除了,请问是否有方法添加人工阴影?
尝试替换L通道的值,但似乎没有效果,代码如下:

input = cv2.imread(INPUT_IMG)

input_lab = cv2.cvtColor(input , cv2.COLOR_BGR2LAB)
input_L, input_A, input_B=cv2.split(input_lab)

# 分割图像
seg_img = segment_img(INPUT_IMG, PATTERN, PROMPT)

seg_lab = cv2.cvtColor(seg_img , cv2.COLOR_BGR2LAB)
seg_L, seg_A, seg_B=cv2.split(seg_lab)


merge_L_channel = cv2.addWeighted(input_L, 1 - ALPHA, seg_L, ALPHA, 0)

merge_lab = cv2.merge([merge_L_channel, input_A, input_B])
output_img = cv2.cvtColor(merge_lab, cv2.COLOR_LAB2BGR)
解决方案

1. 提取原图像阴影蒙版并针对性叠加

直接全局加权L通道无效的核心原因是:你没有只针对原图像的阴影区域进行亮度融合,而是整体混合了全图的亮度通道,导致阴影特征被非阴影区域稀释。

具体步骤:

  • 提取阴影蒙版:从原输入图像中分离出阴影区域,生成二值蒙版(阴影区域为白色,其余为黑色):
# 转换为灰度图,提取阴影区域
gray_input = cv2.cvtColor(input, cv2.COLOR_BGR2GRAY)
# 自适应阈值分割阴影,可调整参数适配你的图像
shadow_mask = cv2.adaptiveThreshold(gray_input, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)
# 形态学处理消除噪点,优化蒙版
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
shadow_mask = cv2.morphologyEx(shadow_mask, cv2.MORPH_CLOSE, kernel)
  • 蒙版区域叠加阴影:仅在阴影蒙版覆盖的区域,将原图像的亮度信息与分割图的亮度融合:
# 分割图转LAB色彩空间
seg_lab = cv2.cvtColor(seg_img, cv2.COLOR_BGR2LAB)
seg_L, seg_A, seg_B = cv2.split(seg_lab)

# 仅在阴影区域混合原图像与分割图的L通道,权重可调整
seg_L[shadow_mask == 255] = cv2.addWeighted(
    seg_L[shadow_mask == 255], 0.3, 
    input_L[shadow_mask == 255], 0.7, 0
)

# 合并通道得到带阴影的结果
merged_lab = cv2.merge([seg_L, seg_A, seg_B])
output_with_shadow = cv2.cvtColor(merged_lab, cv2.COLOR_LAB2BGR)

2. 基于物体轮廓的人工阴影生成

如果原图像阴影提取效果不佳,可根据分割出的物体轮廓,手动生成符合光照逻辑的阴影:

  • 提取分割后物体的蒙版
  • 根据光照方向偏移蒙版生成阴影形状
  • 模糊并降低阴影亮度,叠加到分割图上

示例代码:

# 获取分割后物体的蒙版
seg_gray = cv2.cvtColor(seg_img, cv2.COLOR_BGR2GRAY)
obj_mask = cv2.threshold(seg_gray, 200, 255, cv2.THRESH_BINARY_INV)[1]

# 根据光照方向设置阴影偏移量(示例为右下方向)
dx, dy = 10, 10
shadow_offset = np.zeros_like(obj_mask)
shadow_offset[dy:, dx:] = obj_mask[:-dy, :-dx]

# 模糊阴影边缘并降低亮度
shadow = cv2.GaussianBlur(shadow_offset.astype(np.float32), (15, 15), 0)
shadow = (shadow * 0.5).astype(np.uint8)

# 将阴影叠加到分割图的灰度通道
seg_img_gray = cv2.cvtColor(seg_img, cv2.COLOR_BGR2GRAY)
seg_img_gray[shadow > 0] = cv2.addWeighted(
    seg_img_gray[shadow > 0], 1, 
    shadow[shadow > 0], 1, 0
)
output_with_shadow = cv2.cvtColor(seg_img_gray, cv2.COLOR_GRAY2BGR)

3. 优化原L通道混合逻辑

若想继续使用L通道混合思路,需限制混合范围为阴影区域,而非全局操作,这样既保留分割图的纹理,又还原阴影特征。


内容的提问来源于stack exchange,提问作者Akshay Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 23:25:30