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

基于OpenCV提取产品外框并计算宽高的技术求助

提取带附加部件箱体的外框并计算宽高解决方案

问题背景

需要提取带附加部件的箱体外框,获取其高度h和宽度w,尝试阈值处理、Canny边缘检测及findContours方法后未得到理想结果。

现有尝试代码及结果

阈值处理

img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
ret, t = cv2.threshold(img, 40, 200, cv2.THRESH_BINARY_INV)

plt.imshow(t)

阈值处理图像

边缘检测

edge = cv2.Canny(t, 70, 150)
edge = cv2.dilate(edge, None, iterations = 1)
edge = cv2.erode(edge, None, iterations = 1)

边缘检测图像

原始产品图像:
原始产品图

针对性解决步骤

1. 预处理:过滤干扰区域

原始图像中箱体与附加部件、背景存在颜色差异,优先通过颜色分割缩小有效区域,减少干扰:

import cv2
import numpy as np

# 读取彩色图像并转HSV空间
img_color = cv2.imread(img_path)
hsv = cv2.cvtColor(img_color, cv2.COLOR_BGR2HSV)

# 设定深色箱体的HSV范围(可根据实际图像微调)
lower_hsv = np.array([0, 0, 0])
upper_hsv = np.array([180, 255, 80])
mask = cv2.inRange(hsv, lower_hsv, upper_hsv)

# 形态学闭运算消除小噪点,填补箱体内部缝隙
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7,7))
mask_clean = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=2)

2. 轮廓提取与最优外框筛选

在预处理后的mask上提取轮廓,通过多边形拟合筛选矩形外框:

# 提取最外层轮廓
contours, _ = cv2.findContours(mask_clean, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 按轮廓面积降序排序,优先处理大轮廓(箱体外框面积最大)
contours_sorted = sorted(contours, key=cv2.contourArea, reverse=True)

target_rect = None
for cnt in contours_sorted:
    # 计算轮廓周长,用多边形拟合近似形状
    perimeter = cv2.arcLength(cnt, True)
    approx = cv2.approxPolyDP(cnt, 0.02 * perimeter, True)
    # 筛选四边形(箱体外框为矩形)
    if len(approx) == 4:
        # 获取外接矩形的坐标、宽度、高度
        x, y, w, h = cv2.boundingRect(approx)
        # 验证宽高比例(根据实际箱体比例调整阈值,示例为0.6-1.8)
        if 0.6 < w/h < 1.8:
            target_rect = (x, y, w, h)
            # 在原图绘制外框
            cv2.rectangle(img_color, (x,y), (x+w, y+h), (0,255,0), 3)
            print(f"箱体宽度:{w} 像素,高度:{h} 像素")
            break

# 显示结果
cv2.imshow("Result", img_color)
cv2.waitKey(0)
cv2.destroyAllWindows()

3. 备选方案:霍夫直线拟合外框

若轮廓提取仍受干扰,可通过霍夫直线检测识别箱体四条边,计算交点得到外框:

# 对干净的mask做边缘检测
edges = cv2.Canny(mask_clean, 50, 150)
# 检测长直线(过滤短干扰线)
lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=120, minLineLength=250, maxLineGap=30)

# 分离水平和垂直直线
horizontal_lines = []
vertical_lines = []
for line in lines:
    x1, y1, x2, y2 = line[0]
    # 计算直线角度,区分水平/垂直
    angle = np.arctan2(y2-y1, x2-x1) * 180 / np.pi
    if abs(angle) < 10 or abs(angle) > 170:
        horizontal_lines.append(line[0])
    elif 80 < abs(angle) < 100:
        vertical_lines.append(line[0])

# 取最上下的水平直线、最左右的垂直直线,计算交点得到外框
# (需补充直线排序、交点计算逻辑,此处为核心思路)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 00:31:17