圆卡尺,建坐标系,拟合圆,高斯滤波,双边滤波

圆卡尺,建坐标系,拟合圆

圆卡尺找圆部分

多方向径向卡尺函数,用于从图像中检测圆形物体的边缘点,基于灰度差分原理模拟工业视觉中的 "径向卡尺" 功能

  • 从指定圆心出发,在多个均匀分布的径向方向上,在设定的半径范围内检测符合条件的边缘点,最终将所有检测到的边缘点通过引用参数返回,可用于后续圆拟合(如计算圆心、半径)
cpp 复制代码
static void RadialWithGrayDiff2(
    const cv::Mat& image,                  // 1. 输入图像(必须为单通道灰度图,CV_8UC1)
    cv::Point2f center,                    // 2. 测量圆心(径向线的起点)
    pair<float, float> measureRange,       // 3. 半径范围(startRadius, endRadius),在该范围内检测边缘
    int startAngleDeg,                     // 4. 起始角度(度),如0°
    int endAngleDeg,                       // 5. 结束角度(度),如360°(全圆周)
    int angleStepDeg,                      // 6. 角度步长(度),控制径向线数量(如10°步长对应36条线)
    RadialCaliperDirection direction,      // 7. 测量方向:向内(从endRadius→startRadius)或向外(从startRadius→endRadius)
    Transition transition,                 // 8. 边缘类型:Positive(暗→亮)、Negative(亮→暗)、All(所有类型)
    int grayDiffThreshold,                 // 9. 灰度差阈值:判断边缘的最小灰度变化(如10表示灰度差≥10才视为边缘)
    int minConsecutive,                    // 10. 最小连续点数:需连续N个点满足灰度差条件才认定为有效边缘(抗噪声)
    vector<cv::Point2f>& edgePoints        // 11. 输出参数:存储检测到的边缘点(亚像素精度)
);

工作原理

  1. 生成径向测量线:
    以 center 为圆心,在 [startAngleDeg, endAngleDeg] 角度范围内,按 angleStepDeg 均匀生成多条径向线(如 0°、10°、20°...350°)。

2.沿径向线采样:

每条径向线上,在 measureRange 定义的半径范围内(从 startRadius 到 endRadius,方向由 direction 控制),逐点采样图像的灰度值。

3.灰度差分检测边缘:

对采样的灰度值序列计算相邻点的灰度差,当差值超过 grayDiffThreshold 且符合 transition 定义的边缘类型(如暗→亮),且连续 minConsecutive 个点满足条件时,判定为有效边缘,记录该位置的坐标

  1. 收集结果:

所有径向线上检测到的边缘点存入 edgePoints,用于后续圆拟合(如计算真实圆心和半径)

高斯滤波,双边滤波

  • 高斯滤波:

    属于低通滤波,结果就是图片会边糊

    原因:只考虑了距离,对跃变的区域会有损失

  • 双边滤波:

  • 属于边缘保护,它既考虑了距离又考虑了权重,结果是图片像磨皮处理

cpp 复制代码
void cv::bilateralFilter(
    InputArray src,        // 输入图像
    OutputArray dst,       // 输出图像(滤波后结果)
    int d,                 // 像素邻域直径
    double sigmaColor,     // 颜色空间标准差
    double sigmaSpace,     // 坐标空间标准差
    int borderType = BORDER_DEFAULT  // 边界填充方式(默认即可)
);

建立坐标系

有了2个圆的圆心后,以2点连线为x轴,中点为原点,2点的方向向量为x轴的方向

有了x轴的方向向量(x,y)后,顺时针旋转x轴变负,即(-x,y),逆时针即(x,-y)

有了x,y轴的方向后,就可以求我们要检测的点在新坐标系的坐标,即算该点在新坐标系上的投影

  1. 将测量点转换为相对原点的向量,求测量点距离坐标轴的距离,即测量点减原点坐标,得到

    double px = p3.x - origin.x;

    double py = p3.y - origin.y;

  2. 投影到新坐标系,即坐标乘相关坐标轴的单位向量

    float localX = static_cast(px * ux + py * uy);

    float localY = static_cast(px * vx + py * vy);

cpp 复制代码
cv::Point2f TransformToMidlineCoordinates(cv::Point2f p1, cv::Point2f p2, cv::Point2f p3){
    // 计算中点作为新原点
    cv::Point2f origin((p1.x + p2.x) / 2.0f, (p1.y + p2.y) / 2.0f);

    // 新x轴方向向量
    double dx = p2.x - p1.x;
    double dy = p2.y - p1.y;
    double length = sqrt(dx * dx + dy * dy);
    double ux = dx / length;
    double uy = dy / length;

    // 新y轴方向向量
    double vx = -uy;
    double vy = ux;

    // 将p3转换为相对原点的向量
    double px = p3.x - origin.x;
    double py = p3.y - origin.y;

    // 投影到新坐标系
    float localX = static_cast<float>(px * ux + py * uy);
    float localY = static_cast<float>(px * vx + py * vy);

    return cv::Point2f(localX, localY);
}
相关推荐
saoys26 分钟前
Opencv 学习笔记:图像掩膜操作(精准提取指定区域像素)
笔记·opencv·学习
MM_MS36 分钟前
Halcon变量控制类型、数据类型转换、字符串格式化、元组操作
开发语言·人工智能·深度学习·算法·目标检测·计算机视觉·视觉检测
旅途中的宽~2 小时前
《European Radiology》:2024血管瘤分割—基于MRI T1序列的分割算法
人工智能·计算机视觉·mri·sci一区top·血管瘤·t1
kisshuan123963 小时前
YOLO11-RepHGNetV2实现甘蔗田杂草与作物区域识别详解
人工智能·计算机视觉·目标跟踪
_codemonster4 小时前
高斯卷积的可加性定理
人工智能·计算机视觉
li星野5 小时前
OpenCV4X学习—核心模块Core
人工智能·opencv·学习
saoys7 小时前
Opencv 学习笔记:绘制动态随机直线(附实时展示)
笔记·opencv·学习
UnderTurrets8 小时前
A_Survey_on_3D_object_Affordance
pytorch·深度学习·计算机视觉·3d
山海青风8 小时前
图像识别零基础实战入门 1 计算机如何“看”一张图片
图像处理·python
yugi9878389 小时前
用于图像分类的EMAP:概念、实现与工具支持
人工智能·计算机视觉·分类