霍夫变换(直线和圆)

霍夫变换是一种在图像中寻找直线和圆及其它简单形状的方法。

霍夫线变换原理:二值图像中的任何点都可能是一些直线集合的一部分,例如在原始图像上的一条直线表示为y = ax + b ,这是原始图像上以x和y为坐标系进行表示的,但是如果我们以a和b为新的变量坐标,那么在新的图像中,某一个点代表了所有过原始图像上点的直线。

CvSeq * cvHoughLines2 (CvArr * image, void * line_storage, int method, double rho, double theta, int threshold, double param1 = 0,double param2 = 0 );

第一个变量是输入图像,必须是8位的,但输入信息可以被看成是二值的(即所有非0像素可以看成是相等的)。

第二个参数是指保存结果位置的指针,即可以是内存块(CvMemoryStorage),也可以是N*1的矩阵数列(行数N有助于限制直线的最大数量)。

Method可以取值为CV_HOUGH_STANDARD 代表SHT 标准霍夫变换

CV_HOUGH_PROBABILISTIC 代表PPHT 累计概率霍夫变换

CV_HOUGH_MULTI_SCALE 代表SHT的多尺度变种。

rho和theta代表设置直线所需要的分辨率;tho的单位是像素,theta的单位是弧度。累加平面可以看成是rho和theta所组成的二维直方图。

threshold表示认定为一条直线时在累计平面中必须达到的值。



#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>

using namespace std;
using namespace cv;

int main(int argc, const char * argv[]) {
    /*1、加载一幅灰度图像*/
    const char filename[] = "/Users/linwang/Downloads/bike.jpeg";
    IplImage * Img = cvLoadImage(filename,CV_LOAD_IMAGE_GRAYSCALE);

    /*2、缩小一倍*/
    IplImage *out = cvCreateImage(cvSize(Img->width/2,Img->height/2), Img->depth, Img->nChannels);
    cvResize(Img, out);
    cvShowImage("Src", out);
    
    /*3、霍夫直线变换*/
    CvMemStorage * sto_line = cvCreateMemStorage(0);
    IplImage * bike = cvCloneImage(out);
    cvCanny(bike, bike, 50, 150);
    CvSeq * Res = cvHoughLines2(bike, sto_line, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 1);
    for (int i = 0; i <= Res->total; i++)                           //序列元素个数
    {
        CvPoint* Line = (CvPoint*)cvGetSeqElem(Res, i);
        cvLine(bike, Line[0], Line[1], CV_RGB(200, 200, 200), 4);     //画线
    }
    cvShowImage("bile line", bike);
    
    /*4、霍夫圆变换*/
    CvMemStorage * storage = cvCreateMemStorage(0);
    cvSmooth(out, out,CV_GAUSSIAN,5,5);
    cvCanny(out, out, 50, 150);
    CvSeq * results = cvHoughCircles(out, storage, CV_HOUGH_GRADIENT, 2, out->width/10, 50, 100, 0, 0);
    for(int i = 0;i<results->total;i++)
    {
        float * p = (float *)cvGetSeqElem(results, i);
        CvPoint pt = cvPoint(cvRound(p[0]),cvRound(p[1]));
        cvCircle(out, pt, cvRound(p[2]), CV_RGB(200, 200, 200));
    }
    cvShowImage("bike Circle", out);
    cvWaitKey(0);
    cvReleaseImage(&Img);
    cvReleaseImage(&out);
    cvReleaseImage(&bike);
    return 0;
}


发布了192 篇原创文章 · 获赞 14 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/u011559236/article/details/78686736