下图可以用于解释以上代码:CvPoint pt01,pt02;
//确定直线上的两个点,取1000是因为它足够大,可以确保这两个点在图像外
pt01.x=cvRound(rho*cos(theta)-1000*sin(theta));
pt01.y=cvRound(rho*sin(theta)+1000*cos(theta));
pt02.x=cvRound(rho*cos(theta)+1000*sin(theta));
pt02.y=cvRound(rho*sin(theta)-1000*cos(theta));
float theta_save[10]={0}; //用于保存确定下来的车道线的角度和rho,用于剩余的检测到的线比较,去重复
float rho_save[10]={0};
int num_line=0; //车道线计数
int line_true=0; //是否画车道线的标志位
CvSeq* lines = 0;
IplImage *color_backImage;
cvThreshold(pBkMat,pFtImg,180,255.0,CV_THRESH_BINARY);//二值化背景,得到车道
cvCanny(pFtImg,pFtImg,30,150,3); //边缘检测
unsigned char* i_data=(unsigned char *)pFtImg->imageData; //像素数据的首地址
for(int m_h=0;m_h<(pFtImg->height)/2;m_h++) //仅保留图像下半部分的数据,上半部分干扰太多
for(int n_w=0;n_w<pFtImg->width;n_w++)
i_data[m_h*pFtImg->widthStep+n_w]=0;
lines = cvHoughLines2( pFtImg, storage, CV_HOUGH_STANDARD, 1, CV_PI/180,60, 0, 0 );//用Hough变换检测直线
color_backImage = cvCreateImage( cvGetSize(pFtImg), 8, 3 );
cvCvtColor( pFtImg, color_backImage, CV_GRAY2BGR ); //注意:在灰度图上不能画彩色线,因此要把单通道图转为3通道图
cvNamedWindow("background",1);
for(int o=0;o<MIN(lines->total,100);o++)
{
float* line = (float*)cvGetSeqElem(lines,o); //获取该直线的参数,rho和角度theta
float rho=line[0];
float theta=line[1];
line_true=1;
if(o!=0)
{
for(int p_line=0;p_line<num_line;p_line++)
{//根据第2问中的方法去重复
if( (abs(theta_save[p_line]*180/CV_PI-theta*180/CV_PI)<10) && (abs(rho_save[p_line]-rho)<30) )
{
line_true=0;
break;
}
}
}
if(line_true==1)
{
theta_save[num_line]=theta; //将确定的车道线保存到数组
rho_save[num_line]=rho;
num_line++;
CvPoint pt01,pt02;//确定直线上的两个点,取1000是因为它足够大,可以确保这两个点在图像外
pt01.x=cvRound(rho*cos(theta)-1000*sin(theta));
pt01.y=cvRound(rho*sin(theta)+1000*cos(theta));
pt02.x=cvRound(rho*cos(theta)+1000*sin(theta));
pt02.y=cvRound(rho*sin(theta)-1000*cos(theta));
cvLine( color_backImage, pt01, pt02, CV_RGB(0,0,255), 1, CV_AA, 0 );
cvShowImage("background",color_backImage);
}
//sprintf(CntC,"%f\n%f\n",theta*180/CV_PI,rho); //for debug
// AfxMessageBox(CntC);
}