自己写的简单Hough变换用于检测直线的代码,主要用于更好的理解基于概率的Hough变换的原理。
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#define PI 3.14
typedef struct {
int leftx;
int lefty;
int rightx;
int righty;
}Line;
/*
Houth Transform uses to detect line
Input:
src:Binary Image(gray value is 0 or 255)
nThreshold:The threshold of the number of points in a line.
*/
void Hough(IplImage *src,int nThreshold)
{
int **pArray;
/*pArray[i][j] represent the nums of line's(in parameter coordinate)
angle is i and the distance to origin is j.*/
int nDistMax = (int)cvSqrt((float)(src->width * src->width +
src->height * src->height)) + 1;
// nDistMax is the length of the diagonal
int nAngleMax = 361;
int nAngle;
int nDist;
int i,j;
Line *LineArray;
float Sin[361];
float Cos[361];
IplImage * pColourImg = cvCreateImage(cvGetSize(src),src->depth,3);
cvConvertImage(src,pColourImg);
pArray = new int*[nAngleMax];
for(i=0;i<nAngleMax;i++)
{
pArray[i] = new int[nDistMax];
memset(pArray[i],0,nDistMax*sizeof(int));
}
LineArray = new Line[nAngleMax*nDistMax];
for(i=0;i<nAngleMax*nDistMax;i++)
{
LineArray[i].leftx= 32767;
LineArray[i].rightx= -1;
}
float fRate = (float)(PI/180);
for (i=0;i<nAngleMax;i++)
{
Sin[i]=sin(i*fRate);
Cos[i]=cos(i*fRate);
}
uchar *buf = (uchar *)src->imageData;
int step = src->widthStep;
for (int y = 0; y < src->height; y++)
{
for (int x = 0; x < src->width; x++)
{
if(buf[y*step+x]==255)
{
//nAngle is the angle of line
for(nAngle = 0; nAngle<nAngleMax; nAngle++)
{
nDist = (int)(x * Cos[nAngle] + y * Sin[nAngle]);
//nDist is the distance of line to origin
if(nDist > 0)
{
pArray[nAngle][nDist]++;
//leftx=rightx,lefty=righty,at the first time
if(x<LineArray[nAngle*nDistMax+nDist-1].leftx)
{
LineArray[nAngle*nDistMax+nDist-1].leftx = x;
LineArray[nAngle*nDistMax+nDist-1].lefty = y;
}
if(x>LineArray[nAngle*nDistMax+nDist-1].rightx)
{
LineArray[nAngle*nDistMax+nDist-1].rightx = x;
LineArray[nAngle*nDistMax+nDist-1].righty = y;
}
//the line and the Y-axis are parallel Lines
if(x==LineArray[nAngle*nDistMax+nDist-1].leftx)
{
if(y<LineArray[nAngle*nDistMax+nDist-1].lefty)
{
LineArray[nAngle*nDistMax+nDist-1].leftx = x;
LineArray[nAngle*nDistMax+nDist-1].lefty = y;
}
if(y>LineArray[nAngle*nDistMax+nDist-1].righty)
{
LineArray[nAngle*nDistMax+nDist-1].rightx = x;
LineArray[nAngle*nDistMax+nDist-1].righty = y;
}
}
}
}
}
} // x
} // y
for(i=0;i<nAngleMax;i++)
{
for(j=0;j<nDistMax;j++)
{
if(pArray[i][j]>nThreshold)
{
/*
A line is exit,the angle is i,the distance to origin is j.
there are pArray[i][j] points in the line.
*/
CvPoint pt1,pt2;
pt1.x = LineArray[i*nDistMax+j].leftx;
pt1.y = LineArray[i*nDistMax+j].lefty;
pt2.x = LineArray[i*nDistMax+j].rightx;
pt2.y = LineArray[i*nDistMax+j].righty;
cvLine(pColourImg,pt1,pt2,CV_RGB(255,0,0),1,8,0);
}
}
}
for(i=0;i<nAngleMax;i++)
{
delete []pArray[i];
}
delete []pArray;
delete []LineArray;
cvNamedWindow("Hough");
cvShowImage("Hough",pColourImg);
return;
} // end of Hough
void main()
{
IplImage *src = cvLoadImage("D:\\xgmiao\\image\\1.jpg",0);
IplImage *dst = cvCreateImage(cvGetSize(src),8,1);
cvCanny(src,dst,50,200,3);//edge detection and get binary Image dst.
cvNamedWindow("dst");
cvShowImage("dst",dst);
Hough(dst,80);
cvNamedWindow("src");
cvShowImage("src",src);
cvWaitKey(0);
return ;
}
结果如下:
通过与上一篇博文中直接用Opencv自带的cvHoughLines函数对比,会发现,本程序有问题,该代码中并没有考虑直线的连接性。