图像处理 C语言 文本图像的倾斜校正

程序功能是把一副倾斜的文字图像矫正过来 这个程序,我熬了一夜

1、读取图像,创建结构元素

for(i=0;i<img.height;i++) //img.height 原图高度

{

for(j=0,n=0;n<img.width*3,j<img.width;n+=3,j++) //24位图像二值化处理img.width原图宽度

{

//gray 根据原图rgb值计算灰度值存在gray

gray= ((float)(img.image[lineBytes*i+n+2])+(float)(*(img.image+lineBytes*i+n+1))+(float)(*(img.image+lineBytes*i+n)))/3; //img.image原图数据lineBytes原图每行实际字节数

if(gray>120)

gray=255;

else gray=0;

grayPic[(img.height-i-1)*img.width+j]=(byte)gray; //经过二值化处理过的数据存放在grayPic中;

}

}


2、对图像进行膨胀处理,将断续的文字连成一条直线,便于直线检测

int num=10; //num 膨胀幅度

//水平方向 膨胀

for(i=0;i<img.height;i++)

{

for(j=(num-1)/2;j<(img.width-(num-1)/2)*3;j++)

{

for(k=-(num-1)/2;k<=(num-1)/2;k++)

{

n=*(grayPic+img.width*i+j+k); //从二值化数据取出数据

if(n==255)

{

*(temp3+img.width*i+j)=255; //水平方向膨胀的结果存在temp3

break;

}

}

}

}

num=10;

//对水平膨胀后进行垂直方向膨胀

for(i=(num-1)/2;i<img.height-(num-1)/2;i++)//img.height 原图高度

{

for(j=0;j<img.width*3;j++) //img.width原图宽度

{

for(k=-(num-1)/2;k<=(num-1)/2;k++)

{

n=*(temp3+img.width*(i+k)+j);//temp3中即水平膨胀后取出数据

if(n==255)

{

*(grayPic+img.width*i+j)=255;//膨胀的结果存在grayPic

break;

}

}

}

}


3、膨胀后边缘检测

for(i=3;i<img.height-2;i++) //img.height 原图高度 img.width原图宽度

for(j=3;j<img.width-2;j++) //logNum记录经过计算后的相应像素值

{ //grayPic 膨胀后数据存放的空间

logNum=16*grayPic[i*img.width+j]-grayPic[(i-2)*img.width+j]-grayPic[(i-1)*img.width+j-1]-2*grayPic[(i-1)*img.width+j]-grayPic[(i-1)*img.width+j+1]-grayPic[i*img.width+j-2]-2*grayPic[i*img.width+j-1]-2*grayPic[i*img.width+j+1]-grayPic[i*img.width+j+2]-grayPic[(i+1)*img.width+j-1]-2*grayPic[(i+1)*img.width+j]-grayPic[(i+1)*img.width+j+1]-grayPic[(i+2)*img.width+j];

if(logNum > 0)

lpDIBBits[i*img.width+j]=255;//lpDIBBits //边缘检测后存放的空间

else

lpDIBBits[i*img.width+j]=0;

}


4、对边缘点进行hough变换,找到最长线段的角度kmax

for(i=1;i<img.height;i++) //img.height原图高度

for(j=1;j<img.width;j++) //img.width 原图宽度

{

if(lpDIBBits[i*img.width+j]==255) //对边缘检测后的数据(存在lpDIBBits中)进行hough变化

{

for(k=1;k<ma;k++) //ma=180

{

p=(int)(i*cos(pi*k/180)+j*sin(pi*k/180));//p hough变换中距离参数

p=(int)(p/2+mp/2); //p值优化防止为负

npp[k][p]=npp[k][p]++; //npp对变换域中对应重复出现的点累加

}

}

}

kmax=0; //最长直线的角度

pmax=0; //最长直线的距离

n=0; //这一部分为寻找最长直线

for(i=1;i<ma;i++) //ma=180

for(j=1;j<mp;j++) //mp为原图对角线距离

{

if(npp[i][j]>yuzhi) //找出最长直线 yuzhi为中间变量用于比较

{

yuzhi=npp[i][j];

kmax=i; //记录最长直线的角度

pmax=j; //记录最长直线的距离

}

}


5、得到直线角度kmax,实际应该旋转地角度为kmax

6、用旋转函数旋转图像,并显示图像

RotateDIB(img,kmax);//RotateDIB为旋转函数,img中存放原图数据,kmax为旋转角度


若 感兴趣 可以联系 交流

猜你喜欢

转载自blog.csdn.net/qq_36449541/article/details/80206564