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

使用Python-OpenCV去除图像白色背景污渍的问题求助

OpenCV背景纯白处理问题求助

我是OpenCV新手,正在完成大学作业,需要把原本带污渍的白色背景图像处理成完全纯白背景,保留完整物体。我写了代码,但运行后只得到物体的黑色边界框,达不到预期效果。

原图:原图
结果图:结果图

我的代码:

import cv2
import numpy as np

image = cv2.imread('./MCP_tmp_picam_final.jpg')
original = image.copy()

gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
thresh = cv2.adaptiveThreshold(blur,225,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,21,2)

# Draw boundingboxes onto a mask
mask = np.zeros(original.shape[:2], dtype=np.uint8)
cnts,_ = cv2.findContours(thresh, cv2.RETR_TREE,
                                cv2.CHAIN_APPROX_SIMPLE)

for i, c in enumerate(cnts):
    area = cv2.contourArea(c)
    # Ignore contours that are too small or too large
    if area < 1000 or 100000 < area: #100000
        continue
    rect = cv2.minAreaRect(c)
    #print(rect)
    box = cv2.boxPoints(rect)
    box = np.int0(box)
    cv2.drawContours(mask, [box], 0, (255,255,255), 2)
    cv2.drawContours(image,[box],0,(0,0,255),2)

# Bitwise-and for result
result = cv2.bitwise_and(original, original, mask=mask)
result[mask==0] = (255,255,255)

cv2.imshow('result', result)
cv2.imshow('mask', mask)
cv2.imshow('image', image)
cv2.waitKey()

问题原因与解决方法

问题出在mask的绘制逻辑:你调用cv2.drawContours时使用了厚度参数2,这只会在mask上画出轮廓的边框,内部区域仍为黑色。后续的bitwise_and操作只会保留边框区域,其余区域被设为白色,因此最终结果只有黑色边框。

修改关键:

将绘制mask时的厚度参数从2改为-1,-1表示填充整个轮廓内部,让mask对应物体的区域全部变为白色。

修改后的完整代码:

import cv2
import numpy as np

image = cv2.imread('./MCP_tmp_picam_final.jpg')
original = image.copy()

gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
thresh = cv2.adaptiveThreshold(blur,225,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,21,2)

# Draw boundingboxes onto a mask
mask = np.zeros(original.shape[:2], dtype=np.uint8)
cnts,_ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

for i, c in enumerate(cnts):
    area = cv2.contourArea(c)
    # Ignore contours that are too small or too large
    if area < 1000 or 100000 < area:
        continue
    rect = cv2.minAreaRect(c)
    box = cv2.boxPoints(rect)
    box = np.int0(box)
    # 修改厚度为-1,填充轮廓内部
    cv2.drawContours(mask, [box], 0, 255, -1)
    cv2.drawContours(image,[box],0,(0,0,255),2)

# Bitwise-and for result
result = cv2.bitwise_and(original, original, mask=mask)
result[mask==0] = (255,255,255)

cv2.imshow('result', result)
cv2.imshow('mask', mask)
cv2.imshow('image', image)
cv2.waitKey()

额外提示:

如果目标物体没有被正确选中,可以调整轮廓筛选的面积范围(area < 1000和100000 < area),确保只保留需要的物体轮廓。


内容的提问来源于stack exchange,提问作者Mohamed Lamine Duchme Minani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:43:24