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

如何基于OpenCV提取的前两大轮廓裁剪对应图像区域?

解决OpenCV裁剪前2大轮廓内图像区域的问题

以下是修改后的完整代码,在原有检测并绘制前2大轮廓的基础上,新增了裁剪轮廓内图像区域的功能:

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

image_path = r'C:\Users\bear\Good\230903134657_HNN3TDMXY_1_Delam Analysis.jpg' 
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)

def count_contours(image, th):
    _, binary_image = cv2.threshold(image, th, 255, cv2.THRESH_BINARY)
    contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contour_areas = [(cv2.contourArea(contour), contour) for contour in contours]
    contour_areas.sort(key=lambda x: x[0], reverse=True)
    total_contours_count = len(contour_areas)
    print(total_contours_count)
    return total_contours_count

def draw_and_crop_contours(image, th):
    _, binary_image = cv2.threshold(image, th, 255, cv2.THRESH_BINARY)
    contours, _ = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    
    contour_areas = [(cv2.contourArea(contour), contour) for contour in contours]
    contour_areas.sort(key=lambda x: x[0], reverse=True)
    top_contours = [contour for _, contour in contour_areas[:2]]

    # 绘制轮廓并保存
    contour_image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
    cv2.drawContours(contour_image, top_contours, -1, (0, 255, 0), 2)
    cv2.imwrite('drawcountourtest.png', contour_image)
    
    # 裁剪每个轮廓内的区域
    for idx, contour in enumerate(top_contours):
        # 创建与原图像尺寸一致的空白掩码
        mask = np.zeros_like(image)
        # 用白色填充轮廓内部
        cv2.drawContours(mask, [contour], -1, 255, thickness=cv2.FILLED)
        # 提取轮廓内的图像(非轮廓区域为黑色)
        cropped_full = cv2.bitwise_and(image, image, mask=mask)
        # 获取轮廓的外接矩形,裁剪掉周围的黑色区域
        x, y, w, h = cv2.boundingRect(contour)
        cropped_roi = cropped_full[y:y+h, x:x+w]
        # 保存裁剪后的图像
        cv2.imwrite(f'cropped_contour_{idx+1}.png', cropped_roi)
    
    # 展示绘制结果和裁剪结果
    plt.figure(figsize=(12, 6))
    plt.subplot(1, 3, 1)
    plt.imshow(cv2.cvtColor(contour_image, cv2.COLOR_BGR2RGB))
    plt.title('绘制的轮廓')
    plt.axis('off')
    
    for idx in range(len(top_contours)):
        cropped_img = cv2.imread(f'cropped_contour_{idx+1}.png', cv2.IMREAD_GRAYSCALE)
        plt.subplot(1, 3, idx+2)
        plt.imshow(cropped_img, cmap='gray')
        plt.title(f'裁剪区域{idx+1}')
        plt.axis('off')
    plt.show()

test_count = count_contours(image, 130)
if test_count > 300:
    print(test_count)
    draw_and_crop_contours(image, 200)
else:
    print(test_count)
    draw_and_crop_contours(image, 130)

关键修改说明

  1. 功能整合:将原draw_contours函数重命名为draw_and_crop_contours,同时保留绘制功能并新增裁剪逻辑
  2. 掩码提取轮廓区域:为每个轮廓创建空白掩码,用cv2.FILLED参数填充轮廓内部,确保仅保留轮廓范围内的图像
  3. 过滤与裁剪:通过cv2.bitwise_and过滤掉轮廓外区域,再用cv2.boundingRect获取轮廓的最小包围矩形,裁剪掉结果中的黑色冗余区域
  4. 结果输出:每个裁剪后的区域单独保存为图片,同时在画布上直观展示绘制结果和裁剪效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 09:05:55