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

基于周长与面积的简单圆形Circularity计算异常问题排查

OpenCV计算圆形Circularity值异常问题排查

问题背景

Circularity用于衡量形状与圆形的相似度,标准公式为:

Sample Circularity = (4 * π * Sample Area) / (Sample Perimeter²)
完美圆形的该值为1,偏离圆形则小于1。

但使用Python+OpenCV计算自行生成的理想圆形时,结果始终为1.11;若将周长替换为len(cnt[0]),结果为0.81,均不符合预期。

用户的计算代码:

import cv2
import math

Gray_image = cv2.imread(Input_Path, cv2.IMREAD_GRAYSCALE)
cnt , her = cv2.findContours(Gray_image, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
Perimeter = cv2.arcLength(cnt[0], True)
Area = cv2.contourArea(cnt[0])

# 公式写反
Circularity = math.pow(Perimeter, 2) / (4 * math.pi * Area)
print(round(Circularity , 2))

测试用圆形生成代码:

import cv2
import numpy as np

Fill_Circle = np.zeros((1000, 1000, 3))
cv2.circle(Fill_Circle, (500, 500), 450, (255, 255, 255), -1)

cv2.imwrite(Path_to_Save, Fill_Circle)

问题原因

  1. 公式完全写反:用户代码中计算的是Perimeter²/(4π*Area),和标准定义的(4π*Area)/Perimeter²互为倒数。完美圆的理论值代入该错误公式会得到1,但实际因像素离散性,结果接近1的倒数(1.11)。
  2. 像素轮廓的离散性:OpenCV生成的圆形是像素级的近似多边形,并非数学上的完美圆。cv2.arcLength计算的是离散轮廓的近似周长,cv2.contourArea计算的是轮廓包围的像素面积,两者都存在微小误差。
  3. 错误的周长计算方式:用len(cnt[0])作为周长完全错误——轮廓点数量不等于实际周长,相邻轮廓点的距离可能是1(水平/垂直)或√2(对角线),直接用点数计算会严重低估实际周长。

解决方案

  1. 修正Circularity计算公式:改为符合标准定义的形式:
Circularity = (4 * math.pi * Area) / (Perimeter ** 2)
  1. 接受像素级误差:即使修正公式,结果也会接近1但并非严格1(比如约0.99),这是像素离散化导致的正常误差,属于可接受范围。
  2. 优化测试图像生成:直接生成单通道灰度图,避免通道转换的潜在问题:
import cv2
import numpy as np

# 直接生成单通道灰度图
Fill_Circle = np.zeros((1000, 1000), dtype=np.uint8)
cv2.circle(Fill_Circle, (500, 500), 450, 255, -1)

cv2.imwrite(Path_to_Save, Fill_Circle)

验证结果

修正公式后,运行代码得到的Circularity值会接近1(比如0.99),符合近似完美圆的预期结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:20:45