matlab 实现透视变换 倾斜校正

说明:输入:四个点的坐标,输出:想要的矩形的大小。也就是对任意四边形都可以经过透视变换进行校正成你想要的矩形。(因为我处理的是视频,所以里面有循环进行校正的代码)
这是循环的处理视频的每一帧,对每一帧都进行相同的坐标校正,再保存。
下面是我处理之后的效果:
这是带有四个点的图片:code里面输入的就是这四个点的坐标(这里的坐标是指像素哦)
原始图片
下图是经过透视变换坐标校正之后的图片
坐标校正之后的图片

vedio_read.m文件

% 读取视频并输出图片的每一帧,进行坐标校正之后,再保存到文件夹里。
% fileName = 'step.avi';
fileName = 'suppleness.avi';
obj = VideoReader(fileName);

numFrames = obj.NumberOfFrames;% 帧的总数

 for k = 1 :numFrames % 读取数据
     frame = read(obj,k);
     image_pro = Test_perspectivetransformation(frame);
     imwrite(image_pro,strcat('image_supple\',num2str(k),'.jpg'),'jpg');% 保存帧
  
 end
% image_pro = Test_perspectivetransformation('image_supple\1,jpg');
% imshow(image_pro);
%  

m_PerspectiveTransformationTest.m文件

%函数功能:中心投影变换。输入源图,源图中的任意四边形的4个点的坐标(左上,右上,左下,右下),以及输出图像的大小(高,宽)
function Imgback = m_PerspectiveTransformationTest(imgIn,pointLT,pointRT,pointLB,pointRB,outHeitht,outWidth)
    [imgInHeight,imgInWidth,imgInDimension] = size(imgIn);
    %为了中心投影变换,需要将4个点转化为三个向量,具体看参考文献
    vector10 = pointLB - pointLT;
    vector01 = pointRT - pointLT;
    vector11 = pointRB - pointLT;
    %把vector11表示成vector10和vector01的线性组合,以使三个向量共面
    A = [vector10' , vector01'];
    B = vector11' ;
    S = A\B;
    a0 = S(1);
    a1 = S(2);
    
    
    %输出矩形
    Imgback = uint8(zeros(outHeitht,outWidth,imgInDimension));
    
    
    %利用循环操作来对每个像素点赋值
    for heightLoop = 1:outHeitht
        for widthLoop = 1:outWidth
            %以下算法为参考文献中的公式表示
            x0 = heightLoop/outHeitht;
            x1 = widthLoop/outWidth;
            FenMu = a0+a1-1+(1-a1)*x0+(1-a0)*x1;            %分母
            y0 = a0*x0/FenMu;
            y1 = a1*x1/FenMu;
            
            %根据得到的参数找到对应的源图像中的坐标位置,并赋值
            coordInOri = y0*vector10 + y1*vector01 + pointLT;
            heightC = round(coordInOri(1));
            widthC = round(coordInOri(2));
                if (heightC > imgInHeight || heightC <= 0 || widthC >imgInWidth || widthC <=0 )
                    disp(['m_PerspectiveTransformation超出范围' num2str(heightC) num2str(widthC)]);
                    pause();
                    return;
                end
            for dimentionLoop = 1:imgInDimension
                %使用最近邻域插值,使用高级插值方法效果会更好
                Imgback(heightLoop,widthLoop,dimentionLoop) = imgIn(heightC,widthC,dimentionLoop);
            end
        end
    end
    
    
%     figure; imshow(Imgback); title('投影变换的结果');
%函数功能:中心投影变换。输入源图,源图中的任意四边形的4个点的坐标(左上,右上,左下,右下),以及输出图像的大小(高,宽)
function Imgback = m_PerspectiveTransformation(imgIn,pointLT,pointRT,pointLB,pointRB,outHeitht,outWidth)
    [imgInHeight,imgInWidth,imgInDimension] = size(imgIn);
    %为了中心投影变换,需要将4个点转化为三个向量,具体看参考文献
    vector10 = pointLB - pointLT;
    vector01 = pointRT - pointLT;
    vector11 = pointRB - pointLT;
    %把vector11表示成vector10和vector01的线性组合,以使三个向量共面
    A = [vector10' , vector01'];
    B = vector11' ;
    S = A\B;
    a0 = S(1);
    a1 = S(2);
    
    m_PerspectiveTransformation.m文件 
    %输出矩形
    Imgback = uint8(zeros(outHeitht,outWidth,imgInDimension));
   
    %利用循环操作来对每个像素点赋值
    for heightLoop = 1:outHeitht
        for widthLoop = 1:outWidth
            %以下算法为参考文献中的公式表示
            x0 = heightLoop/outHeitht;
            x1 = widthLoop/outWidth;
            FenMu = a0+a1-1+(1-a1)*x0+(1-a0)*x1;            %分母
            y0 = a0*x0/FenMu;
            y1 = a1*x1/FenMu;
            
            %根据得到的参数找到对应的源图像中的坐标位置,并赋值
            coordInOri = y0*vector10 + y1*vector01 + pointLT;
            heightC = round(coordInOri(1));
            widthC = round(coordInOri(2));
                if (heightC > imgInHeight || heightC <= 0 || widthC >imgInWidth || widthC <=0 )
                    disp(['m_PerspectiveTransformation超出范围' num2str(heightC) num2str(widthC)]);
                    pause();
                    return;
                end
            for dimentionLoop = 1:imgInDimension
                %使用最近邻域插值,使用高级插值方法效果会更好
                Imgback(heightLoop,widthLoop,dimentionLoop) = imgIn(heightC,widthC,dimentionLoop);
            end
        end
    end
    
    
  % figure; imshow(Imgback); title('投影变换的结果');

这会输出校正过的视频的每一帧,下面附图片帧合并为视频的代码,其实是可以放在一起的,我懒得弄。自己合成一个整体就好了。

% 图片帧进行合成视频
myObj = VideoWriter('supple.avi');%目标视频路径及名称
open(myObj);
for i=1:351%逐帧加入视频中
      fname=strcat('image_supple\',num2str(i),'.jpg');
      frame = imread(fname);
      writeVideo(myObj,frame);
end
close(myObj);%关闭视频对象
  • 10
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 27
    评论
评论 27
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值