【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 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
伞伞悦读2 天前
【第38期】Python 模块与包详解:import、from、模块搜索路径、包结构和 __init__
开发语言·python
C语言小火车2 天前
C/C++ 为什么需要编译器?
开发语言·c++
霍霍的袁2 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
孙启超2 天前
【AI开发之Rust】第 11 课:智能指针与内部可变性
开发语言·后端·rust
此生决int2 天前
深入理解C++系列(20)——C++11(下)
开发语言·c++
CoderYanger3 天前
A.每日一题:835. 图像重叠
java·开发语言·程序人生·leetcode·面试·职场和发展·学习方法
伞伞悦读3 天前
【第37期】Python JSON 与配置详解:序列化、反序列化、嵌套结构和配置文件
开发语言·python·json
CCCCCCCCharlie3 天前
Linux进程控制四大核心操作
linux·开发语言
Brilliantwxx3 天前
【STM32】 SPI Flash 驱动开发实战:阻塞模式驱动 W25Q64(含工程代码)
开发语言·stm32·单片机·嵌入式硬件