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

操作:

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

输出:

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

相关推荐
蹊黎3 小时前
C++中vector类的部分简单实现
开发语言·c++·visual studio
程序猿追9 小时前
kotlin-retry 接入鸿蒙后,怎样确认它真的会停止重试
开发语言·kotlin·harmonyos
我是人✓9 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
智能直播9 小时前
网络RTMP拉流不卡顿、声音不同步,一文讲透缓冲区、时间戳
开发语言·ffmpeg·php·音视频·视频编解码
墨云安全10 小时前
内网资产无法暴露到公网,怎么做安全检测?2026 年内网渗透测试的落地路径
开发语言·安全·网络安全·渗透测试·php
摇滚侠10 小时前
《计算机是如何工作的:人人都能懂的计算机软硬件工作原理》第 9 章 机器码与汇编语言 阅读笔记 9
java·开发语言·笔记
Cc.Y10 小时前
Java零基础入门:深入Java核心:文件IO与序列化全解
java·开发语言·python
jimy111 小时前
c++的 Type Traits (一)
开发语言·c++
Web极客码12 小时前
Python Ollama 本地 Agent 入门与订单查询实践
开发语言·jvm·python
kimnoic13 小时前
PHP 8.2的DNF类型怎么用才规范
开发语言·php