霍夫变换

霍夫变换——直线

  Hough Line Transform用来做直线检测,前提是已经做了边缘检测。
  霍夫变换是平面空间到极坐标空间的转换,具有以下特点:

  • 对于任意一条直线上的所有点来说,变换到极坐标中,根据theta值可以得到r值
  • 属于同一条直线上的点在极坐标(r,theta)必然在一个点上有最强的信号出现,因此根据最强信号的极坐标反算到平面坐标中就可以得到直线上各个点的像素坐标,从而得到直线。

相关API:

  • 标准的霍夫变换cv::HoughLines从平面坐标转换到霍夫空间,最终输出是(theta,r),表示极坐标空间
  • 霍夫变换直线概率cv::HoughLinesP最终输出是直线的两个点

先进行边缘检测,在进行霍夫直线检测

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include <math.h>
using namespace cv;
using namespace std;
int main(int argc, int ** argv)
{
    src = imread("F:/linedec.png");
    if (!src.data) {
        printf("无法加载图片\n");
        return -1;
    }
    namedWindow("input img", CV_WINDOW_AUTOSIZE);
    namedWindow("output img", CV_WINDOW_AUTOSIZE);
    Canny(src, gray, 150, 200);
    cvtColor(gray, dst, CV_GRAY2BGR);
    imshow("edge img", gray);
    vector<Vec4f> plines;
    HoughLinesP(gray, plines, 1, CV_PI / 180.0, 10, 0, 10);
    Scalar color = Scalar(0, 0, 255);
    for (size_t i = 0; i < plines.size(); i++)
    {
        Vec4f hlines = plines[i];
        line(dst, Point(hlines[0], hlines[1]), Point(hlines[2], hlines[3]), color, 3, LINE_AA);
    }
    imshow("output img", dst);
    waitKey(0);
    return 0;
}

演示效果


image.png

霍夫变换——圆检测

  从平面坐标到极坐标转换三个参数C(x0,y0,r)其中x0与y0是圆心坐标
  假设平面坐标的任意一个圆上的点,转换到极坐标中:C(x0,y0,r)处有最大值,霍夫变换正是利用这个原理实现圆的检测。

相关API:
cv::HoughCircles
  因为霍夫圆检测对噪声比较敏感,所有先对图像做中值滤波。
  基于效率考虑,opencv中实现的霍夫变换圆检测是基于图像梯度的实现,分为两步:

  1. 检测边缘,发现可能的圆心
  2. 基于第一步的基础上从候选圆心开始计数最佳半径大小

HoughCircles参数说明

#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include <math.h>
using namespace cv;
using namespace std;
int main(int argc, int ** argv)
{
    src = imread("F:/circle.png");
    if (!src.data) {
        printf("无法加载图片\n");
        return -1;
    }
    namedWindow("input img", CV_WINDOW_AUTOSIZE);
    namedWindow("output img", CV_WINDOW_AUTOSIZE);
    imshow("input img", src);
    //中值滤波
    Mat output;
    medianBlur(src, output, 3);
    cvtColor(output, output, CV_BGR2GRAY);
    //霍夫圆检测
    vector<Vec3f> pcircles;
    HoughCircles(output, pcircles, CV_HOUGH_GRADIENT, 1, 10, 100, 30, 5, 50);
    src.copyTo(dst);
    for (size_t i = 0; i < pcircles.size(); i++)
    {
        Vec3f cc = pcircles[i];
        circle(dst, Point(cc[0], cc[1]), cc[2], Scalar(0, 0, 255), 2, LINE_AA);
        circle(dst, Point(cc[0], cc[1]), 2, Scalar(0, 255, 0), 2, LINE_AA);
    }
    imshow("output img", dst);
    waitKey(0);
    return 0;
}

演示效果


image.png

cc[0]cc[1]代表圆心的x和y的像素值,cc[2]代表半径

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 在图像处理和计算机视觉领域中,如何冲当前的退选哪个中提取出所需要的特征信息是图像识别的关键所在。在许多应用场合中需...
    傻傻小萝卜阅读 12,229评论 0 1
  • 霍夫变换是检测直线或者圆的一种比较简单的方法。霍夫变换检测直线是比较简单的,做完以后是一个二维平面上的许多曲线,通...
    和蔼的zhxing阅读 4,373评论 0 0
  • 基本思路 先使用上文介绍的Prewitt算子将输入的图像边缘化处理,再使用霍夫变换检测直线。其中使用到了matla...
    DerryChan阅读 13,398评论 1 1
  • 本文转自 python数字图像处理 霍夫线变换 在图片处理中,霍夫变换主要是用来检测图片中的几何形状,包括直线、圆...
    jiandanjinxin阅读 33,586评论 6 23
  • 整座城市都在看雨只有你在看我有没有带伞。承诺无数,抵不过一句我陪你,千言万语,抵不过一句我懂你。你虽然不在身边,但...
    清姿_3942阅读 1,839评论 0 0