(I)直线篇
1 直线是如何表示的?
对于平面中的一条直线,在笛卡尔坐标系中,常见的有点斜式,两点式两种表示方法。然而在hough变换中,考虑的是另外一种表示方式:使用(r,theta)来表示一条直线。其中r为该直线到原点的距离,theta为该直线的垂线与x轴的夹角。如下图所示。
在实际的直线检测情况中,如果超过一定数目的点拥有相同的(r,theta)坐标,那么就可以判定此处有一条直线。在r0theta 坐标系图中,明显的交汇点就标示一条检测出的直线。
如下图,可以判定出平面上的点共构成了两条直线,即检测出两条直线。
IplImage *pGrayImage = cvLoadImage("C:\\Users\\徐图之\\Desktop\\source.bmp", -1);
IplImage *pCannyImage = cvCreateImage(cvGetSize(pGrayImage), IPL_DEPTH_8U, 1);
cvCanny(pGrayImage, pCannyImage, 30, 90);
cvSmooth(pCannyImage, pCannyImage);
// 线段检测(只能针对二值图像)
CvMemStorage *pcvMStorage = cvCreateMemStorage();
double fRho = 1;
double fTheta = CV_PI / 180;
int nMaxLineNumber = 50; //最多检测条直线
double fMinLineLen = 150; //最小线段长度
double fMinLineGap = 10; //最小线段间隔
CvSeq *pcvSeqLines = cvHoughLines2(pCannyImage, pcvMStorage, CV_HOUGH_PROBABILISTIC, fRho, fTheta, nMaxLineNumber, fMinLineLen, fMinLineGap);
// 绘制线段
IplImage *pColorImage = cvCreateImage(cvGetSize(pGrayImage), IPL_DEPTH_8U, 3);
cvCvtColor(pCannyImage, pColorImage, CV_GRAY2BGR);
for (int i = 0; i < pcvSeqLines->total; i++)
{
CvPoint* line = (CvPoint*)cvGetSeqElem(pcvSeqLines, i);
cvLine(pColorImage, line[0], line[1], CV_RGB(255, 0, 0), 2);
}
cvNamedWindow("pstrWindowsSrcTitle", CV_WINDOW_AUTOSIZE);
cvShowImage("pstrWindowsSrcTitle", pGrayImage);
cvNamedWindow("pstrWindowsLineName", CV_WINDOW_AUTOSIZE);
cvShowImage("pstrWindowsLineName", pColorImage);
cvWaitKey(0);
cvReleaseMemStorage(&pcvMStorage);
cvDestroyWindow("pstrWindowsSrcTitle");
cvDestroyWindow("pstrWindowsLineName");
cvReleaseImage(&pGrayImage);
cvReleaseImage(&pCannyImage);
cvReleaseImage(&pColorImage);