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

如何用OpenCV Python精准识别并完整填充图像孔洞

基于轮廓完整填充图像黑色孔洞的代码修改方案

我需要识别图像中的黑色孔洞并基于邻域像素颜色填充。目前通过HSV阈值分割检测黑色区域轮廓,但现有代码只能填充轮廓的外接矩形区域,无法完整填充孔洞,期望实现完整填充轮廓内部的效果。

现有代码:

img=cv2.imread(r'image.png')
img_copy = img.copy()
black_MIN = np.array([0, 0, 0],np.uint8)
black_MAX = np.array([179, 50, 100],np.uint8)

hsv_img = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)

frame_threshed = cv2.inRange(hsv_img, black_MIN, black_MAX)
contours,hierarchy = cv2.findContours(frame_threshed, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
    area = cv2.contourArea(c)  # Area of first contour

    perimeter = cv2.arcLength(c, True)  
    approx = cv2.approxPolyDP(c, 0.04 * perimeter, True)
    (x,y,w,h) = cv2.boundingRect(c)
    roi=img[y:y+h,x:x+w]
    cv2.rectangle(img_copy,(x,y),(x+w,y+h),(0,252,213),-1)
plt.imshow(img_copy[:,:,::-1])

解决方案

问题核心是你用cv2.rectangle填充了轮廓的外接矩形,而非轮廓实际区域。只需替换为轮廓内部填充,同时可加入噪声过滤优化效果:

修改后的固定颜色填充代码

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread(r'image.png')
img_copy = img.copy()
black_MIN = np.array([0, 0, 0], np.uint8)
black_MAX = np.array([179, 50, 100], np.uint8)

hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
frame_threshed = cv2.inRange(hsv_img, black_MIN, black_MAX)

contours, hierarchy = cv2.findContours(frame_threshed, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

for idx, c in enumerate(contours):
    area = cv2.contourArea(c)
    # 过滤过小的噪声轮廓,阈值根据实际图像调整
    if area < 50:
        continue
    
    # 直接填充轮廓内部,-1表示填充模式
    cv2.drawContours(img_copy, [c], 0, (0,252,213), -1)

plt.imshow(img_copy[:,:,::-1])
plt.show()

关键修改点

  • 用cv2.drawContours替代cv2.rectangle,通过参数-1实现轮廓内部填充
  • 增加面积过滤,避免填充细碎噪声点
  • 可选:若需区分外轮廓和内部孔洞,可通过层级判断:if hierarchy[0][idx][3] != -1(表示当前轮廓是父轮廓的子轮廓,即孔洞),只填充这类轮廓

基于邻域像素的智能填充(更贴合需求)

如果需要用孔洞周围的像素颜色自动填充,可使用cv2.inpaint函数:

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread(r'image.png')
black_MIN = np.array([0, 0, 0], np.uint8)
black_MAX = np.array([179, 50, 100], np.uint8)

hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_img, black_MIN, black_MAX)

# 膨胀掩码,确保覆盖孔洞边缘细节
mask = cv2.dilate(mask, np.ones((3,3), np.uint8), iterations=1)
# 基于邻域像素修复孔洞,INPAINT_TELEA算法效果更自然
inpainted_img = cv2.inpaint(img, mask, 3, cv2.INPAINT_TELEA)

plt.imshow(inpainted_img[:,:,::-1])
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 10:35:35