【matlab】坐标图四角畸变矫正代码

如图所示,是拍摄一个平面显示器的坐标图,该坐标图由于"近大远小"、摄像机旋转等操作变得"畸形",希望能够手动拾取这个坐标图的四个角点,然后自动"畸变矫正",输出严格的平面图

主代码

matlab 复制代码
clc;
clear;
close all;

%% 1. 读取图像
[filename, pathname] = uigetfile({'*.png;*.jpg;*.jpeg;*.bmp;*.tif','图像文件 (*.png,*.jpg,*.jpeg,*.bmp,*.tif)'}, '选择要矫正的图像');
if isequal(filename, 0)
    disp('用户取消选择');
    return;
end
img = imread(fullfile(pathname, filename));

%% 2. 显示图像并手动拾取四个角点
figure('Name', '畸变矫正 - 拾取角点', 'NumberTitle', 'off', 'Color', 'w');
imshow(img);
title('请按顺序点击四个角点:左上 -> 右上 -> 右下 -> 左下(点击4次后自动继续)');
hold on;

% 拾取 4 个角点(ginput 为基础函数,无需额外工具箱)
[x, y] = ginput(4);

if length(x) < 4
    error('必须选择4个角点!');
end

% 可视化确认选中的区域
corners = [x, y; x(1), y(1)]; % 闭合
plot(corners(:,1), corners(:,2), 'r-o', 'LineWidth', 2, ...
    'MarkerSize', 10, 'MarkerFaceColor', 'r');
text(x(1), y(1), ' 左上', 'Color', 'g', 'FontSize', 14, 'FontWeight', 'bold');
text(x(2), y(2), ' 右上', 'Color', 'g', 'FontSize', 14, 'FontWeight', 'bold');
text(x(3), y(3), ' 右下', 'Color', 'g', 'FontSize', 14, 'FontWeight', 'bold');
text(x(4), y(4), ' 左下', 'Color', 'g', 'FontSize', 14, 'FontWeight', 'bold');
hold off;
drawnow;

%% 3. 定义投影变换参数
% 畸变图中的四个角点(movingPoints)
movingPoints = [x, y];

% 根据原四边形边长估算输出矩形尺寸(像素)
w1 = sqrt((x(2)-x(1))^2 + (y(2)-y(1))^2); % 上边
w2 = sqrt((x(3)-x(4))^2 + (y(3)-y(4))^2); % 下边
h1 = sqrt((x(4)-x(1))^2 + (y(4)-y(1))^2); % 左边
h2 = sqrt((x(3)-x(2))^2 + (y(3)-y(2))^2); % 右边

outputWidth  = round(max(w1, w2));
outputHeight = round(max(h1, h2));

% 矫正后的目标矩形角点(fixedPoints),左上为 (1,1)
fixedPoints = [
    1, 1;                           % 左上
    outputWidth, 1;                 % 右上
    outputWidth, outputHeight;      % 右下
    1, outputHeight                 % 左下
];

% 计算投影变换矩阵
tform = fitgeotrans(movingPoints, fixedPoints, 'projective');

%% 4. 执行畸变矫正
outputView = imref2d([outputHeight, outputWidth]);
img_rectified = imwarp(img, tform, 'OutputView', outputView);

%% 5. 显示并保存结果
figure('Name', '矫正结果', 'NumberTitle', 'off', 'Color', 'w');
imshow(img_rectified);
title('畸变矫正后的平面图');

[~, name, ext] = fileparts(filename);
outputName = fullfile(pathname, [name '_rectified' ext]);
imwrite(img_rectified, outputName);
fprintf('矫正完成!图像已保存至:\n  %s\n', outputName);

操作:

按照顺时针顺序依次拾取左上、右上、右下、左下点即可:

输出:

与原图(如下所示)比较,二者形状一致:

相关推荐
格林威2 小时前
多相机并行采图最佳实践:Task.WhenAll + 异常处理 + 资源释放
开发语言·人工智能·数码相机·计算机视觉·c#·视觉检测·机器视觉
djjjx.2 小时前
【 C++ 】多态
开发语言·c++·多态
夜雪一千2 小时前
Python如何使用XPath定位没有特征的元素?无id、无class通用定位技巧
开发语言·python
艾莉丝努力练剑2 小时前
【QT:解决问题】Qt5Core.dll:无法定位程序输入点
java·开发语言·qt·学习·面试
流浪0012 小时前
Python 基础语法(一):常量、变量、输入输出与运算符
开发语言·python
光影少年3 小时前
react离线缓存、图片缓存方案
开发语言·前端·javascript·react native·react.js·缓存·前端框架
SomeB1oody3 小时前
【RustyML入门】3.7. 循环层
开发语言·后端·机器学习·rust·教程
言乐66 小时前
Python游戏水平测试辅助系统
开发语言·python·游戏·django·pygame
WWJA王文举13 小时前
I²C通信完整流程详解:START、地址、ACK、数据、Repeated START和STOP一次讲透
c语言·开发语言
zhanghaha131413 小时前
Python进阶教程:6_JSON 数据解析 —— 新手完全指南
开发语言·python·json