OpenCV图像处理中“找圆技术”的使用
一、为什么“找圆”
代码:
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <math.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat img, gray;
if( argc != 2 || !(img=imread(argv[1], 1)).data)
return -1;
cvtColor(img, gray, COLOR_BGR2GRAY);
// smooth it, otherwise a lot of false circles may be detected
GaussianBlur( gray, gray, Size(9, 9), 2, 2 );
vector<Vec3f> circles;
HoughCircles(gray, circles, HOUGH_GRADIENT,2, gray.rows/4, 200, 100 );
for( size_t i = 0; i < circles.size(); i++ )
{
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
// draw the circle center
circle( img, center, 3, Scalar(0,255,0), -1, 8, 0 );
// draw the circle outline
circle( img, center, radius, Scalar(0,0,255), 3, 8, 0 );
}
namedWindow( "circles", 1 );
imshow( "circles", img );
waitKey(0);
return 0;
}
- 特别需要注意的是,目前版本出现新参数“HOUGH_GRADIENT_ALT”,在默认参数下比以前有很大程度的精度提升:
代码:
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <math.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat img, gray;
if( argc != 2 || !(img=imread(argv[1], 1)).data)
return -1;
cvtColor(img, gray, COLOR_BGR2GRAY);
// smooth it, otherwise a lot of false circles may be detected
GaussianBlur( gray, gray, Size(9, 9), 2, 2 );
vector<Vec3f> circles;
HoughCircles(gray, circles, HOUGH_GRADIENT,2, gray.rows/4, 200, 100 );
for( size_t i = 0; i < circles.size(); i++ )
{
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
// draw the circle center
circle( img, center, 3, Scalar(0,255,0), -1, 8, 0 );
// draw the circle outline
circle( img, center, radius, Scalar(0,0,255), 3, 8, 0 );
}
namedWindow( "circles", 1 );
imshow( "circles", img );
waitKey(0);
return 0;
}
- 特别需要注意的是,目前版本出现新参数“HOUGH_GRADIENT_ALT”,在默认参数下比以前有很大程度的精度提升:
但是HoughCircle的缺点也是显而易见的,简单来说,在默认参数下,它非常容易丢目标。
2.2BlobDetector
所谓Blob就是图像中一组具有某些共同属性(例如,灰度值)的连接像素。OpenCV提供了一种方便的方法来检测斑点并根据不同的特征对其进行过滤。
// Setup SimpleBlobDetector parameters.
SimpleBlobDetector::Params params;
// Change thresholds
params.minThreshold = 10;
params.maxThreshold = 200;
// Filter by Area.
params.filterByArea = true;
params.minArea = 1500;
// Filter by Circularity
params.filterByCircularity = true;
params.minCircularity = 0.1;
// Filter by Convexity
params.filterByConvexity = true;
params.minConvexity = 0.87;
// Filter by Inertia
params.filterByInertia = true;
params.minInertiaRatio = 0.01;
#if CV_MAJOR_VERSION < 3 // If you are using OpenCV 2
// Set up detector with params
SimpleBlobDetector detector(params);
// You can use the detector this way
// detector.detect( im, keypoints);
#else
// Set up detector with params
cv::Ptr<cv::SimpleBlobDetector> detector = cv::SimpleBlobDetector::create(params);
vector<KeyPoint> keypoints;
detector->detect(screw1, keypoints);
#endif
在OpenCV中实现的叫做SimpleBlobDetector,它基于以下描述的相当简单的算法,并且进一步由参数控制,具有以下步骤。
SimpleBlobDetector::Params::Params()
{
thresholdStep = 10; //二值化的阈值步长,即公式1的t
minThreshold = 50; //二值化的起始阈值,即公式1的T1
maxThreshold = 220; //二值化的终止阈值,即公式1的T2
//重复的最小次数,只有属于灰度图像斑点的那些二值图像斑点数量大于该值时,该灰度图像斑点才被认为是特征点
minRepeatability = 2;
//最小的斑点距离,不同二值图像的斑点间距离小于该值时,被认为是同一个位置的斑点,否则是不同位置上的斑点
minDistBetweenBlobs = 10;
filterByColor = true; //斑点颜色的限制变量
blobColor = 0; //表示只提取黑色斑点;如果该变量为255,表示只提取白色斑点
filterByArea = true; //斑点面积的限制变量
minArea = 25; //斑点的最小面积
maxArea = 5000; //斑点的最大面积
filterByCircularity = false; //斑点圆度的限制变量,默认是不限制
minCircularity = 0.8f; //斑点的最小圆度
//斑点的最大圆度,所能表示的float类型的最大值
maxCircularity = std::numeric_limits<float>::max();
filterByInertia = true; //斑点惯性率的限制变量
minInertiaRatio = 0.1f; //斑点的最小惯性率
maxInertiaRatio = std::numeric_limits<float>::max(); //斑点的最大惯性率
filterByConvexity = true; //斑点凸度的限制变量
minConvexity = 0.95f; //斑点的最小凸度
maxConvexity = std::numeric_limits<float>::max(); //斑点的最大凸度
}
{
thresholdStep = 10; //二值化的阈值步长,即公式1的t
minThreshold = 50; //二值化的起始阈值,即公式1的T1
maxThreshold = 220; //二值化的终止阈值,即公式1的T2
//重复的最小次数,只有属于灰度图像斑点的那些二值图像斑点数量大于该值时,该灰度图像斑点才被认为是特征点
minRepeatability = 2;
//最小的斑点距离,不同二值图像的斑点间距离小于该值时,被认为是同一个位置的斑点,否则是不同位置上的斑点
minDistBetweenBlobs = 10;
filterByColor = true; //斑点颜色的限制变量
blobColor = 0; //表示只提取黑色斑点;如果该变量为255,表示只提取白色斑点
filterByArea = true; //斑点面积的限制变量
minArea = 25; //斑点的最小面积
maxArea = 5000; //斑点的最大面积
filterByCircularity = false; //斑点圆度的限制变量,默认是不限制
minCircularity = 0.8f; //斑点的最小圆度
//斑点的最大圆度,所能表示的float类型的最大值
maxCircularity = std::numeric_limits<float>::max();
filterByInertia = true; //斑点惯性率的限制变量
minInertiaRatio = 0.1f; //斑点的最小惯性率
maxInertiaRatio = std::numeric_limits<float>::max(); //斑点的最大惯性率
filterByConvexity = true; //斑点凸度的限制变量
minConvexity = 0.95f; //斑点的最小凸度
maxConvexity = std::numeric_limits<float>::max(); //斑点的最大凸度
}
- 阈值:通过使用以minThreshold开始的阈值对源图像进行阈值处理,将源图像转换为多个二进制图像。这些阈值以thresholdStep递增,直到maxThreshold。因此,第一个阈值为minThreshold,第二个阈值为minThreshold + thresholdStep,第三个阈值为minThreshold + 2 x thresholdStep,依此类推;
- 分组:在每个二进制图像中,连接的白色像素被分组在一起。我们称这些二进制blob;
- 合并:计算二进制图像中二进制斑点的中心,并合并比minDistBetweenBlob更近的斑点;
- 中心和半径计算:计算并返回新合并的Blob的中心和半径。
并且可以进一步设置SimpleBlobDetector的参数来过滤所需的Blob类型。
- 按颜色:首先需要设置filterByColor =True。设置blobColor = 0可选择较暗的blob,blobColor = 255可以选择较浅的blob。
- 按大小:可以通过设置参数filterByArea = 1以及minArea和maxArea的适当值来基于大小过滤blob。例如。设置minArea = 100将滤除所有少于100个像素的斑点。
- 按圆度:这只是测量斑点距圆的距离。例如。正六边形的圆度比正方形高。要按圆度过滤,请设置filterByCircularity =1。然后为minCircularity和maxCircularity设置适当的值。圆度定义为()。圆的为圆度为1,正方形的圆度为PI/4,依此类推。
- 按凸性:凸度定义为(斑点的面积/凸包的面积)。现在,形状的“凸包”是最紧密的凸形,它完全包围了该形状,用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边形,它能包含点集中所有的点。直观感受上,凸性越高则里面“奇怪的部分”越少。要按凸度过滤,需设置filterByConvexity = true,minConvexity、maxConvexity应该属于[0,1],而且maxConvexity> minConvexity。
- 按惯性比:这个词汇比较抽象。我们需要知道Ratio可以衡量形状的伸长程度。简单来说。对于圆,此值是1,对于椭圆,它在0到1之间,对于直线,它是0。按惯性比过滤,设置filterByInertia = true,并设置minInertiaRatio、maxInertiaRatio同样属于[0,1]并且maxConvexity> minConvexity。
按凸性(左低右高)
按惯性比(左低右高)
按凸性(左低右高) | 按惯性比(左低右高) |
cv::Ptr<cv::SimpleBlobDetector> detector = cv::SimpleBlobDetector::create();
OpenCV图像处理中“找圆技术”的使用的更多相关文章
- OpenCV图像处理中的“机器学习"技术的使用
注意,本文中所指"机器学习"(ML)技术,特指SVM.随机森林等"传统"技术. 一.应用场景 相比较当下发展迅速的各路"端到端" ...
- OpenCV图像处理中常用函数汇总(2)
// 霍夫线变换 hough vector<Vec2f> lines;//定义一个矢量结构lines用于存放得到的线段矢量集合 HoughLines(dstImage,lines,,CV_ ...
- OpenCV图像处理中常用函数汇总(1)
//俗话说:好记性不如烂笔头 //用到opencv 中的函数时往往会一时记不起这个函数的具体参数怎么设置,故在此将常用函数做一汇总: Mat srcImage = imread("C:/Us ...
- opencv——pcb上找圆mark点(模板匹配)
#include "stdafx.h" #include <cv.h> #include <highgui.h> #include <cxcore.h ...
- Android技术——在Android中的随意视图中找控件
1.在非常多情况下,我们可能不知道控件的id,可是我们却希望在包括这个控件的视图中找到它,能够採用例如以下做法: 例:在Activity的根视图中找出当中全部的Button控件 private voi ...
- Zedboard甲诊opencv图像处理(三)
整个工程进展到这一步也算是不容易吧,但技术含量也不怎么高,中间乱起八糟的错误太烦人了,不管怎么样,现在面临了最大的困难吧,图像处理算法.算法确实不好弄啊,虽然以前整过,但都不是针对图像的. 现在的图像 ...
- Python+OpenCV图像处理(十四)—— 直线检测
简介: 1.霍夫变换(Hough Transform) 霍夫变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛,也有很多改进算法.主要用来从图像中分离出具有某种相同特征的几何形状(如,直线 ...
- 【python+opencv】直线检测+圆检测
Python+OpenCV图像处理—— 直线检测 直线检测理论知识: 1.霍夫变换(Hough Transform) 霍夫变换是图像处理中从图像中识别几何形状的基本方法之一,应用很广泛,也有很多改进 ...
- (转载)找圆算法((HoughCircles)总结与优化
Opencv内部提供了一个基于Hough变换理论的找圆算法,HoughCircle与一般的拟合圆算法比起来,各有优势:优势:HoughCircle对噪声点不怎么敏感,并且可以在同一个图中找出多个圆 ...
随机推荐
- Flutter Widgets
Flutter Widgets Flutter 组件 Syncfusion Flutter Widgets 所有组件均支持即装即用的 Android,iOS和 Web not free https:/ ...
- 如何禁用 Chrome Taps Group feature 💩
如何禁用 Chrome Taps Group feature bug https://support.google.com/chrome/go/feedback_confirmation How to ...
- How to using PyPI publish a Python package
How to using PyPI publish a Python package PyPI & Python package https://pypi.org/ main make a f ...
- ES2019 features & ES-Next
ES2019 features & ES-Next https://github.com/tc39/proposals Object.fromEntries(), trimStart(), t ...
- git stash & git stash pop
git stash & git stash pop $ git checkout feature/select-seat-system $ git checkout feature/app-d ...
- 200万枚SPC空投来袭,这样的薅羊毛活动你确定不参加吗?
在过去的2020年,币圈真的是很火爆,很多人在参与数字货币交易或DeFi挖矿中赚到了大钱.但是转眼到了2021年,DeFi进入了下半场,区块链市场也进入了新的阶段,那么区块链的下一个爆点是什么呢?很多 ...
- 2021-2-20:请你说说分布式系统 BASE 理论是什么?
BASE 理论是由 Dan Pritchett 在 ACM 上发表的一篇论文中提出的理论.是在 CAP 理论基础上提出的一种更实际的理论指导,和 PACELC 理论是有些相近的地方的. BASE 是指 ...
- 数据归一化 scikit-learn中的Scaler
1 import numpy as np 2 from sklearn import datasets 3 4 # 获取数据 5 iris = datasets.load_iris() 6 X = i ...
- hadoop环境搭建:高可用
目录 1.硬件配置 2.软件版本 3.准备工作 3.1.配置网络环境 3.2.安装JDK 3.3.安装ZOOKEEPER 4.安装Hadoop 5.启动 6.问题 7.配置文件 1.硬件配置 采用3台 ...
- Java并发之CompletionService详解
CompletionService是什么? 它是JUC包中的一个接口类,默认实现类只有一个ExecutorCompletionService. CompletionService干什么的? 它将异步任 ...