opencv学习之路(18)、霍夫变换
一、简介
在图像处理和计算机视觉领域中,如何从当前的图像中提取所需要的特征信息是图像识别的关键所在。在许多应用场合中需要快速准确地检测出直线或者圆。其中一种非常有效的解决问题的方法是霍夫(Hough)变换。
二、霍夫线变换
霍夫线变换的原理
以上原理部分,转自http://blog.csdn.net/poem_qianmo/article/details/26977557
#include "opencv2/opencv.hpp"
using namespace cv; void main()
{
Mat src=imread("E://1.png");
Mat dst;
imshow("src", src); Canny(src, src, , );
imshow("Canny", src);
//cvtColor(src, dst, CV_BGR2GRAY);//彩色图转灰度图:该语句不能放在canny边缘检测后(canny检测后,图像变为了灰度图)
cvtColor(src, dst, CV_GRAY2BGR);//灰度图转彩色图 //进行霍夫线变换
vector<Vec2f> lines; //定义矢量结构lines用于存放得到的线段矢量集合
HoughLines(src, lines, , CV_PI/, );//超过150的线段才被检测到 //依次在图中绘制出每条线段
for (size_t i = ; i < lines.size(); i++)
{
float rho=lines[i][],theta=lines[i][];
Point pt1,pt2;
double a=cos(theta),b=sin(theta);
double x0=a*rho,y0=b*rho;
pt1.x=cvRound(x0+*(-b));//cvRound(double value) 函数:对一个double型数字四舍五入,返回一个整数
pt1.y=cvRound(y0+*(a));
pt2.x = cvRound(x0 - *(-b));
pt2.y = cvRound(y0 - *(a));
line(dst,pt1,pt2,Scalar(,,),,);
} imshow("dst", dst);
waitKey();
destroyAllWindows();
}
三、累计概率霍夫变换
#include "opencv2/opencv.hpp"
using namespace cv; void main()
{
//HoughLinesP()用法
Mat src = imread("E://1.png");
Mat dstImg = src.clone();
imshow("src", src); cvtColor(src, src, CV_BGR2GRAY);
Canny(src,src, , );
vector<Vec4i> lines; //定义矢量结构lines用于存放得到的线段矢量集合
HoughLinesP(src, lines, , CV_PI/, , , );
//依次在图中绘制出每条线段
for(size_t i = ; i<lines.size(); i++)
{
Vec4i p = lines[i];
line(dstImg, Point(p[0], p[1]), Point(p[2], p[3]), Scalar(0, 255, 0), 2, 8); }
imshow("dst", dstImg);
waitKey();
destroyAllWindows();
}
四、霍夫圆变换
霍夫圆变换的基本原理和上面讲的霍夫线变化大体上是很类似的,只是点对应的二维极径极角空间被三维的圆心点x, y还有半径r空间取代。说“大体上类似”的原因是,如果完全用相同的方法的话,累加平面会被三维的累加容器所代替:在这三维中,一维是x,一维是y,另外一维是圆的半径r。这就意味着需要大量的内存而且执行效率会很低,速度会很慢。
对直线来说, 一条直线能由参数极径极角表示. 而对圆来说, 我们需要三个参数来表示一个圆, 也就是:
这里的(Xcenter,Ycenter)表示圆心的位置 (下图中的绿点) ,而 r 表示半径, 这样我们就能唯一的定义一个圆了, 见下图:
在OpenCV中,我们一般通过一个叫做“霍夫梯度法”的方法来解决圆变换的问题。
- 第一个参数,InputArray类型的image,输入图像,即源图像,需为8位的灰度单通道图像。
- 第二个参数,InputArray类型的circles,经过调用HoughCircles函数后此参数存储了检测到的圆的输出矢量,每个矢量由包含了3个元素的浮点矢量(x, y, radius)表示。
- 第三个参数,int类型的method,即使用的检测方法,目前OpenCV中就霍夫梯度法一种可以使用,它的标识符为CV_HOUGH_GRADIENT,在此参数处填这个标识符即可。
- 第四个参数,double类型的dp,用来检测圆心的累加器图像的分辨率于输入图像之比的倒数,且此参数允许创建一个比输入图像分辨率低的累加器。上述文字不好理解的话,来看例子吧。例如,如果dp= 1时,累加器和输入图像具有相同的分辨率。如果dp=2,累加器便有输入图像一半那么大的宽度和高度。
- 第五个参数,double类型的minDist,为霍夫变换检测到的圆的圆心之间的最小距离,即让我们的算法能明显区分的两个不同圆之间的最小距离。这个参数如果太小的话,多个相邻的圆可能被错误地检测成了一个重合的圆。反之,这个参数设置太大的话,某些圆就不能被检测出来了。
- 第六个参数,double类型的param1,有默认值100。它是第三个参数method设置的检测方法的对应的参数。对当前唯一的方法霍夫梯度法CV_HOUGH_GRADIENT,它表示传递给canny边缘检测算子的高阈值,而低阈值为高阈值的一半。
- 第七个参数,double类型的param2,也有默认值100。它是第三个参数method设置的检测方法的对应的参数。对当前唯一的方法霍夫梯度法CV_HOUGH_GRADIENT,它表示在检测阶段圆心的累加器阈值。它越小的话,就可以检测到更多根本不存在的圆,而它越大的话,能通过检测的圆就更加接近完美的圆形了。
- 第八个参数,int类型的minRadius,有默认值0,表示圆半径的最小值。
- 第九个参数,int类型的maxRadius,也有默认值0,表示圆半径的最大值。
需要注意的是,使用此函数可以很容易地检测出圆的圆心,但是它可能找不到合适的圆半径。我们可以通过第八个参数minRadius和第九个参数maxRadius指定最小和最大的圆半径,来辅助圆检测的效果。或者,我们可以直接忽略返回半径,因为它们都有着默认值0,单单用HoughCircles函数检测出来的圆心,然后用额外的一些步骤来进一步确定半径。
#include "opencv2/opencv.hpp"
using namespace cv; void main()
{
Mat src = imread("E://C.jpg");
Mat dst = src.clone();
imshow("src", src); cvtColor(src, src, CV_BGR2GRAY);
GaussianBlur(src,src,Size(,),); vector<Vec3f> circles;
HoughCircles(src, circles, CV_HOUGH_GRADIENT,1.5, , , );
for(size_t i = ; i<circles.size(); i++)
{
Point center(cvRound(circles[i][]), cvRound(circles[i][]));
int radius = cvRound(circles[i][]);
circle(dst, center, , Scalar(, , ), -, ,);//设置为-1时,画实心圆
circle(dst, center, radius, Scalar(, , ), , ,);//画空心圆
}
imshow("dst", dst);
waitKey();
}
五、其他
opencv学习之路(18)、霍夫变换的更多相关文章
- OpenCV 学习之路(2) -- 操作像素
本节内容: 访问像素值 用指针扫描图像 用迭代器扫描图像 编写高效的图像扫描循环 扫描图像并访问相邻像素 实现简单的图像运算 图像重映射 访问像素值 准备工作: 创建一个简单函数,用它在图像中加入椒盐 ...
- Opencv学习之路—Opencv下基于HOG特征的KNN算法分类训练
在计算机视觉研究当中,HOG算法和LBP算法算是基础算法,但是却十分重要.后期很多图像特征提取的算法都是基于HOG和LBP,所以了解和掌握HOG,是学习计算机视觉的前提和基础. HOG算法的原理很多资 ...
- OpenCV 学习之路(1)
OpenCV的第一个代码: #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #i ...
- opencv学习之路(41)、人脸识别
一.人脸检测并采集个人图像 //take_photo.cpp #include<opencv2/opencv.hpp> using namespace cv; using namespac ...
- opencv学习之路(40)、人脸识别算法——EigenFace、FisherFace、LBPH
一.人脸识别算法之特征脸方法(Eigenface) 1.原理介绍及数据收集 特征脸方法主要是基于PCA降维实现. 详细介绍和主要思想可以参考 http://blog.csdn.net/u0100066 ...
- opencv学习之路(39)、PCA
一.PCA理论介绍 网上已经有许多介绍pca原理的博客,这里就不重复介绍了.详情可参考 http://blog.csdn.net/zhongkelee/article/details/44064401 ...
- opencv学习之路(38)、Mat像素统计基础——均值,标准差,协方差;特征值,特征向量
本文部分内容转自 https://www.cnblogs.com/chaosimple/p/3182157.html 一.统计学概念 二.为什么需要协方差 三.协方差矩阵 注:上述协方差矩阵还需要除以 ...
- opencv学习之路(37)、运动物体检测(二)
一.运动物体轮廓椭圆拟合及中心 #include "opencv2/opencv.hpp" #include<iostream> using namespace std ...
- opencv学习之路(36)、运动物体检测(一)
一.简介 二.背景减法 图片说明 #include "opencv2/opencv.hpp"using namespace cv; void main() { Mat img1 = ...
随机推荐
- Go web ajax project
这个是本人学习之用,比较乱 我也不知道这是在教大家什么,但如果你能看懂,那你就能真正干活了 //https-ajax.go package main import ( "fmt" ...
- 查看手机cpu信息
adb shell getprop ro.product.cpu.abi
- unity3d-游戏实战突出重围,第四天 添加角色
1:添加unity自带的第一人称角色控制器,命名为hreo 2:添加第三人称角色控制器.这里是添加源文件Sources下面的.如箭头指示:而不是“3rd Person Controller”.并命名为 ...
- 数据表格控件 DataGridControl
数据表格控件 书154页 <?xml version="1.0" encoding="utf-8"?> <s:Application xmln ...
- 路径遍历:ZIP条目覆盖
程序在解压zip文件时,如果没有验证zip条目,攻击者可能对条目覆盖,从而造成路径遍历 例如:以下代码示例解压zip文件. static final int BUFFER = 512; / ...
- jQuery清除数组中的空值
var aa = ["12", "34", "", "423", " "]; console.l ...
- sqlserver备份还原数据库时报占用错误
.做项目时遇到这种情形:原来的test_dev数据库,想复制出test_ft供测试用.此时备份test_dev出test_backup文件,想直接还原成test_ft时会报占用错误. 还原数据库:Th ...
- 并发工具CyclicBarrier
想想一下这样一个场景,有多个人需要过河,河上有一条船,船要等待满10个人才过河,过完河后每个人又各自行动. 这里的人相当于线程,注意这里,每个线程运行到一半的时候,它就要等待一个条件,即船满过河的条件 ...
- PE结构图示
- linux常用命令:mv 命令
mv命令是move的缩写,可以用来移动文件或者将文件改名(move (rename) files),是Linux系统下常用的命令,经常用来备份文件或者目录. 1.命令格式: mv [选项] 源文件或目 ...