图像倾斜校正_基于MATLAB
目的:
实现对图像的倾斜校正。
方法一:
利用霍夫变换,代码如下: clear,clc,close all; I=imread('1.jpg'); bw=rgb2gray(I);
bw=im2bw(I,graythresh(bw)); bw=double(bw);
BW=edge(bw,'canny');
imshow(BW);title('canny 边界图像'); [H,T,R]=hough(BW);
figure,imshow(H,[],'XData',T,'YData',R,'InitialMagnification','fit'); xlabel('\heta'),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'); % 标出线段的起始和终端点
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');% imrate 是逆时针的所以取一个负号 figure,imshow(A); 结果:
方法二:
由于这里的图形比较规则,可针对性地对图形进行边缘检测,求倾斜角,再根据角度进行校正。代码如下:
clear all; clc; close all; Img = imread('c:\\\\ce.jpg'); figure;
subplot(2, 2, 1); imshow(Img); title('原图'); I = rgb2gray(Img);
subplot(2, 2, 2); imshow(I); title('灰度图像'); bw = im2bw(I, graythresh(I)); bw = edge(bw, 'canny');
subplot(2, 2, 3); imshow(bw); title('canny边界图像'); [r, c] = find(bw); [rmin, indr] = min(r);
[cmin, indc] = min(c); p1 = [rmin, c(indr)]; p2 = [r(indc) cmin]; hold on;
plot([p1(2) p2(2)], [p1(1) p2(1)], 'r-o'); k = (p2(1)-p1(1))/(p2(2)-p1(2)); theta = atan(k)/pi*180;
I1(:, :, 1) = imrotate(Img(:, :, 1), theta, 'bilinear'); I1(:, :, 2) = imrotate(Img(:, :, 2), theta, 'bilinear'); I1(:, :, 3) = imrotate(Img(:, :, 3), theta, 'bilinear'); subplot(2, 2, 4); imshow(I1); title('摆正图像'); 结果:
方法三:
跟方法二一个原理,只是这个看着更简洁一些,代码如下: clear,clc,close all; I=imread('1.jpg');
imshow(I);title('Original image');
gray=rgb2gray(I);figure,imshow(gray);title('Grayscale image'); bw=edge(gray,'canny'); theta=1:180;
[R,xp]=radon(bw,theta);
[I0,J]=find(R>=max(max(R)));%J记录了倾斜角 qingxiejiao=90-J
I1=imrotate(I,qingxiejiao,'bilinear','crop'); figure,imshow(I1);title('correct image'); 结果:
方法四:
还是基于角度的分析,这里是检测最佳边缘,对角度一点点微调,直到最合适,代码如下: clear,clc,close all; I=imread('1.jpg');
imshow(I);title('original image'); Maxa=1;Angle=1;
for a=-40:40 %旋转,找出最大的s(a)作为旋转地角度 Tempbw1=imrotate(I,a,'bilinear');%bw2为二值图像旋转 gray=rgb2gray(Tempbw1);
bw=im2bw(gray,graythresh(gray)); bw=double(bw);
Tempbw2=edge(bw,'canny',0.2);%取旋转后的边缘图像 s(Angle)=sum(sum(Tempbw2));%各行水平投影总和 if s(Angle)>=s(Maxa)%如果s(a)增大记录角度angle Maxa=Angle; angle=a; end
Angle=Angle+1; end angle
goal=imrotate(I,angle,'bilinear'); figure,imshow(goal); 结果:
希 望 对 大 家 有 帮 助 !