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

来源:互联网 发布:手机淘宝店铺怎么注册 编辑:程序博客网 时间:2024/04/29 20:13

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

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

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

方法二:采用熟悉的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;   endend% 强调最长的部分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/piA = 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;endI1=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:mfor j=1:nif I(i,j)>avgI(i,j)=255;else I(i,j)=(255-abs((((I(i,j)-avg)^p)*255)/(avg-mi)^p));end endendmask=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

原创粉丝点击