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

如何用OpenCV将带透明背景的Matplotlib图表叠加到图像上?

问题:Matplotlib图表叠加OpenCV图像时的背景残留及高效处理需求

我尝试使用OpenCV将Matplotlib图表叠加到图像的指定位置,但叠加层始终带有黑色或白色背景,导致叠加后的背景图像比原图偏暗或偏亮。由于需要对视频的每一帧执行此操作,因此解决方案必须具备高效性。


方法一:将图表放在透明图像后叠加到背景

import cv2
import numpy as np
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.figure import Figure

# 保存带透明背景的图表为PNG
fig = Figure(figsize=(5, 4), dpi=100)
canvas = FigureCanvasAgg(fig)

ax = fig.add_subplot(111)
ax.plot([1, 2, 3])

canvas.draw()
fig.savefig("Test", transparent=True)

graph = cv2.imread('Test.png')

# 为图表添加alpha通道并设为0
graph = cv2.cvtColor(graph, cv2.COLOR_RGB2RGBA)
graph[:, :, 3] = 0

# 读取背景图像
background = cv2.imread('hill-966202_960_720.jpg')
background = cv2.cvtColor(background, cv2.COLOR_RGB2RGBA)

# 创建与背景尺寸相同的透明图像
background_y, background_x, background_channel = background.shape
transparent_image = np.full((background_y, background_x, background_channel), [255, 255, 255, 0])

# 将图表放置到透明图像的指定位置
y, x = 80, 123
overlay_y, overlay_x, _ = graph.shape
transparent_image[y:(y + overlay_y), x:(x + overlay_x)] = graph[:, :, :]

transparent_image = transparent_image.astype(np.uint8)
added_image = cv2.addWeighted(transparent_image, 0.4, background, 0.6, 0)

cv2.imshow("TEST", added_image)
cv2.waitKey(0)

结果:叠加层带有白色背景,与原始背景图像对比差异明显

  • 叠加后效果:[白色背景残留的叠加图像]
  • 原始背景:[原始背景图像]

方法二:将图表叠加到背景副本后与原图混合

import cv2
import numpy as np
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.figure import Figure

# 保存带透明背景的图表为PNG
fig = Figure(figsize=(5, 4), dpi=100)
canvas = FigureCanvasAgg(fig)

ax = fig.add_subplot(111)
ax.plot([1, 2, 3])

canvas.draw()
fig.savefig("Test", transparent=True)

graph = cv2.imread('Test.png')

# 为图表添加alpha通道并设为0
graph = cv2.cvtColor(graph, cv2.COLOR_RGB2RGBA)
graph[:, :, 3] = 0

# 读取背景图像
background = cv2.imread('hill-966202_960_720.jpg')
background = cv2.cvtColor(background, cv2.COLOR_RGB2RGBA)
background_copy = background.copy()

# 将图表放置到背景副本的指定位置
y, x = 80, 123
overlay_y, overlay_x, _ = graph.shape
background_copy[y:(y + overlay_y), x:(x + overlay_x)] = graph[:, :, :]

added_image = cv2.addWeighted(background_copy, 0.4, background, 0.6, 0)

cv2.imshow("TEST", added_image)
cv2.waitKey(0)

结果:图表周围仍带有背景残留

  • 叠加后效果:[图表周围背景残留的图像]

方法三:逐像素去除图表背景

import cv2
import numpy
import numpy as np
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.figure import Figure
import time

fig = Figure(figsize=(5, 4), dpi=100)
canvas = FigureCanvasAgg(fig)

ax = fig.add_subplot(111)
ax.plot([1, 2, 3])

canvas.draw()
buf = canvas.buffer_rgba()

graph_as_array = np.asarray(buf)

background = cv2.imread('hill-966202_960_720.jpg')
background = cv2.cvtColor(background, cv2.COLOR_RGB2RGBA)
background_copy = background.copy()

y, x = 80, 123

overlay_y, overlay_x, _ = graph_as_array.shape

background_copy[y:(y + overlay_y), x:(x + overlay_x)] = graph_as_array[:, :, :]

for height in range(y, y + overlay_y):
    for width in range(x, x + overlay_x):
        pixel = background_copy[height][width]
        if pixel[0] == 255 and pixel[1] == 255 and pixel[2] == 255:
            background_copy[height][width] = background[height][width]

cv2.imshow("TEST", background_copy)
cv2.waitKey(0)

结果:叠加效果良好,但逐像素遍历速度过慢,无法满足视频逐帧处理的需求

  • 叠加后效果:[无背景残留的图像]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 01:28:12