算法——旋转正方形矩阵

本文介绍了一种将矩阵顺时针旋转90度的算法,通过内外圈逐层交换元素实现,额外空间复杂度为O(1),适用于正方形矩阵。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【题目】

  给定一个整型正方形矩阵matrix,请把该矩阵调整成 顺时针旋转90度的样子。

【要求】 额外空间复杂度为O(1)。

1  2  3                      7  4  1      
4  5  6         ------->     8  5  2
7  8  9                      9  6  3

 

思路:

先转外圈,后转内圈

1  3  9  7四个点相互交换位置。  1来到3的位置、3来到9的位置、9来到7的位置、7来到1的位置

2  6  8  4四个点相互交换位置。  2来到6的位置、6来到8的位置、8来到4的位置、4来到2的位置

3  9  7  1四个点相互交换位置。   3来到9的位置、9来到7的位置、7来到1的位置、1来到3的位置

 

/**
 * 矩阵转圈
 */
public class Rotate {
    public void rotate(int[][] matrix){
        int tR = 0;
        int tC = 0;
        int dR = matrix.length - 1;
        int dC = matrix[0].length - 1;
        while(tR < dR){
            rotate(matrix,tR++,tC++,dR--,dC--);
        }
    }

    private void rotate(int[][] matrix, int tR, int tC, int dR, int dC) {
        int time = dC - tC;
        int temp = 0;
        for(int i = 0 ; i != time ; i++){
            temp = matrix[tR][tC+i];
            matrix[tR][tC+i] = matrix[dR - i][tC];
            matrix[dR - i][tC] = matrix[dR][dC - i];
            matrix[dR][dC - i] = matrix[tR + i][dC];
            matrix[tR + i][dC] = temp;
        }
    }
}

 

 

 

 

<think>嗯,用户这次的问题是关于如何在Matlab中实现图像旋转并保持旋转后图像的幅面不变。看来用户对图像处理有一定需求,可能是科研或工程应用。之前我回复过LaTeX排版规范和快速排序的内容,但这次是全新的图像处理问题,需要完全从头构建答案。用户特别强调“保持幅面不变”,这意味着旋转后的图像不能有裁剪,整个原始图像内容都必须保留在画框内。这需要调整旋转后的画布尺寸。考虑到旋转后对角线方向尺寸最大,应该根据原始图像尺寸和旋转角度重新计算新画布大小。Matlab自带的imrotate函数虽然可以实现旋转,但默认会裁剪图像。不过它的crop参数选项正好能满足需求——设置crop可让输出图像包含完整的旋转后内容。这里需要解释清楚crop模式的工作原理:通过扩展画布来容纳旋转后新增的空白区域。用户可能是处理医学影像或遥感图像,这些领域经常需要无损旋转操作。在示例代码里应该展示完整的流程:读取图像、计算新尺寸、执行旋转、显示对比。为了更实用,最好补充边界填充方法的说明,比如常用的黑色填充和镜像填充的区别。注意用户要求“实验方法或代码”,说明需要实操性强的解决方案。除了基础示例,还应该提示扩展可能:比如处理多通道的RGB图像,以及避免插值伪影的注意事项。最后的性能分析建议可能对处理大图像的用户有帮助。</think> 在Matlab中实现图像旋转**保持幅面不变**(不裁剪原始内容)的关键是计算新的画布尺寸并使用`imrotate`的`'crop'`选项。以下是详细实现方法和代码: ```matlab % 读取图像 originalImg = imread('lena.jpg'); % 设置旋转角度 (单位:度) theta = 30; %% 核心算法: 计算新画布尺寸 [h, w, ~] = size(originalImg); diagonal = sqrt(h^2 + w^2); % 原始图像对角线长度 newSize = ceil([diagonal, diagonal]); % 新画布为正方形 %% 创建新画布并居中放置原图 offsetX = floor((newSize(2) - w)/2); % 水平居中偏移量 offsetY = floor((newSize(1) - h)/2); % 垂直居中偏移量 canvas = zeros([newSize, size(originalImg,3)], 'like', originalImg); canvas(offsetY:offsetY+h-1, offsetX:offsetX+w-1, :) = originalImg; %% 执行旋转并保持完整幅面 rotatedImg = imrotate(canvas, theta, 'bilinear', 'crop', 'loose'); %% 结果展示 figure; subplot(121), imshow(originalImg), title('原始图像'); subplot(122), imshow(rotatedImg), title(['旋转', num2str(theta), '° 保持幅面']); ``` ### 关键参数说明: 1. **'crop' 模式**: - `'crop'`:输出与输入尺寸相同(默认裁剪边缘) - `'loose'`:输出包含全部旋转内容(幅面不变的关键)[^1] 2. **插值方法**: - `'nearest'`:最近邻(速度快,锯齿明显) - `'bilinear'`:双线性(推荐平衡质量与速度) - `'bicubic'`:双三次(质量高但速度慢) 3. **尺寸计算原理**: 新画布边长需大于等于原始图像对角线长度$d$: $$d = \sqrt{w^2 + h^2}$$ 旋转后空白区域自动填充为黑色(可修改`canvas`初始值改变背景色) ### 效果对比: | 类型 | 常规旋转 | 幅面不变旋转 | |------|----------|--------------| | 结果 | ![裁剪旋转](https://via.placeholder.com/150?text=Cropped) | ![全幅旋转](https://via.placeholder.com/200?text=FullFrame) | | 特点 | 边缘丢失 | 保留全部信息 | | 存储 | 尺寸不变 | 尺寸增大约$\sqrt{2}≈1.41$倍 | ### 扩展应用: ```matlab % 修改背景色为白色 canvas = ones([newSize, size(originalImg,3)], 'like', originalImg)*255; % 处理RGB图像 (需保持三维矩阵结构) if size(originalImg,3)==3 % 代码自动支持RGB end % 高质量旋转 (抗锯齿) rotatedImg = imrotate(canvas, theta, 'bicubic', 'crop', 'loose'); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值