精华内容
下载资源
问答
  • OpenCV小孔圆心定位

    千次阅读 2019-12-09 22:30:58
    前面写的使用改进的最小二乘法拟合缺陷圆效果很好,但在小孔的圆心定位上效果大相径庭,原因可能是小孔边缘点坐标数少,同时小孔变形的影响也很大。...随机一个点为A,但最好是第 n / 3 个点,避免所选点位于水平...

    前面写的使用改进的最小二乘法拟合缺陷圆效果很好,但在小孔的圆心定位上效果大相径庭,原因可能是小孔边缘点坐标数少,同时小孔变形的影响也很大。在王术彬的论文《基于几何特征的圆心定位方法研究与应用》中学到两种方法。
    一、直角三角形法
    通过在圆内找到一个内接直角三角形,利用斜边的中点为圆心,斜边的一半为半径的性质实现小孔定位。
    步骤:

    1. 随机找一个点为A,但最好是第 n / 3 个点,避免所选点位于水平和垂直线上,导致找不到后面两点;
    2. 沿A的 x 方向寻找垂直的B点;
    3. 沿A的 y 方向寻找水平的C点;
    4. 计算B、C点间的中点为圆心,距离为直径。
      在这里插入图片描述
      但该方法易受孔大小的限制,当孔过小时不能找到合适的B、C点,且只适用于完整圆中。

    二、中垂线法
    利用圆上三点可以构造两条弦,分别做弦的中垂线,两线交点即为圆心,求得半径。
    步骤:

    1. 可取第一点为A,第 n / 3个点为B,第 2 * n / 3个点为C点;
    2. 求取两线的斜率和线上一点;
    3. 推导出交点计算公式,利用公式计算圆心:
    	x = double(y2 - y1 + k1 * x1 - k2 * x2) / (k1 - k2);
    	y = k1*(x - x1) + y1;
    

    在这里插入图片描述
    该方法较直角三角形法,计算稍微复杂,但适用范围更广。

    三、结果显示
    在这里插入图片描述

    展开全文
  • 图像圆心

    2012-12-28 09:07:25
    题目来自Opencv每周一练第十一期 找圆心 代码和原图
  • 两个步骤:寻找圆心、对所有可能的圆心做估计 1、寻找圆心 用Canny算法进行边缘检测,得到边界二值图 用Sobel算子计算原图的梯度 遍历边缘二值图中的非0点,沿着梯度方向和反方向画线段(梯度方向为圆弧的法线方向...

    两个步骤:寻找圆心、对所有可能的圆心做估计

    1、寻找圆心

    用Canny算法进行边缘检测,得到边界二值图
    用Sobel算子计算原图的梯度
    遍历边缘二值图中的非0点,沿着梯度方向和反方向画线段(梯度方向为圆弧的法线方向,即半径方向),线段的起点和长度由参数允许的半径区间决定。将线段经过的点在累加器中记数
    对累计器中的点从大到小排序,记数越大越有可能成为圆心,优先估计半径

    2、对某个可能的圆心作半径估计

    计算所有边界图中的非0点离圆心的距离,并从小到大排序
    从小半径r开始,距离相差在一个小量范围内的点,都认为是同一个圆,记数属于该半径r的非0点数,记为n
    尝试放大半径,同样记数改半径的点数
    判断两个半径孰优孰劣的依据——点的线密度(点数n/半径r),密度越高,半径的可信度越大
    重复以上步骤,直至半径超过参数允许的范围,从而得到最优半径
    --------------------- 
    作者:hhyh612 
    来源:CSDN 
    原文:https://blog.csdn.net/hhyh612/article/details/54947205 
    版权声明:本文为博主原创文章,转载请附上博文链接!

    展开全文
  • OpenCV霍夫梯度圆算法

    千次阅读 多人点赞 2017-02-09 20:34:03
    OpenCV使用霍夫梯度算法检测图像中的圆。 算法步骤如下 用Canny算法进行边缘检测,得到一副边缘的二值图用Sobel算子计算图像的梯度图遍历边缘图中的非0点,沿着梯度方向和反方向求线段(梯度方向为圆弧的法线...

    OpenCV使用霍夫梯度算法检测图像中的圆。

    算法步骤如下


    寻找圆心

    1. 用Canny算法进行边缘检测,得到边界二值图
    2. 用Sobel算子计算原图的梯度
    3. 遍历边缘二值图中的非0点,沿着梯度方向和反方向画线段(梯度方向为圆弧的法线方向,即半径方向),线段的起点和长度由参数允许的半径区间决定。将线段经过的点在累加器中记数
    4. 对累计器中的点从大到小排序,记数越大越有可能成为圆心,优先估计半径

    对某个可能的圆心作半径估计
    1. 计算所有边界图中的非0点离圆心的距离,并从小到大排序
    2. 从小半径r开始,距离相差在一个小量范围内的点,都认为是同一个圆,记数属于该半径r的非0点数,记为n
    3. 尝试放大半径,同样记数改半径的点数
    4. 判断两个半径孰优孰劣的依据——点的线密度(点数n/半径r),密度越高,半径的可信度越大
    5. 重复以上步骤,直至半径超过参数允许的范围,从而得到最优半径
    展开全文
  • [img=... 上图中白色部门,是由两个不很规则的矩形(姑且看着是矩形)和两个圆组成,背景有很多干扰,麻烦请哪位大神帮忙做下,圆需要找到圆心坐标和半径,矩形是四个角的坐标。
  • opencv 识别圆环

    2020-11-15 16:57:07
    利用opencv识别圆环圆心方法思路涉及到的opencv方法关键代码效果实现总结 方法思路 大概的流程就是: 先对图像去噪声 识别出轮廓 出自己想要的轮廓(重点) 涉及到的opencv方法 1 cv::GaussianBlur...

    方法思路

    大概的流程就是:	先对图像去噪声
    			 	识别出轮廓
    			 	找出自己想要的轮廓(重点)
    

    涉及到的opencv方法

    1 cv::GaussianBlur() //彩色图像转化成灰度图,并且去噪
    2 cv::threshold() //图像二值化,用法以后会根据我的经验详解一次
    3 cv::findContours() //找图像轮廓
    4 cv::fitEllipse() //椭圆拟合
    其实用到的opencv的封装方法还有很多,在这解释也没有必要,主要用这四个就能实现了,简单又方便。
    

    关键代码

    void markDetect(cv::Mat image, std::vector<cv::Point2f> &marks){
    cv::Mat smoothed_gray_gpu, fd_x, fd_y, fd_mag, fd_mag_8bit_abs, edge, smoothed_gray, edge_;
    cv::GaussianBlur(image, smoothed_gray_gpu, cv::Size(3, 3), 0);//彩色图像转化成灰度图
    // smoothed_gray = smoothed_gray_gpu.clone();
    // cv::Sobel(smoothed_gray_gpu, fd_x, CV_32F, 1, 0, 1);//边缘检测
    // cv::Sobel(smoothed_gray_gpu, fd_y, CV_32F, 0, 1, 1);
    // cv::magnitude(fd_x, fd_y, fd_mag);//梯度幅值
    // fd_mag.convertTo(fd_mag_8bit_abs, CV_8UC1, 1);
    cv::threshold(smoothed_gray_gpu, edge, 127, 255, cv::THRESH_TOZERO);
    
    std::vector<std::vector<cv::Point> > contours;
    cv::cvtColor(edge, edge_, CV_BGR2GRAY);
    cv::findContours(edge_, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
    cv::drawContours(image, contours, -1, cv::Scalar::all(255));
    
    
    bool is_mark;
    float ellipseness, eccenty, radius;
    cv::RotatedRect ellipse;
    cc_ellipse_.clear();
    //std::cout <<"contours.size()="<< contours.size() << std::endl;
    for (size_t i=0; i<contours.size(); i++) {//遍历轮廓,找圆
    	if (contours[i].size() < 5)
    		continue;
    	if(cv::contourArea(contours[i]) < min_contour_area_)
    	{
    		continue;
    	}
    	ellipseness = FitEllipse(contours[i], ellipse);//和圆的相似程度
    	if (!InsideImage(image, ellipse.center)) continue;
    	radius = EllipseRadius(ellipse);//半径
    	eccenty = EllipseEccentricity(ellipse);//圆心
    
    	is_mark = (ellipseness <= max_ellipseness_
    			&& radius >= min_radius_
    			&& eccenty <= max_eccentricity_
    	/*&& data >= min_center_grayscale_*/);
        std::cout<<"ismark="<<is_mark<<std::endl;
    	if (is_mark) {
    		UpateConcentricEllipse(ellipse);//更新满足要求的椭圆list,同心圆
    		// std::cout<<"eccenty="<<eccenty<<std::endl;
    		cv::ellipse(image, ellipse, cv::Scalar(0,0,255));
    	}
    }
    std::cout <<"cc_ellipse_.size()"<<cc_ellipse_.size() << std::endl;
    for (size_t i=0; i<cc_ellipse_.size(); i++)
    {
    	if (RecognizeMark(cc_ellipse_[i])){
    		marks.push_back(cv::Point2f(cc_ellipse_[i].center()));
    		std::cout << "push elli"<<cc_ellipse_[i].center() << std::endl;
    		cv::circle(image, cc_ellipse_[i].center(), 5, cv::Scalar(255,0,0));
    		std::cout << cc_ellipse_[i].center() << std::endl;
    	}
    }
    }
    
    float FitEllipse(const std::vector<cv::Point> &contour, cv::RotatedRect &ellipse)
     {//返回的数值代表和圆的相似度
    float dist = 0;
    std::vector<cv::Point> contourEllipse;
    
    ellipse = cv::fitEllipse(contour);
    
    cv::Size axes(0.5*ellipse.size.width, 0.5*ellipse.size.height);
    cv::ellipse2Poly(ellipse.center, axes, ellipse.angle, 0, 360, 1, contourEllipse);
    
    for (size_t i=0; i<contour.size(); i+=3)
    	dist += std::abs((float)cv::pointPolygonTest(contourEllipse, contour[i], true));
    
    return dist/contour.size();
    }
    bool InsideImage(const cv::Mat &image, const cv::Point &pt) {//点是否在轮廓内
    cv::Rect rect(0, 0, image.cols, image.rows);
    return rect.contains(pt);
    }
    
    float EllipseRadius(const cv::RotatedRect &ellipse) 
    {
    return (ellipse.size.width + ellipse.size.height) * 0.5f;
    }
    
    float EllipseEccentricity(const cv::RotatedRect &ellipse)
     {
    float a = std::max(ellipse.size.width, ellipse.size.height) * 0.5f;
    float b = std::min(ellipse.size.width, ellipse.size.height) * 0.5f;
    return sqrt(1 - (b*b)/(a*a));
    }
    void UpateConcentricEllipse(const cv::RotatedRect &ellipse) {
    for(size_t i=0; i<cc_ellipse_.size(); i++) {
    	if (cc_ellipse_[i].Concentric(ellipse.center, cc_ellipse_range_)) {
    		std::cout<<"ellipse.center="<<ellipse.center<<std::endl;
    		cc_ellipse_[i].Add(ellipse);
    		return;
    	}
    }
    
    cc_ellipse_.push_back(ConcentricEllipse());
    cc_ellipse_.back().Add(ellipse);
    }
    
    bool RecognizeMark(const ConcentricEllipse &cc_ellipse) 
    {//判断是不是满足要求的圆环,看大圆和小圆的大小有没有超出要求
    const ConcentricEllipse::EllipseSet &ellipse_set = cc_ellipse.ellipse();
    
    if (ellipse_set.size() < 2) return false;
    
    ConcentricEllipse::CEllipseSetIterator itr = ellipse_set.begin();
    float min_r = EllipseRadius(*itr);
    itr = ellipse_set.end();
    --itr;
    float max_r = EllipseRadius(*itr);
    float r_ratio = min_r / max_r;
    if (r_ratio < mark_min_cc_r_ratio_ || r_ratio > mark_max_cc_r_ratio_) return false;
    
    return true;
    }
    

    在这里解释以下,被注释掉的梯度滤波可以发现更多更全面的轮廓,但是我这里圆环的
    轮廓明显,可以使用更粗糙的滤波方式,具体对比我这里就不展现了。

    效果实现

    输入图片
    环状物
    输出图片在这里插入图片描述

    总结

    按照一般的处理过程处理直到识别出图像轮廓都没有问题,主要是按照自己的需求筛选出我们想要的轮廓,这就
    要我们找轮廓特征然后结合合理的方法来筛选了。现在提供的代码只是部分,而且比较乱,之后会抽空整理一份完整的出来。
    
    展开全文
  • 前面学习了霍夫直线检测,现在把它推广一下用来检测圆,不过它的思路还是用投票来计算交点的方式,但是霍夫...仔细考虑一下,其实还有别的方法来找圆心的,比如下图: 在这图里可以发现使用同一个半径不停地画圆...
  • 在这里将要学习Meanshift算法,这个算法主要在视频里寻找指定目标区域对象。Meanshift算法的原理在直觉上是很很简单的,假设有一张很点做成的图,如下图: ...当你想这个圆的质心时,你会发现它并不...
  • 前面也讨论过使用尺规作图时,可以有三点不共线垂直平分线的方法,其实垂值平分线给我们一个提示,就是只要找到法线,就可以找到圆心,有了圆心的位置再去半径就容易多了。这样比前面蛮力计算要快很多。如果我们再...
  • 使用opencv识别同心圆

    千次阅读 2015-12-25 23:48:37
    使用过opencv视觉库的小伙伴都知道,opencv自带的函数HoughCircles()可以用来检测圆,但无法直接检测同心圆。所以当我们在识别靶盘的时候,需要对该函数...3. 计算这些圆的圆心距,出最小的圆心距,然后以该圆心
  • Opencv C++表盘读数识别

    2020-04-08 16:59:29
    参考链接:... 1、模板匹配 2、寻找RoI 3、霍夫变换找圆心和半径 4、Canny算子和霍夫直线变换找指针位置 5、表盘指针定位 6、计算角度并进行读数转换 准确的有待提高... ...
  • 目录原理API代码编写 ...随机三个点,那么相同半径下,这三个圆会相交在圆心。 通过rgb相加,交点的像素值会很大,看上去最亮,这个点就是原点。 API void HoughCircles(InputArray image, Outpu
  • opencv-最小二乘法拟合光斑最大轮廓

    千次阅读 2015-04-24 16:35:38
    预处理中,使用了OTSU阈值分割,opencv中cv...轮廓只保留面积最大的,然后圆心并在图上标注。 代码: #include "cv.h" #include "highgui.h" #include using namespace std; int otsu(IplImage* src) { Cv
  • 我们如何才能在一张图像中的圆的轮廓,同时找到它的圆心坐标以及它的面积和周长呢?我的思路是阈值分割+形态学处理+高宽比过滤。大家也可以尝试下霍夫圆检测的思路。 接下我们编写代码:#include &lt;opencv2...
  • 在工业中产品或者夹具上经常有...(3)点击圆按钮,这时就会显示出找到的圆孔的圆心坐标等信息。 附图如下: 像上图这样比较模糊的图像通过设置参数也可以准确找到圆心。 转载于:https://www.cnblogs.com/chit...
  • • 学习使用霍夫变换在图像中圆形(环)。 • 学习函数:cv2.HoughCircles()。 首先对图像进行canny边缘检测,对边缘中的每一个非0点,通过Sobel算法计算局部梯度。那么计算得到的梯度方向,实际上就是圆切线的...
  • ⚠️由于自己的拖延症,3.4.3翻到一半,OpenCV发布了4.0.0了正式版,所以接下来是按照4.0.0翻译的。 ⚠️除了版本之外,其他还是照旧,Hough Circle Transform,附原文。 目标 在这一章, 我们会学到用霍夫...
  • opencv学习笔记】022之霍夫圆变换

    千次阅读 2018-04-11 17:28:50
    1.原理介绍opencv中实现霍夫圆变换原理其实很简单的,初中生都会的,所以大家不要担心了啦,看下面这张图片,你看到了啥?对,没错,就是两根直线,四个圆,四个点,四个点分别是四个圆的圆心。并且四个圆大小是一样...
  • 利用opencv寻找乒乓球的坐标及大小

    千次阅读 2013-03-31 21:06:48
    功能:打开USB摄像头读取图片,出图像中黄色乒乓球,并返回球的坐标及半径(都是基于图像像素坐标的) 开发环境:Fedoar 9 opencv-2.4.0 程序流程图:      /*程序可以将黄色的乒乓球,在光线不太亮的情况下,...
  • • 学习使用霍夫变换在图像中圆形(环)。 • 学习函数:cv2.HoughCircles()。 原理 圆形的数学表达式为,其中(xcenter,ycenter)为圆心的坐标,r 为圆的直径。从这个等式中我们可以看出:一个圆环需要 3个参数来...
  • opencv代码分析--hough变换识别圆

    千次阅读 2012-10-30 15:18:59
    opencv中圆识别的基本原理如下: 1、canny算子求图像的单像素二值化边缘 2、假设我们需要半径为R的所有圆,则对于边缘图中的每一个边缘点,该边缘点的切线的法线方向上(正负两个方向),寻找到该边缘点距离为R的...
  • 确定圆心:图片上每一个边缘点,出梯度方向,做一条直线,直线上所有像素点的位置都投一票。得票最多的点就是圆心。** ** 3. 确定半径:比如通过阈值,找到了几个圆心。把半径打散,边缘上每一个点,算...
  • 串口通信,opencv3.0窗口大小可调编译cmake ../make./color正常光线下运行比较稳定,圆比较准确。程序设置了圆的半径区间以及圆心最小间距,以满足产品的需求,可自行修改调试。历程如下#define USE_SERIAL 0 // ...
  • 上网一查才发现cv2Gradient会出一个最大可能的圆心, 也就是只能拟合一个最佳的圆, 所以想用它来拟合同心圆是不可能的。 极坐标变换 有个问题, 就是坐标变换后, 数字有可能图像显示上不连贯 截

空空如也

空空如也

1 2
收藏数 24
精华内容 9
关键字:

opencv找圆心