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

如何通过轮廓准确获取米粒的长度与宽度?已用OpenCV相关函数未果

解决米粒长度/宽度测量问题的实用方案

你当前用cv2.boundingRect()得到的是轴对齐的外接矩形,对倾斜的米粒来说会包含大量空白区域,自然测不准。换成最小外接矩形或者计算轮廓最远点距离,就能拿到更贴合米粒实际尺寸的数据,具体步骤如下:

核心改进思路

  1. 替换轴对齐矩形为旋转最小外接矩形
    cv2.minAreaRect()会生成贴合物体轮廓的旋转矩形,返回值((x_center,y_center), (width,height), angle)里的width和height就是米粒的实际宽高(取较大值为长度,较小值为宽度)。

  2. 先优化轮廓质量
    Canny边缘检测容易出现断裂或噪声轮廓,建议先做这些预处理:

  • 把图像转灰度后用OTSU阈值分割生成二值图,比Canny更易得到闭合轮廓
  • 用形态学闭运算(cv2.morphologyEx())填补轮廓小缺口,去除小噪声点

代码示例

import cv2
import numpy as np

# 读取图像(假设已读入img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# OTSU二值化
_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
# 形态学闭运算填补缺口
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)
# 查找轮廓
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 遍历有效轮廓(过滤小噪声)
for cnt in contours:
    area = cv2.contourArea(cnt)
    if area < 100:  # 根据实际米粒大小调整阈值
        continue
    # 计算最小外接矩形
    rect = cv2.minAreaRect(cnt)
    (center, (w, h), angle) = rect
    # 确定长度和宽度(取大的为长度)
    length = max(w, h)
    width = min(w, h)
    print(f"米粒长度:{length:.2f}px,宽度:{width:.2f}px")
    
    # 可选:画出旋转矩形(可视化验证)
    box = cv2.boxPoints(rect)
    box = np.int0(box)
    cv2.drawContours(img, [box], 0, (0,255,0), 2)

cv2.imshow("Result", img)
cv2.waitKey(0)

额外补充

如果需要亚像素级精度,可以先对轮廓做cv2.approxPolyDP()近似,或者用cv2.cornerSubPix()优化轮廓点坐标后再计算尺寸。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 02:25:14