C#でn×nの行列を90度回転させる方法をわかりやすく解説
n×nの行列には、合計で n/2 個の「正方形(リング)」が存在し、ネストされたループを使って各リングを1つずつ処理することで回転を実現できます。各リング内では、要素が4つ1組のサイクルで移動するため、そのサイクルごとに要素を反時計回りに入れ替えていきます。
要素の移動ルール
各サイクルにおける要素の移動先は以下の通りです。
- 位置
(n-1-j, i)の要素は、位置(i, j)へ移動 - 位置
(i, j)の要素は、位置(j, n-1-i)へ移動 - 位置
(j, n-1-i)の要素は、位置(n-1-i, n-1-j)へ移動 - 位置
(n-1-i, n-1-j)の要素は、位置(n-1-j, i)へ移動
C#での実装例
using System;
using System.Text;
namespace ConsoleApplication{
public class Matrix{
public void RotateMatrixBy90Degree(int[] matrix){
int n = matrix.GetLength(0);
for (int i = 0; i < n / 2; i++){
for (int j = i; j < n - i - 1; j++){
int top = matrix[i, j];
// 左側の要素を上へ移動
matrix[i, j] = matrix[n - 1 - j, i];
// 下側の要素を左へ移動
matrix[n - 1 - j, i] = matrix[n - i - 1, n - 1 - j];
// 右側の要素を下へ移動
matrix[n - i - 1, n - 1 - j] = matrix[j, n - i - 1];
// 上側の要素を右へ移動
matrix[j, n - i - 1] = top;
}
}
for (int i = 0; i < n; i++){
StringBuilder s = new StringBuilder();
for (int j = 0; j < n; j++){
s.Append(matrix[i, j] + " ");
}
Console.WriteLine(s);
s = null;
}
}
}
class Program{
static void Main(string[] args){
Matrix m = new Matrix();
int[] matrix = { { 5, 1, 9, 11 }, { 2, 4, 8, 10 }, { 13, 3, 6, 7 }, { 15, 14, 12, 16 } };
m.RotateMatrixBy90Degree(matrix);
}
}
}実行結果
15 13 2 5 14 3 4 1 12 6 8 9 16 7 10 11
アルゴリズムのポイント
この手法の計算量は O(n²) であり、追加の行列を作成せずに元の配列を直接書き換える「インプレース回転」になっている点が特徴です。外側のループはリングの数(n/2)だけ回り、内側のループは各リングの辺上の要素を処理します。一時変数 top を使って値を退避させてから4方向へ順に代入していくことで、データの上書きを防ぎながら安全に入れ替えを行えます。
-
C++とOpenCVを使って動画を回転させる方法
OpenCVにおける動画の回転処理は、画像を回転させる場合と基本的に同じ仕組みです。唯一の違いは、静止画像を画像行列(Mat)に読み込む代わりに、動画ファイルを読み込むか、カメラから映像ストリームを取得するという点です。この記事では、動画ファイルを読み込むのではなく、カメラで撮影した映像をリアルタイムに回転させて表示します。もし既存の動画ファイルを使用したい場合は、VideoCaptureの引数に動画ファイルのパスを正しく指定するだけで対応できます。また、トラックバー(スライダー)を追加することで、実行中に回転角度を自由に変更できるようにしています。回転角度の初期値は180度に設定されており、
-
C++とOpenCVを使って画像を回転させる方法
OpenCVによる画像回転の基本OpenCVに組み込まれた関数を使用すれば、画像の回転は非常に簡単な作業です。画像を回転させるには、「highgui.hpp」と「imgproc.hpp」の2つのヘッダーファイルを読み込みます。本プログラムでは、これらに加えて画像の回転処理に関わる複数の関数を紹介します。以下のプログラムは、C++でOpenCVを使用して画像を回転させる方法を示しています。サンプルコード#include<iostream> #include<opencv2/highgui/highgui.hpp> #include<opencv2/imgproc/i