基于Opencv的法兰盘螺纹孔位置确定(一)

该博客介绍了如何利用OpenCV进行法兰盘螺纹孔的位置确定,通过Canny算子边缘检测、闭运算、轮廓跟踪等步骤,结合最小二乘法拟合实现精确定位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

汽车工业领域的法兰盘分布有螺纹孔,实际生产过程中,螺纹孔因加工问题未安上螺纹,本项目旨在对法兰盘螺纹孔定位并检测。

请添加图片描述
请添加图片描述
定位圆环ROI过程如下所示

一、Canny算子边缘检测得到边缘图

    cv::Mat cannyImg;
    int low_Val = 100, high_Val = 2 * low_Val;    //进行Canny边缘检测的高阈值与低阈值
    cv::Canny(image0, cannyImg, low_Val, high_Val, 3);    //Canny边缘检测参数,默认apertureSize = 3

请添加图片描述

二、闭运算

    Mat closeSmallImg;
    cv::Mat elementSmall = cv::getStructuringElement(cv::MORPH_ELLIPSE,
        cv::Size(3, 3)
    );
    //不用开运算会把轮廓去掉
    //不用9*9,9*9得到的螺纹孔更多,但背景的圆不易被剔除掉,后续思考改进
    cv::morphologyEx(cannyImg, closeSmallImg, cv::MORPH_CLOSE, elementSmall);
    //将小空隙填满,将临近的轮廓连接

请添加图片描述

三、轮廓跟踪寻找轮廓

    vector<cv::Vec4i> hierarchy;
    vector<vector<cv::Point> > contours;
    cv::findContours(closeSmallImg, contours, hierarchy,
        cv::RETR_TREE, cv::CHAIN_APPROX_NONE, cv::Point(0, 0));

    Mat drawImg = Mat::zeros(cannyImg.size(), CV_8UC3);
    cv::RNG rng(12345);
    for (int i = 0; i < contours.size(); i++)
    {
   
        cv::Scalar color = cv::Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
        cv::drawContours(drawImg, contours, i, color, 2, 8, hierarchy, 0, cv::Point());
    }
    cv::imshow("s3 Contours Image", drawImg);

请添加图片描述

四、预设置参数

    //轮廓长度与轮廓间距离设置
    int minCDis = 50;    //筛选轮廓时,允许的最小轮廓间距离
    int minCircleLen = 65;    //筛选轮廓时定位圆孔的最小轮廓长度
    int maxCircleLen = 75;    //筛选轮廓时定位圆孔的最大轮廓长度
    //圆环半径设置
    float RH_mm = 140;    //检测圆盘圆孔的半径 单位:毫米
    float R0_mm = 115;   //检测圆盘的内径    单位:毫米
    float R1_mm = 160;  //检测圆环的外径    单位:毫米

    //二、标记ROI预览显示ROI
     cv::Point estimateCenter = cv::Point(750, 500);            //估计的ROI区域的中心坐标
    int estimateRadius = 500;                                //估计的ROI区域的半径
    Mat subImg = Mat::zeros(image0.size(), CV_8UC1);    //初始化一个mat,其大小与srcImg一样,类型为8位单通道类型    
    image0.copyTo(subImg);                                        //把src里的图像复制到subimg中
    cv::cvtColor(subImg, subImg, cv::COLOR_GRAY2RGB);            //把subimg转变为彩色图像
    //thickness为1,lineType为8,shift为对应给定点的小数位数(0对结果不产生影响)
    cv::circle(subImg, estimateCenter,
        estimateRadius, cv::Scalar(0, 0, 255), 1, 8, 0);    //在subimg上画圆
    cv::imshow("s0 ROI Img", subImg);

五、轮廓筛选

    const cv::Scalar RED = cv::Scalar(0, 0, 255);  
    const cv::Scalar GREEN = cv::Scalar(0, 255, 0);
    const cv::Scalar BLUE = cv::Scalar(255, 0, 0);
    const cv::Scalar YELLOW = cv::Scalar(0, 255, 255);
    //1.不在估计区域范围内的轮廓去掉,相同重心的轮廓只保留一个contours2
    // Get the moments,得到轮廓矩
    vector<cv::Moments> mu(contours.size());
    for (int j = 0; j < contours.size(); j++)
    {
   
        mu[j] = moments(contours[j], false);
    }

    ///  Get the mass centers,重心
    vector<cv::Point2f> mc(contours.size());
    for (int j = 0; j < contours.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值