【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);

操作:

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

输出:

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

相关推荐
qq_4069810311 分钟前
c++拷贝构造函数
开发语言·c++
爱喝雪碧的可乐37 分钟前
MATLAB
开发语言·算法·matlab
H.莓飛2 小时前
【C++】【STL】vector_OJ题
linux·服务器·开发语言·数据结构·c++·visual studio
严肃小白兔3 小时前
MATLAB 优秀开源项目与工具箱推荐:涵盖通信、图像处理、脑机接口等九大领域
图像处理·matlab·信息与通信·开源项目
j7~4 小时前
【C++ 八股文】(篇四)C++11 新特性
开发语言·c++·面试·c++11·八股文
eggwyw4 小时前
C++中大括号的用法合集
开发语言·c++
xiaoye-duck4 小时前
《C++ 项目:手写大模型接入 SDK》本地 Ollama 部署与适配
开发语言·网络·c++·语言模型
联犀4 小时前
联犀 Go SIMD 实战:视频转码从 16.5ms 到 5.46ms
开发语言·golang·音视频
octopus_c4 小时前
STL 之 string:auto 与范围 for、常用接口、模拟实现与深浅拷贝
开发语言·c++·算法
Nerd(BUG版)5 小时前
KMP学习day5--Kotlin Flow异步流基础
开发语言·学习·kotlin