c语言 霍夫变换检测直线,C++ 霍夫直线检测

霍夫变换原理参考:http://blog.csdn.net/jia20003/article/details/7724530

位图文件格式参考:http://www.cnblogs.com/kingmoon/archive/2011/04/18/2020097.html

本程序用标准C++语法读取读取一张400*400大小的单色图片,并用霍夫变换检测其中的直线。

待检测图像:

0818b9ca8b590ca3270a3433284dd417.png

程序输出图像:

0818b9ca8b590ca3270a3433284dd417.png

程序的主要步骤:

1,读入一个400*400的单色位图,找到数据区,赋值到一个二维矩阵 pic【400】【400】。

2,从0度到180度枚举角度theta,对pic【400][400]做霍夫变换并提取theta角度下长度达到thrd个连续像素点的线段,把线段中的点赋值到 pic2【400】【400】中。

3,依据pic2【400】【400】写文件lineout.bmp。

程序里有两个小麻烦:

1,由于单色位图每个像素只占1bit,C语言中最小的数据类型(char,bool)也占一字节,所以要整字节读出,并作位分离,处理完后又要做位合并再写图像

2,每行像素为400个,400 /8=50字节,但是通过ultraEdit观看发现实际每行像素用了52字节,大概每行要四字节对齐吧,因为50不是4的倍数,所以补到52字节。

代码:

#include

#include

#define PI acos(-1.0)

using namespace std;

int pic[400][400];

int pic2[400][400];

int bit_test[8]={1,2,4,8,16,32,64,128};

struct pos{int x,y;};

pos RT[600][600];

int RTnum[600];

float mysin[360],mycos[360];

void init_sincos()

{

for(int i=0;i<360;i++)

{

mysin[i]=sin(float(i)*PI/180.0);

mycos[i]=cos(float(i)*PI/180.0);

}

}

bool adjacent(pos a,pos b)

{

if(abs(a.x-b.x)<=2&&abs(b.y-a.y)<=2)

return 1;

return 0;

}

void txtshow()

{

int i,j,k;

freopen("out.txt","w",stdout);

for(i=0;i<400;i++)

{

for(j=0;j<50;j++)

{

for(k=0;k<8;k++)

{

cout<

}

}

cout<

}

fclose(stdout);

system("out.txt");

}

int main()

{

int i,j,k,row,col;

init_sincos();

//读取图片

char *p_img_path="line.bmp";

char img_path[100];

int plen=strlen(p_img_path);

for(i=0;i<=plen;i++)

img_path[i]=p_img_path[i];

char* pchBuf = NULL;

int nLen=62+400*52;

pchBuf=(char*)malloc(nLen+1);

FILE *pF=fopen(img_path,"rb");

nLen=fread(pchBuf,1,nLen,pF);

//图片转存到pic数组中 ,图像在位图数据区中其实是上下颠倒的。

for(i=0;i<400;i++)

{

for(j=0;j<50;j++)

{

for(k=0;k<8;k++)

{

pic[399-i][8*j+k]=((pchBuf[62+i*52+j]&bit_test[7-k])>0);

}

}

}

//txtshow();

//图像修改

double r,theta;

int intr;

for(k=0;k<=180;k++)

{

for(i=0;i<600;i++)

RTnum[i]=0;

//寻找角度为theta的边,边长为r

for(i=0;i<400;i++)//i 行号,y

{

for(j=0;j<400;j++)//j 列号,x

{

if(pic[i][j]==1)

continue;

r=mysin[k]*float(i)+mycos[k]*float(j);

intr=fabs(r);

RT[intr][RTnum[intr]].x=j;

RT[intr][RTnum[intr]].y=i;

RTnum[intr]++;

}

}

//找完直线显示

pos a,b;

int s1,s2,pnum;

int thrd=30;

for(intr=0;intr<600;intr++)

{

if(RTnum[intr]>=thrd)

{

s1=s2=0;

pnum=1;

a=RT[intr][0];

for(i=1;i

{

b=RT[intr][i];

if(adjacent(a,b))

{

pnum++;

}

else

{

s2=i-1;

if(pnum>=thrd)

{

for(j=s2-pnum+1;j<=s2;j++)

{

pic2[RT[intr][j].y][RT[intr][j].x]=1;

}

}

pnum=1;

}

a=b;

}

if(pnum>=thrd)

{

s2=i-1;

for(j=s2-pnum+1;j<=s2;j++)

{

pic2[RT[intr][j].y][RT[intr][j].x]=1;

}

}

}

}

}

fclose(stdout);

//保存到图像

FILE *pF2=fopen("outline.bmp","wb");

for(i=0;i<62;i++)

fputc(pchBuf[i],pF2);//转存图像文件头

for(i=0;i<400;i++) //转存图像像素信息

{

for(j=0;j<50;j++)

{

char tempc=0;

for(k=0;k<8;k++)

{

tempc+=pic2[399-i][8*j+k]*bit_test[7-k];

}

fputc(~(tempc),pF2);

}

fputc(0,pF2);fputc(0,pF2);

}

fclose(pF);

free(pchBuf);

fclose(pF2);

system("outline.bmp");

}

你可能感兴趣的:(c语言,霍夫变换检测直线)