霍夫线变换可以在灰度图中找到线段
函数原型:
CVAPI(CvSeq*) cvHoughLines2( CvArr* image, void* line_storage, int method,
double rho, double theta, int threshold,
double param1 CV_DEFAULT(0), double param2 CV_DEFAULT(0));
image,图像(必须是8位的)
line_storage,内存块
method,选择SHT(标准霍夫变换)或者PPHT(累计概率霍夫变换)
rho,分辨率(单位:像素)
theta,分辨率(单位:弧度)
threshold,认定为一条直线时在累计平面中必须达到的值
PPHT才用到param1和param2两个参数
param1,将要返回直线的最小长度
param2,设置为一条直线上分离线段不能练成一条直线的分隔像素点数
思路:
1.先将3通道的BGR彩图模糊化,次数根据实际需要而定
2.将模糊所得的图转为单通道灰度图
3.用cvCanny函数把边界提取出来
4.用cvHoughLines2函数提取直线
5.画出提取出来的直线
测试用图:
程序代码:
#include <highgui.h>
#include<cv.h>
#include <opencv2/legacy/legacy.hpp>
using namespace std;
int main()
{
IplImage *img_in = cvLoadImage("test.jpg");
IplImage *img_temp = cvCreateImage(cvGetSize(img_in),IPL_DEPTH_8U,1);
IplImage *img_canny = cvCreateImage(cvGetSize(img_in),IPL_DEPTH_8U,1);
IplImage *img_out = cvCreateImage(cvGetSize(img_in),IPL_DEPTH_8U,3);
CvSeq *lines;
cvNamedWindow("img_in",CV_WINDOW_AUTOSIZE);
cvShowImage("img_in",img_in);
cvSmooth(img_in,img_in,CV_GAUSSIAN,5,5);
cvSmooth(img_in,img_in,CV_GAUSSIAN,5,5);
cvCvtColor(img_in,img_temp,CV_BGR2GRAY);
cvNamedWindow("img_temp",CV_WINDOW_AUTOSIZE);
cvShowImage("img_temp",img_temp);
cvCanny(img_in,img_canny,50,200,3);
cvNamedWindow("img_canny",CV_WINDOW_AUTOSIZE);
cvShowImage("img_canny",img_canny);
CvMemStorage *storage = cvCreateMemStorage(0);
lines = cvHoughLines2(img_canny,storage,CV_HOUGH_PROBABILISTIC,1,CV_PI/180,10,30,5);
cvCvtColor(img_canny,img_out,CV_GRAY2BGR);
for(int i=0;i<lines->total;i++)
{
CvPoint* line = (CvPoint*)cvGetSeqElem (lines,i);
cvLine(img_out,line[0],line[1],CV_RGB(255,0,0),2,8);
}
cvNamedWindow("img_out",CV_WINDOW_AUTOSIZE);
cvShowImage("img_out",img_out);
cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&img_in);
cvReleaseImage(&img_temp);
cvReleaseImage(&img_canny);
cvReleaseImage(&img_out);
return 0;
}
运行结果: