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

如何基于轮廓裁剪图像片段?OpenCV衣物提取遇阻求助

问题:OpenCV轮廓检测后精准裁剪衣物片段

我用OpenCV做轮廓检测,目的是提取人物衣物片段用于后续CNN分类,但现在卡在了轮廓检测后精准沿轮廓裁剪图像的环节。

相关处理步骤图像

  • 原始图像:wear.jpg
  • 去背景后图像:cutted_wear.png
  • 灰度模糊后图像:test.jpg
  • 边缘检测结果:edges.jpg
  • 形态学闭运算结果:closed.jpg
  • 轮廓绘制结果:test_final.jpg

现有实现代码

导入依赖

import cv2
import imutils
import numpy as np
from rembg import remove
from PIL import Image

去除背景

input_path = 'wear.jpg'
output_path = 'cutted_wear.png'
output = remove(Image.open(input_path))
output.save(output_path)

预处理与边缘检测

image = cv2.imread('cutted_wear.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (9, 9), 0)
cv2.imwrite('test.jpg', gray)

edges = cv2.Canny(gray, 25, 130)
cv2.imwrite('edges.jpg', edges)

形态学闭运算

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 10))
closed = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)
cv2.imwrite('closed.jpg', closed)

轮廓检测与绘制

cnts = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
total = 0
for c in cnts:
    p = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.00001 * p, True)
    if len(approx) > 0:
        cv2.drawContours(image, [approx], -1, (0, 255, ), 4)
        total +=1
print(total)
cv2.imwrite('test_final.jpg', image)

精准沿轮廓裁剪的解决方案

要实现沿轮廓精准裁剪,核心是利用轮廓生成掩码(Mask),再通过掩码与原始图像做位运算提取目标区域,具体步骤如下:

  1. 筛选面积最大的轮廓(对应衣物主体,过滤小干扰轮廓)
  2. 创建与原图尺寸一致的掩码,将目标轮廓填充为白色
  3. 通过位运算提取轮廓内的图像区域
  4. 获取轮廓外接矩形,裁剪出包含目标的最小边界区域

修改后的完整代码(新增裁剪逻辑)

在原有轮廓检测代码后添加裁剪相关逻辑:

import cv2
import imutils
import numpy as np
from rembg import remove
from PIL import Image

# 1. 去除背景
input_path = 'wear.jpg'
output_path = 'cutted_wear.png'
output = remove(Image.open(input_path))
output.save(output_path)

# 2. 预处理与边缘检测
image = cv2.imread('cutted_wear.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (9, 9), 0)
edges = cv2.Canny(gray, 25, 130)

# 3. 形态学闭运算
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 10))
closed = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)

# 4. 轮廓检测
cnts = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)

# 5. 精准裁剪核心逻辑
# 筛选面积最大的轮廓(衣物主体)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
target_cnt = cnts[0]

# 生成掩码
mask = np.zeros(image.shape[:2], dtype=np.uint8)
cv2.drawContours(mask, [target_cnt], -1, 255, thickness=cv2.FILLED)

# 位运算提取目标区域
cropped = cv2.bitwise_and(image, image, mask=mask)

# 裁剪到最小外接矩形
x, y, w, h = cv2.boundingRect(target_cnt)
cropped = cropped[y:y+h, x:x+w]

# 保存最终裁剪结果
cv2.imwrite('precision_cropped_wear.png', cropped)

关键细节说明

  • 轮廓筛选:通过cv2.contourArea排序取最大轮廓,可有效过滤背景残留或噪声带来的小轮廓
  • 掩码填充:使用cv2.FILLED确保轮廓内部完全被覆盖,避免裁剪出现漏边
  • 外接矩形裁剪:去除多余黑边,得到仅包含衣物的最小尺寸图像,更适配后续CNN模型输入

内容的提问来源于stack exchange,提问作者Денис Лютый

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 08:50:00