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

OpenCV计算两个最大轮廓质心并绘制最小外接圆方法

OpenCV 轮廓质心计算与最小外接圆绘制实现

你已经筛选出两个面积最大的轮廓后,直接调用OpenCV内置接口即可完成需求,不需要额外实现复杂计算:

  • 质心计算:通过cv2.moments()获取轮廓矩,按矩的物理意义换算坐标
  • 最小外接圆:通过cv2.minEnclosingCircle()直接获取外接圆的圆心和半径

核心逻辑说明

质心计算

对单个轮廓调用cv2.moments(轮廓对象)会返回包含所有矩值的字典,其中:

  • m00 对应轮廓的零阶矩,值等于轮廓面积
  • m10/m00 为质心横坐标
  • m01/m00 为质心纵坐标

计算前需要判断m00不为0,避免轮廓面积极端为0时触发除以0的运行错误。拿到坐标后用cv2.circle()绘制蓝色实心标记点即可。

最小外接圆绘制

对单个轮廓调用cv2.minEnclosingCircle(轮廓对象)会直接返回两个结果:外接圆圆心坐标(浮点型)、外接圆半径(浮点型),将值转为整数后,用cv2.circle()绘制红色空心圆即可。


修改后完整代码

已移除原代码里冗余的循环内函数定义、无用导入,加入了质心和外接圆绘制逻辑:

import cv2
import numpy as np

# 初始化摄像头
cap = cv2.VideoCapture(0)
if not cap.isOpened():
    print("Error opening video stream or file")

# 视频流循环
while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    # 转HSV空间做颜色阈值筛选
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
    red_lower = np.array([16, 132, 0])
    red_upper = np.array([20, 236, 255])
    mask = cv2.inRange(hsv, red_lower, red_upper)
    res = cv2.bitwise_and(frame, frame, mask=mask)
    thresh = cv2.cvtColor(res, cv2.COLOR_BGR2GRAY)

    # 查找轮廓
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    print(f'Number of contours found = {len(contours)}')

    # 轮廓数足够时取面积最大的两个处理
    if len(contours) >= 2:
        sorted_contours = sorted(contours, key=cv2.contourArea, reverse=True)
        top2_contours = [sorted_contours[0], sorted_contours[1]]

        for cnt in top2_contours:
            # 1. 计算轮廓矩绘制质心(蓝色点)
            M = cv2.moments(cnt)
            if M["m00"] != 0:
                cX = int(M["m10"] / M["m00"])
                cY = int(M["m01"] / M["m00"])
                cv2.circle(frame, (cX, cY), 5, (255, 0, 0), -1)

            # 2. 计算并绘制最小外接圆(红色圈)
            (circle_x, circle_y), radius = cv2.minEnclosingCircle(cnt)
            circle_center = (int(circle_x), int(circle_y))
            cv2.circle(frame, circle_center, int(radius), (0, 0, 255), 2)

    # 画面展示
    cv2.imshow('Frame', frame)
    cv2.imshow('mask', mask)
    cv2.imshow('gray', thresh)

    # 按q退出
    if cv2.waitKey(25) & 0xFF == ord('q'):
        break

# 资源释放
cap.release()
cv2.destroyAllWindows()

效果说明

运行后输出的Frame窗口中:

  • 蓝色实心点为两个激光点的轮廓质心
  • 红色空心圈为对应轮廓的最小外接圆
  • 标记逻辑和参考示例完全匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 05:18:21