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

如何判断木棍二进制掩码是否笔直并计算弯曲曲率?

木棍二进制掩码的笔直判断与曲率计算方案

一、预处理:提取木棍中心骨架

直接取掩码中心点误差较大,优先采用**骨架提取(细化)**获取木棍的单像素中心轴线,这是后续分析的核心基础:

  • 用OpenCV的cv2.ximgproc.thinning()函数对二进制掩码做细化处理,确保输出为单像素宽度的骨架(需提前保证掩码是二值化状态:前景为白色,背景为黑色)。

二、判断木棍是否笔直

基于提取的骨架点集,通过最小二乘法拟合直线+点线距离统计判断笔直度:

  1. 提取骨架上所有非零像素的坐标,得到N×2格式的点集points。
  2. 用最小二乘法拟合直线,得到直线方程参数。
  3. 计算每个骨架点到拟合直线的垂直距离,取所有距离的平均值avg_dist。
  4. 设定阈值(可参考木棍平均宽度的1/10),若avg_dist小于阈值则判定为笔直,否则为弯曲。

三、弯曲时的曲率计算方案

针对弯曲木棍,可通过两种方式量化弯曲程度:

方法1:局部曲率统计

  • 对骨架点集做滑动窗口处理(比如取连续5个点),用三点法计算局部曲率:对于点P_i-1, P_i, P_i+1,计算三点构成圆的半径r,局部曲率为1/r。
  • 取所有局部曲率的平均值或最大值作为整体曲率值,数值越大表示弯曲程度越高。

方法2:全局圆弧拟合

  • 对整个骨架点集拟合最优圆弧,得到圆弧半径R,整体曲率即为1/R。可通过最小二乘法拟合圆弧参数,或用点集外接圆做近似计算。

示例代码片段(Python+OpenCV)

import cv2
import numpy as np
from sklearn.linear_model import LinearRegression

# 读取二值化掩码
mask = cv2.imread('stick_mask.png', 0)
# 提取骨架
skeleton = cv2.ximgproc.thinning(mask)
# 获取骨架点坐标
points = np.column_stack(np.where(skeleton > 0))

if len(points) > 2:
    # 最小二乘法拟合直线
    X = points[:, 0].reshape(-1, 1)
    y = points[:, 1]
    model = LinearRegression().fit(X, y)
    y_pred = model.predict(X)
    # 计算点到直线的平均距离
    distances = np.abs(y - y_pred) / np.sqrt(model.coef_[0]**2 + 1)
    avg_dist = np.mean(distances)
    
    # 设定判断阈值(示例值,可根据实际木棍尺寸调整)
    threshold = 2
    if avg_dist < threshold:
        print("木棍是笔直的")
    else:
        print("木棍是弯曲的,正在计算曲率...")
        # 三点法计算平均曲率
        curvature_list = []
        for i in range(1, len(points)-1):
            p_prev = points[i-1]
            p_curr = points[i]
            p_next = points[i+1]
            # 计算三点外接圆半径
            a = np.linalg.norm(p_curr - p_prev)
            b = np.linalg.norm(p_next - p_curr)
            c = np.linalg.norm(p_next - p_prev)
            s = (a + b + c) / 2
            area = np.sqrt(s*(s-a)*(s-b)*(s-c))
            if area < 1e-6:
                continue
            r = (a*b*c)/(4*area)
            curvature = 1/r if r !=0 else 0
            curvature_list.append(curvature)
        avg_curvature = np.mean(curvature_list)
        print(f"平均曲率值:{avg_curvature:.6f}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 04:53:14