程序功能是把一副倾斜的文字图像矫正过来 这个程序,我熬了一夜
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为旋转角度
若 感兴趣 可以联系 交流