C++ 霍夫直线检测

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

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

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

待检测图像:

C++ 霍夫直线检测_第1张图片

程序输出图像:

C++ 霍夫直线检测_第2张图片

程序的主要步骤:

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<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=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");
}


你可能感兴趣的:(图形学)