opencv之7.3霍夫变换

霍夫变换可以实现任何由参数方程描述的几何体的检测。
1.检测直线
原理:霍夫变换基于二值图像,寻找经过每个单独像素点的所有直线,当直线经过足够多的像素点,则这个直线的存在足够明显。
void HoughLines( InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn = 0, double stn = 0, double min_theta = 0, double max_theta = CV_PI );
代码:

Mat image, result, result2;
    image = imread("D:/road.jpg", 0);
    Canny(image, result, 120, 200);
    namedWindow("Canny");
    imshow("Canny", result);

    /*vector<Vec2f> lines;                                      //lines为二维向量,vector<Vec2f>定义二维浮点向量
    HoughLines(result, lines, 1, PI/ 180, 120);                 //霍夫变换
    vector<Vec2f>::iterator it = lines.begin();
    while (it != lines.end())
    {
        float rho = (*it)[0];
        float theta = (*it)[1];
        if (theta < PI / 4 || theta>3 * PI / 4)                 //这个是优化
        {
            Point ptr1(rho / cos(theta), 0);
            Point ptr2((rho - result.rows*sin(theta)) 
            / cos(theta), result.rows);
            line(result, ptr1, ptr2, Scalar(255,0,0));          //
        }
        else
        {
            Point ptr1(0, rho / sin(theta));
            Point ptr2(result.cols, (rho - result.cols*sin(theta)) / cos(theta));
            line(result, ptr1, ptr2, Scalar(255,255,0));
        }
        it++;
    }
    namedWindow("hough");
    imshow("hough", result);
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
概率霍夫检测:不再逐行扫描图像,随机选择像素。一旦累加器达到阈值,则移除直线所经过的像素点,并接受线段的长度。
void HoughLinesP( InputArray image, OutputArray lines,double rho, double theta, int threshold,double minLineLength = 0, double maxLineGap = 0 );
minLineLength表示接受线段的最小长度,maxLineGap表示像素点的最大距离。
代码:
LineFinder.h头文件:
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#define PI 3.141591653
using namespace std;
using namespace cv;

class LineFinder
{
private:
    Mat image;
    vector<Vec4f> lines;
    double deltaRho, deltatheta;
    int minVote;
    double minLength;
    double maxGap;

public:
    LineFinder() :deltaRho(1), deltatheta(PI / 180), minVote(10), minLength(0.), maxGap(0.)
    {

    }
    //设置分辨率
    void SetAccResolusion(double dRho, double dTheta)
    {
        deltaRho = dRho;
        deltatheta = dTheta;
    }
    void SetLengthandGap(double Length, double Gap)
    {
        minLength = Length;
        maxGap = Gap;
    }
    void SetMinVote(int minv)
    {
        minVote = minv;
    }
    vector<Vec4f>findLines(Mat &binary)
    {
        lines.clear();
        HoughLinesP(binary, lines, deltaRho, deltatheta, minVote, minLength, maxGap);
        return lines;
    }
    void drawDetectedLines(Mat &image, Scalar color = Scalar(255,255,255))
    {
        vector<Vec4f>::iterator it = lines.begin();
        for (;it != lines.end();++it)
        {
            Point ptr1((*it)[0], (*it)[1]);
            Point ptr2((*it)[2], (*it)[3]);
            line(image, ptr1, ptr2, color);
        }
    }
};
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

main.cpp文件

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "LineFinder.h"
#define PI 3.141591653
using namespace std;
using namespace cv;

int main()
{
    Mat image, result, result2;
    image = imread("D:/road.jpg", 0);
    Canny(image, result, 120, 200);
    namedWindow("Canny");
    imshow("Canny", result);
    LineFinder finder;
    finder.SetLengthandGap(100, 20);
    finder.SetMinVote(200);
    vector<Vec4f> lines = finder.findLines(result);
    finder.drawDetectedLines(image);
    namedWindow("HoughP");
    imshow("HoughP", image);
    waitKey(0);
    return 0;
}
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

检测圆:
三个参数确定一个圆。
HoughCircles( InputArray image, OutputArray circles, int method, double dp,double minDist, double param1 = 100, double param2 = 100, int minRadius = 0, int maxRadius = 0 );
src_gray: 输入图像 (灰度图),无需canny变换
circles: 存储下面三个参数: x_{c}, y_{c}, r 集合的容器来表示每个检测到的圆.
CV_HOUGH_GRADIENT: 指定检测方法. 现在OpenCV中只有霍夫梯度法
dp = 1: 累加器图像的反比分辨率
min_dist = src_gray.rows/8: 检测到圆心之间的最小距离
param_1 = 200: Canny边缘函数的高阈值
param_2 = 100: 圆心检测阈值.投票数
min_radius = 0: 能检测到的最小圆半径, 默认为0.
max_radius = 0: 能检测到的最大圆半径, 默认为0
代码:
Mat image, result, result2;
image = imread(“D:/round.jpg”, 0);
namedWindow(“image”);
imshow(“image”, image);
GaussianBlur(image, image, Size(5, 5), 1.5);
vector circles;
HoughCircles(image, circles, HOUGH_GRADIENT, 2, 50, 200, 200, 25, 200);
vector::iterator it = circles.begin();
for (;it != circles.end();++it)
{
circle(image, Point((*it)[0], (*it)[1]), (*it)[2], Scalar(255), 2);
}
namedWindow(“circle”);
imshow(“circle”, image);

(function () { ('pre.prettyprint code').each(function () { var lines = (this).text().split(\n).length;var numbering = $('
    ').addClass('pre-numbering').hide(); (this).addClass(hasnumbering).parent().append( numbering); for (i = 1; i

霍夫变换可以实现任何由参数方程描述的几何体的检测。
1.检测直线
原理:霍夫变换基于二值图像,寻找经过每个单独像素点的所有直线,当直线经过足够多的像素点,则这个直线的存在足够明显。
void HoughLines( InputArray image, OutputArray lines, double rho, double theta, int threshold, double srn = 0, double stn = 0, double min_theta = 0, double max_theta = CV_PI );
代码:

Mat image, result, result2;
    image = imread("D:/road.jpg", 0);
    Canny(image, result, 120, 200);
    namedWindow("Canny");
    imshow("Canny", result);

    /*vector<Vec2f> lines;                                      //lines为二维向量,vector<Vec2f>定义二维浮点向量
    HoughLines(result, lines, 1, PI/ 180, 120);                 //霍夫变换
    vector<Vec2f>::iterator it = lines.begin();
    while (it != lines.end())
    {
        float rho = (*it)[0];
        float theta = (*it)[1];
        if (theta < PI / 4 || theta>3 * PI / 4)                 //这个是优化
        {
            Point ptr1(rho / cos(theta), 0);
            Point ptr2((rho - result.rows*sin(theta)) 
            / cos(theta), result.rows);
            line(result, ptr1, ptr2, Scalar(255,0,0));          //
        }
        else
        {
            Point ptr1(0, rho / sin(theta));
            Point ptr2(result.cols, (rho - result.cols*sin(theta)) / cos(theta));
            line(result, ptr1, ptr2, Scalar(255,255,0));
        }
        it++;
    }
    namedWindow("hough");
    imshow("hough", result);
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
概率霍夫检测:不再逐行扫描图像,随机选择像素。一旦累加器达到阈值,则移除直线所经过的像素点,并接受线段的长度。
void HoughLinesP( InputArray image, OutputArray lines,double rho, double theta, int threshold,double minLineLength = 0, double maxLineGap = 0 );
minLineLength表示接受线段的最小长度,maxLineGap表示像素点的最大距离。
代码:
LineFinder.h头文件:
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#define PI 3.141591653
using namespace std;
using namespace cv;

class LineFinder
{
private:
    Mat image;
    vector<Vec4f> lines;
    double deltaRho, deltatheta;
    int minVote;
    double minLength;
    double maxGap;

public:
    LineFinder() :deltaRho(1), deltatheta(PI / 180), minVote(10), minLength(0.), maxGap(0.)
    {

    }
    //设置分辨率
    void SetAccResolusion(double dRho, double dTheta)
    {
        deltaRho = dRho;
        deltatheta = dTheta;
    }
    void SetLengthandGap(double Length, double Gap)
    {
        minLength = Length;
        maxGap = Gap;
    }
    void SetMinVote(int minv)
    {
        minVote = minv;
    }
    vector<Vec4f>findLines(Mat &binary)
    {
        lines.clear();
        HoughLinesP(binary, lines, deltaRho, deltatheta, minVote, minLength, maxGap);
        return lines;
    }
    void drawDetectedLines(Mat &image, Scalar color = Scalar(255,255,255))
    {
        vector<Vec4f>::iterator it = lines.begin();
        for (;it != lines.end();++it)
        {
            Point ptr1((*it)[0], (*it)[1]);
            Point ptr2((*it)[2], (*it)[3]);
            line(image, ptr1, ptr2, color);
        }
    }
};
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

main.cpp文件

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "LineFinder.h"
#define PI 3.141591653
using namespace std;
using namespace cv;

int main()
{
    Mat image, result, result2;
    image = imread("D:/road.jpg", 0);
    Canny(image, result, 120, 200);
    namedWindow("Canny");
    imshow("Canny", result);
    LineFinder finder;
    finder.SetLengthandGap(100, 20);
    finder.SetMinVote(200);
    vector<Vec4f> lines = finder.findLines(result);
    finder.drawDetectedLines(image);
    namedWindow("HoughP");
    imshow("HoughP", image);
    waitKey(0);
    return 0;
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

检测圆:
三个参数确定一个圆。
HoughCircles( InputArray image, OutputArray circles, int method, double dp,double minDist, double param1 = 100, double param2 = 100, int minRadius = 0, int maxRadius = 0 );
src_gray: 输入图像 (灰度图),无需canny变换
circles: 存储下面三个参数: x_{c}, y_{c}, r 集合的容器来表示每个检测到的圆.
CV_HOUGH_GRADIENT: 指定检测方法. 现在OpenCV中只有霍夫梯度法
dp = 1: 累加器图像的反比分辨率
min_dist = src_gray.rows/8: 检测到圆心之间的最小距离
param_1 = 200: Canny边缘函数的高阈值
param_2 = 100: 圆心检测阈值.投票数
min_radius = 0: 能检测到的最小圆半径, 默认为0.
max_radius = 0: 能检测到的最大圆半径, 默认为0
代码:
Mat image, result, result2;
image = imread(“D:/round.jpg”, 0);
namedWindow(“image”);
imshow(“image”, image);
GaussianBlur(image, image, Size(5, 5), 1.5);
vector circles;
HoughCircles(image, circles, HOUGH_GRADIENT, 2, 50, 200, 200, 25, 200);
vector::iterator it = circles.begin();
for (;it != circles.end();++it)
{
circle(image, Point((*it)[0], (*it)[1]), (*it)[2], Scalar(255), 2);
}
namedWindow(“circle”);
imshow(“circle”, image);

(function () { ('pre.prettyprint code').each(function () { var lines = (this).text().split(\n).length;var numbering = $('
    ').addClass('pre-numbering').hide(); (this).addClass(hasnumbering).parent().append( numbering); for (i = 1; i

猜你喜欢

转载自blog.csdn.net/a839766550/article/details/78324436