电脑没装PS,只能拿MATLABP个图了

目录

前言

fitgeotrans 求变换矩阵

imwarp 根据变换信息转换图像

imref2d

程序

前言

差不多两个月没写了,要毕业了,写毕业论文,腾不出来心思写东西。

今天,在写毕业论文时需要插一个实验材料(一块钢板)的图片,我翻了翻相册,发现之前做实验时拍的不好,钢板放歪了,如图1-1所示。

图1-1 放歪的实验钢板

Fig1.1 @#$&^&*(&^&^

这直接插到论文里不太好,还是想把它给放正了。于是在网上搜“怎么把图片中的物体摆正”,结果都是用PS做的

我电脑没装PS啊

我就想了想,这玩意不就是做一个透视变换么?MATLAB有现成的工具箱能用啊,哎,还是花几分钟写几行MATLAB程序处理一下吧

老早前看过一点点MATLAB图像处理的书,对一些函数和概念还有一些模糊的印象

下面先介绍三个关键的函数/类,然后再给出程序。

fitgeotrans 求变换矩阵

Fit geometric transformation to control point pairs

tform = fitgeotrans(movingPoints,fixedPoints,transformationType) 

takes the pairs of control points, movingPoints and fixedPoints, and uses them to infer the geometric transformation specified by transformationType.

这个函数需要:

  1. movingPoints 原图中的几个控制点(根据需要选取);

  2. fixedPoints 变换后的控制点;

  3. transformationType 变换的类型。

返回一个对象,包含了变换矩阵的信息。

这里我要做的是透视变换(透视变换等价于中心投影变换),所以transformationType就选取projective,别的就不说了。

有个需要注意的(后面会用到),我们选择的第一个控制点对应的变换后的点,是变换后的图像的世界坐标系的原点(时间久了,不确定是不是这么说的,反正我记得是这么理解的)。

图2-1 图像的世界坐标系

Fig2.1 ^&*#%&#%$&*#

imwarp 根据变换信息转换图像

Apply geometric transformation to image

B = imwarp(A,tform, Name, Value)

transforms the numeric, logical, or categorical image A according to the geometric transformation tform. The function returns the transformed image in B. Specifies name-value pair arguments to control various aspects of the geometric transformation.

这个就根据上面计算出来的包含变换矩阵信息的对象tform将图像A变换成图像B。通过指定Name-Value可以设置一些转换的效果。

Name-Value这我就用了'OutputView'这个属性,还有两个我没用上,大家可以自己看看帮助文档。

B = imwarp(A,tform, 'OutputView', imref2d)

imref2d 是一个类,下面单独介绍一下

imref2d

Reference 2-D image to world coordinates

An imref2d object stores the relationship between the intrinsic coordinates anchored to the rows and columns of a 2-D image and the spatial location of the same row and column locations in a world coordinate system.
The image is sampled regularly in the planar world-x and world-y coordinate system such that intrinsic-x values align with world-x values, and intrinsic-y values align with world-y values. The resolution in each dimension can be different.

这是一个MATLAB的类,我用的时候就关注了它的三个properties,别的也没多想:

  1. ImageSize:设置一下转化后的图像的长和宽

  2. XWorldLimits:设置图像的世界坐标系X方向的范围

  3. YWorldLimits:设置一下图像的世界坐标系Y方向的范围
    只显示XWorldLimits和YWorldLimits范围内的图像。

世界坐标系的原点就是我们开始时选的第一个控制点

程序

clc
clear
close all

%%  读入图片
pic = imread('perspective.jpg');

%%  显示原图
fig1 = figure('Name', 'Original', 'ToolBar', 'none');
ax1 = axes('Parent', fig1, 'NextPlot', 'add');
imshow(pic, 'Parent', ax1);

%%  标定顶点,逆时针(如果 顺时针结果不大对劲,可能是我再后面的控制点没对应上)
coor1 = ginput(1); %  左下
scatter(coor1(1), coor1(2), 'Marker', 'o', 'MarkerFaceColor', 'r', 'Parent', ax1);

coor2 = ginput(1); %  右下
scatter(coor2(1), coor2(2), 'Marker', 'o', 'MarkerFaceColor', 'r', 'Parent', ax1);
line([coor1(1), coor2(1)], [coor1(2), coor2(2)], 'Color', 'k', 'LineWidth', 2);

coor3 = ginput(1); %  右上
scatter(coor3(1), coor3(2), 'Marker', 'o', 'MarkerFaceColor', 'r', 'Parent', ax1);
line([coor2(1), coor3(1)], [coor2(2), coor3(2)], 'Color', 'k', 'LineWidth', 2);

coor4 = ginput(1); %  左上
scatter(coor4(1), coor4(2), 'Marker', 'o', 'MarkerFaceColor', 'r', 'Parent', ax1);
line([coor3(1), coor4(1)], [coor3(2), coor4(2)], 'Color', 'k', 'LineWidth', 2);
line([coor4(1), coor1(1)], [coor4(2), coor1(2)], 'Color', 'k', 'LineWidth', 2);

coors = [coor1; coor2; coor3; coor4];

%  计算图中的物体的长宽,用于算出变换后的坐标
width = sqrt(sum( (coor2 - coor1).^2) );
height = sqrt(sum( (coor4 - coor1).^2) );

%%  根据图中物体的长宽,计算出投影变换后的大致的 与上述标定顶点 对应的坐标点
base_coors = [1, 1; ...
    width+1, 1; ...
    width+1, height+1; ...
    1, height+1];

%%  获取变换矩阵
%  根据变换前和变换后的点计算出变换矩阵
tform = fitgeotrans(coors, base_coors, 'projective');
%%  根据变换矩阵求出变换后的结果,并裁剪出我们想要的部分
%  第一个标定的点是世界坐标系的原点
output_view = imref2d;
output_view.ImageSize = [fix(height), fix(width)];  %  高是多少行,宽是多少列
output_view.XWorldLimits = [1, width+1];  %  世界坐标系 x 的范围(多宽)
output_view.YWorldLimits = [1, height+1]; %  世界坐标系 y 的范围(多高)
pic_perspective = imwarp(pic, tform, 'OutputView', output_view); % ,'XData',[1 width+1],'YData',[1 height+1]

%%  显示变换后的结果
fig2 = figure('Name', 'Perspective');
ax2 = axes('Parent', fig2, 'NextPlot', 'add');
imshow(pic_perspective, 'Parent', ax2);

测试结果1:

看上去还凑合吧,下面我再拿我的一卡通试试看看。

测试结果2:

这还行

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值