31、 霍夫变换 霍夫变换是一种用于在...
31、 霍夫变换
霍夫变换是一种用于在图像中查找直线、圆等形状的方法。 霍夫直线变换的基本理论是,二值图像中的任何点都可能是某条直线的一部分。如果通过斜率a和截距b对直线进行参数化,则原始图像中的一个点将转换为(a,b)平面中与通过该点的所有线相对应的点的轨迹。如果将输入图像中的每个非零像素转换为输出图像中的这样一组点并对所有这些贡献求和,那么出现在输入(即(x,y)平面)图像中的直线将显示为在输出(即(a,b)平面)图像中的局部最大值。(a,b)平面通常称为累加器平面。截距截取形式实际上并不是代表所有通过点的线的最佳方式,通常将每条线表示为极坐标(ρ,θ)中的一个点,隐含的线是穿过指定点但垂直于从原点到该点的半径的线。OpenCV支持三种不同的霍夫直线变换:标准霍夫变换SHT,多尺度霍夫变换MHT和渐进概率霍夫变换PPHT。PPHT是此算法的一种变体,之所以称其为“概率”,是因为它只累加了一部分,而不是累加了累加器平面中的每个可能点,这种结果是大大减少了计算时间。标准和多尺度Hough变换都在函数HoughLines()中实现,区别在于使用或不使用最后两个可选参数。
void
cv::HoughLines(
cv::InputArray
image,
cv::OutputArray
lines,
double
rho,
double
theta,
int
threshold,
double
srn = 0,
double
stn = 0
);
第一个参数是输入图像,它必须是8位图像,但是输入被视为二值信息(即所有非零像素都被视为等效)。 第二个参数是找到的行将被存储的位置,这是一个N×1两通道浮点型数组(列数N将是返回的行数),对于每个找到的行包含rho(ρ)和theta(θ)值。参数rho和theta设置直线所需的分辨率(即累加器平面的分辨率)。rho单位是像素,theta单位是弧度。阈值是累加器平面中的值。该参数表明必须要返回的线的点数。
标准的Hough变换不使用参数srn和stn。它们用于多尺度霍夫变换(MHT)。
HoughLinesP()函数与HoughLines()非常相似,但有两个重要区别。第一个是lines参数将是一个四通道数组,找到的是线段两个端点的位置(x0,y0)和(x1,y1)。 第二个区别是对于PPHT,minLineLength和maxLineGap参数设置将返回线段的最小长度,以及算法不将其连接到单个较长线段中所需的共线段之间的分隔。
霍夫圆变换与霍夫直线变换大致相似。但它具有三个维度的累加器,x,y(圆心的位置)和圆半径r。 这意味着更高的内存需求和更慢的速度。 在OpenCV中,通过使用一种称为Hough梯度的方法避免了此问题。这种实现方式使算法可以运行得更快,并且它有助于解决三维累加器稀疏的问题。
霍夫圆变换函数HoughCircles()具有与直线变换相似的参数。
例1:使用霍夫圆变换在图像中查找圆
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat src;
Mat thrImg;
src = imread('E:/hough.jpg', 0);
imshow('src', src);
vector<Vec3f> circles;
HoughCircles(src, circles, cv::HOUGH_GRADIENT,2,40,160,90,20,55 );
for (size_t i = 0; i < circles.size(); ++i)
{
circle(src,Point(cvRound(circles[i][0]), cvRound(circles[i][1])),cvRound(circles[i][2]),Scalar(0, 0, 255),3);
}
imshow('Hough', src);
waitKey(0);
return 0;
}
2020年农历除夕夜,祝大家春节快乐。我也是有时无聊顺便普及下图像处理及机器视觉的基础知识。但是头条适合娱乐,还是不适合做这种技术方面的内容。感谢大家的关注,此头条号此后可能不再发机器视觉方面的内容了,我还是喜欢在公众号上安静地写点东西。有兴趣的可以去公众号上。名称与此头条号名称完全一样。此头条号以后会传播另一个方面的知识,不是工科技术类了,有兴趣的也可以关注了解下。再次感谢大家关注。