倾斜校正-表格图像的校正

方法一:直接寻找表格边框的倾斜角

如果表格中的水平边框能够很好经过预处理得到,那么通过定位这一边框。得到边框的起始点和斜率,就能得到相应的角度。通过角度就能够实现校正。

难点在于如何得到边框的起始点。起始点的特点是起点的行坐标最小,终点的列坐标最小。

方法二:采用熟悉的hough变换

倾斜校正前处理和后处理都是一致,区别在于怎么得到倾斜的角度,而倾斜的角度是通过倾斜的直线得到。关键就在于检测直线的方法。hough变换检测直线的原理其他地方有详细的介绍,这里结合matlab的函数做一个梳理。这里要用的三个函数是hough,houghpeaks,houghlines。

图像经hough后得到的是一个参数空间的矩阵,矩阵的每一个值是对应坐标处累加器的值,参数空间的划分在得到的另外两个向量theta,rho中体现。

在得到hough变换的矩阵后,houghpeaks就来检测矩阵中符合要求有可能是直线的参数点,当然阈值和检测的个数是可以自己设定的。这时得到的是峰值的横纵坐标。

得到峰值后就要确定每个峰值所确定的线段,houghlines就是用来完成这一工作的。houghlines返回的是关于一个线段的所有信息-两个点的横纵坐标和的值。

后续的工作就是遍历所有线段并显示出来,找到其中最长的一条。用这一条确定斜率,由斜率得到角度,然后进行旋转就可。

方法三:radon变换

Radon 变换检测倾斜角度的原理是:对倾斜的表格图像在一定的倾斜角度(0:179)范围内进行,然后查找使投影最大的那个角度。记录这一角度,就能够得到倾斜的角度。

%hough变换倾斜校正:
clc;
clear all;
[fn pn fi]=uigetfile('*.*','choose apicture');
Img=imread([pn fn]);
% Img=imrotate(Img,5,'bilinear');
 I =rgb2gray(Img);
figure;imhist(I);
bw = ~improve_hist(I);
figure;
imshow(bw);
 
BW=bw;
str=strel('line',20,0);
BW=imerode(BW,str);
str=strel('line',80,0);
BW=imdilate(BW,str);
% BW=edge(BW,'canny');
figure;
imshow(BW);title('canny 边界图像');
[H,T,R]=hough(BW);
figure,imshow(H,[],'XData',T,'YData',R,'InitialMagnification','fit');
xlabel('\theta'),ylabel('\rho');
axis on, axis normal,hold on;
P=houghpeaks(H,4,'threshold',ceil(0.3*max(H(:))));
x=T(P(:,2)); y = R(P(:,1));
plot(x,y,'s','color','white');
lines=houghlines(BW,T,R,P,'FillGap',50,'MinLength',7);
figure,imshow(BW),title('直线标识图像');
max_len = 0;
hold on;
for k=1:length(lines)
   xy=[lines(k).point1;lines(k).point2];
    %标出线段
   plot(xy(:,1),xy(:,2),'LineWidth',2,'Color','green');%[260,1;348,142]的第一列x值,第二列y值。绿色画出直线
    %标出线段的起始和终端点
   plot(xy(1,1),xy(1,2),'x','LineWidth',2,'Color','yellow');%线段的起点--黄色
   plot(xy(2,1),xy(2,2),'x','LineWidth',2,'Color','red');%线段的终点--红色
    len=norm(lines(k).point1-lines(k).point2);%计算矩阵的范数。
   Len(k)=len;
   if (len>max_len)
       max_len=len;
       xy_long=xy;
   end
end
% 强调最长的部分
plot(xy_long(:,1),xy_long(:,2),'LineWidth',2,'Color','blue');%最长的线段--蓝色。
[L1 Index1]=max(Len(:));
% 最长线段的起始和终止点
x1=[lines(Index1).point1(1)lines(Index1).point2(1)];
y1=[lines(Index1).point1(2)lines(Index1).point2(2)];
% 求得线段的斜率
K1=-(lines(Index1).point1(2)-lines(Index1).point2(2))/...
   (lines(Index1).point1(1)-lines(Index1).point2(1))
angle=atan(K1)*180/pi
A = imrotate(I,-angle,'bilinear','loose');%imrate 是逆时针的所以取一个负号
figure,
subplot(121);imshow(I);
subplot(122);imshow(A);
 
radon变换倾斜校正:
clc;
clear all;
close all;
[fn pn fi]=uigetfile('*.*','choose apicture');
Img=imread([pn fn]);
imshow(Img);title('Original image');
I = rgb2gray(Img);
I=improve_hist(I);
bw=edge(I,'canny');
theta=1:179;
[R,xp]=radon(bw,theta);
[I0,J]=find(R>=max(R(:)));%J记录了倾斜角
if J<=90
  qingxiejiao=J;
else
  qingxiejiao=J-180;
end
I1=imrotate(Img,-qingxiejiao,'bilinear','crop');
subplot(1,2,1),imshow(Img);title('Originalimage');
subplot(1,2,2),imshow(I1);title('correct image');
function [ b1 ] = improve_hist( f1 )
I=f1;
[m,n]=size(I);
I=double(I);
avg=mean(I(:));
mi=min(I(:));
p=0.45;
for i=1:m
for j=1:n
if I(i,j)>avg
I(i,j)=255;
else 
I(i,j)=(255-abs((((I(i,j)-avg)^p)*255)/(avg-mi)^p));
end 
end
end
mask=fspecial('log');
g=imfilter(I,mask,'replicate');
g=I-g;
g=im2uint8(g);
[~,re]=binary_iterate(g);
b1=re;
end

function [t b1 ] = binary_iterate( f1 )
% 用迭代的方法对图像进行二值化

t=mean(f1(:));                  
is_done=false;                        
count=0;                              
while ~is_done                         
    
    r1=f1(f1<=t);              
    r2=f1(f1>t); 
    temp1=mean(r1(:));              
    if isnan(temp1);                    
         temp1=0; 
    end 
    temp2=mean(r2(:));               
    if isnan(temp2)                      
         temp2=0; 
    end 
    t_new=(temp1+temp2)/2; 
    is_done=abs(t_new-t)<1;             
    t=t_new;                           
    count=count+1;                     
    if count>=1000                    
        Error='Error:Cannot find the ideal threshold.'  
        Return                       
    end 
end 


b1=im2bw(mat2gray(f1),t/256);
end
不能保证对其他图像也能取到好效果。
下载地址:http://pan.baidu.com/s/1kT3D3jp

  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值