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

OpenCV中反转背景色并保留前景目标的实现方法

两类白色像素的区分与目标提取方案

两类白色像素的本质差异非常清晰:和图像四周边界存在连通路径的白色属于背景区域,被黑色连通块完全包围、与图像边界无连通路径的白色属于黑色块内部的目标形状,无需深度学习模型,用基础的图像处理操作即可实现精准区分,具体流程如下:

  • 预处理:读取输入二值图像,统一像素值规则:白色像素值为255,黑色像素值为0,若原图像素规则相反,先做一次全局反色对齐标准。
  • 背景标记:以图像四条边上的所有白色像素作为种子点,执行漫水填充算法,遍历所有与种子点连通的白色像素,将这部分像素统一标记为背景。
  • 结果生成:创建一张与输入图尺寸完全一致的全黑画布,将所有未被标记为背景的原白色像素(即黑色块内部的形状)保留为白色绘制到画布上,即可得到纯黑背景下仅保留内部目标的输出图。

样例效果

  • 输入图像:
    带内部白色箭头的黑色连通块二值图
  • 输出图像:
    纯黑背景下仅保留白色箭头的结果图

参考实现代码(Python + OpenCV)

import cv2
import numpy as np

# 以灰度模式读取输入二值图
img = cv2.imread("input.png", cv2.IMREAD_GRAYSCALE)
h, w = img.shape

# 初始化漫水填充所需掩码,尺寸要求比原图宽高各多2个像素
fill_mask = np.zeros((h + 2, w + 2), dtype=np.uint8)

# 遍历图像四条边界,从所有边界上的白色像素开始漫水填充标记背景
for col in range(w):
    if img[0, col] == 255:
        cv2.floodFill(img, fill_mask, (col, 0), 128)
    if img[h-1, col] == 255:
        cv2.floodFill(img, fill_mask, (col, h-1), 128)
for row in range(h):
    if img[row, 0] == 255:
        cv2.floodFill(img, fill_mask, (0, row), 128)
    if img[row, w-1] == 255:
        cv2.floodFill(img, fill_mask, (w-1, row), 128)

# 生成结果:仅保留未被标记为背景的原白色像素,其余区域全部置黑
output = np.where(img == 255, 255, 0).astype(np.uint8)
cv2.imwrite("output.png", output)

特殊情况处理:如果黑色连通块存在和图像边缘相接的缺口,会导致漫水填充误把内部白色标记为背景,这种情况可以先给原图添加1-2个像素宽度的全黑外边框,再执行上述流程即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 12:51:22