在图像处理和计算机视觉领域中,如何冲当前的退选哪个中提取出所需要的特征信息是图像识别的关键所在。在许多应用场合中需要快速的检测出直线或者是圆。其中一种非常有效的的解决方法是霍夫变换,其为图像处理中从图像中识别几何图形的基本方法。
霍夫变换的概述
霍夫变换在opencv中分为霍夫线变换和霍夫圆变换
opencv中的霍夫线变换
霍夫线变换是一种用来寻找直线的方法,在使用霍夫线变换之前,首先对图像进行边缘检测,即霍夫线变换的直接输入只能是边缘二值图像。
opencv中霍夫线变换有三种
(1)标准霍夫变换(SHT),由HoughLines调用
(2)多尺度霍夫变换(MSHT),由HoughLines调用,
(3)累计概率霍夫变换(PPHT),由HoughLinesP调用,可以在一定范围内进行霍夫变换
霍夫变换的原理
标准霍夫变换函数:HoughLines()
void HoughLines( InputArray image,// 源图像,需为8位的单通道二进制图像,可以将任意的源图像载进来,并由函数修改成此格式再放进来
OutputArray lines,
double rho,
double theta,
int threshold,
double srn = 0,
double stn = 0,
double min_theta = 0,
double max_theta = CV_PI );
参数详解
代码实现
NSString *image = @"lou.png";
UIImage *image1 = [UIImage imageNamed:image];
Mat im; UIImageToMat(image1, im);
if (im.empty()) {
return;
}
// 创建零时变量
Mat midImage,dstImage;
// 进行边缘检测和转换为灰度图
Canny(im, midImage, 50, 200);
cvtColor(midImage, dstImage, COLOR_GRAY2BGR);
// 进行霍夫变换
std::vector<Vec2f>lines;// 定义一个矢量lines,存放得到的线段矢量集合
HoughLines(midImage, lines, CV_PI/180, 150, 0);
for (size_t i = 0; i < lines.size(); i++) {
float rho = lines[i][0],theta = lines[i][1];
cv::Point pt1,pt2;
double a = cos(theta),b = sin(theta);
double x0 = a*rho,y0 = b*rho;
pt1.x = cvRound(x0 + 1000*(-b));
pt1.y = cvRound(y0 + 1000*(a));
pt2.x = cvRound(x0 - 1000*(-b));
pt2.y = cvRound(y0 - 1000*(a));
line(dstImage, pt1, pt2, Scalar(100,100,195));
}
self.secondImageView.image = MatToUIImage(dstImage);
效果
累计概率霍夫变换函数:HoughLinesP() 函数
void HoughLinesP( InputArray image,
OutputArray lines,
double rho,
double theta,
int threshold,
double minLineLength = 0,
double maxLineGap = 0
);
参数详解
代码实现
NSString *image = @"xixi.jpg";
UIImage *image1 = [UIImage imageNamed:image];
Mat im;
UIImageToMat(image1, im);
if (im.empty()) { return; }
// 创建零时变量
Mat midImage,dstImage;
// 进行边缘检测和转换为灰度图
Canny(im, midImage, 50, 200,3);
cvtColor(midImage, dstImage, CV_GRAY2BGR);
std::vector<Vec4i>lines;// 定义一个矢量lines,存放得到的线段矢量集合
HoughLinesP(midImage,lines, 1,CV_PI/180, 80, 50, 10);
for (size_t i = 0; i < lines.size(); i++) {
Vec4i l = lines[i];
line(dstImage, cv::Point(l[0],l[1]),cv::Point(l[2],l[3]) , Scalar(186,88,255),1,LINE_AA);
}
self.secondImageView.image = MatToUIImage(dstImage);
效果