1. Arnold変換の概要
Arnold変換は、ロシアの数学者ウラジーミル・アーノルドがエルゴード理論の研究で導入した写像であり、特に猫の画像に適用されたことから「キャットマップ」とも呼ばれます。この変換は画像の各ピクセル位置を置換し、視覚的に乱れた効果を生み出すことで、マルチメディアのカオス暗号化に広く利用されています。
Arnoldスクランブルはデジタル画像処理技術の一種で、ピクセルの並び順を変更することで視覚的な歪みや変形を発生させます。主に画像の暗号化や保護、アート効果の生成、画像の複雑性向上に応用されます。
原理は置換群の概念に基づきます。n×nの画像をn²個のピクセルからなるベクトルと見なし、一連の置換操作でその順序を変更します。具体的には、各ピクセル座標(x, y)を以下の式で新しい座標(x', y')に写像します。
x' = (a*x + y) mod n
y' = (b*x + (a*b+1)*y) mod n
ここでa, bはスクランブルパラメータ、nは画像サイズです。この操作を繰り返すことでピクセル配置がランダム化され、視覚的な歪みが生じます。重要なのは、この変換が可逆であることです。パラメータa, bと反復回数が分かれば、逆変換により元の画像を復元できます。
実際の応用では、デジタルウォーターマークや画像暗号化に頻繁に使用され、複数回の変換によりピクセル配置が極めて複雑になり、セキュリティが向上します。また、デジタルアートでの視覚効果生成にも利用されます。
2. スクランブル手順
- パラメータ選択:互いに素な正の整数a, bを選びます(例:a=3, b=5)。
- 画像を行列に変換:画像をn×nの行列に変換します。サイズが合わない場合はパディングやトリミングを行います。
- スクランブル操作:各ピクセル座標(x, y)に対して上記の式を適用し、新しい座標(x', y')を計算します。
- 反復:得られた座標に対して再度変換を適用し、所定の回数だけ繰り返します。
- 画像再構成:スクランブル後の行列を画像に戻し、暗号化画像として保存します。復号時は逆変換を行います。
3. MATLABによる実装例
3.1 スクランブル処理
% パラメータ設定
a = 3;
b = 5;
iter = 512;
% 画像読み込みとグレースケール変換
img = imread('Lena.png');
img_gray = rgb2gray(img);
img_mat = double(img_gray);
[n, m] = size(img_mat);
% スクランブル反復
for k = 1:iter
for i = 1:n
for j = 1:m
x_new = mod(a*i + j, n) + 1;
y_new = mod(b*i + (a*b+1)*j, n) + 1;
img_mat(x_new, y_new) = img_gray(i, j);
end
end
end
% 結果表示・保存
img_scrambled = uint8(img_mat);
imshow(img_scrambled);
imwrite(img_scrambled, 'Lena_scrambled.jpg');
3.2 ブロック単位のスクランブル(別手法)
img = imread('Lena.png');
img = rgb2gray(img);
n = 512; a = 3; b = 5;
for k = 1:n
blocks = mat2cell(img, repmat(n, 1, size(img,1)/n), repmat(n, 1, size(img,2)/n));
for i = 1:size(blocks,1)
for j = 1:size(blocks,2)
block = blocks{i,j};
[X, Y] = meshgrid(1:n, 1:n);
X1 = mod(a*X + Y, n) + 1;
Y1 = mod(b*X + (a*b+1)*Y, n) + 1;
idx = sub2ind([n, n], Y1(:), X1(:));
block = reshape(block(idx), n, n);
blocks{i,j} = block;
end
end
img = cell2mat(blocks);
end
imshow(img);
3.3 逆スクランブル(復元)
clear; clc;
img = imread('Lena.bmp');
if numel(size(img)) > 2
img = rgb2gray(img);
disp('カラー画像をグレースケールに変換');
else
disp('グレースケール画像');
end
imshow(img); title('原画像');
[h,w] = size(img);
if h ~= w
img = imresize(img, [min(h,w) min(h,w)]);
disp('画像を正方形にリサイズ');
end
N = size(img,1);
n = 10; a = 1; b = 1;
% スクランブル
imgn = zeros(N,N);
for i = 1:n
for y = 1:N
for x = 1:N
xx = mod((x-1) + b*(y-1), N) + 1;
yy = mod(a*(x-1) + (a*b+1)*(y-1), N) + 1;
imgn(yy,xx) = img(y,x);
end
end
img = imgn;
end
imgn = uint8(imgn);
imshow(imgn); title('スクランブル後');
imwrite(imgn, 'scrambled.bmp');
% 逆スクランブル
img2 = imread('scrambled.bmp');
for i = 1:n
for y = 1:N
for x = 1:N
xx = mod((a*b+1)*(x-1) - b*(y-1), N) + 1;
yy = mod(-a*(x-1) + (y-1), N) + 1;
imgn(yy,xx) = img2(y,x);
end
end
img2 = imgn;
end
imgn = uint8(imgn);
imshow(imgn); title('復元画像');
imwrite(imgn, 'restored.bmp');
4. 2次元Arnoldスクランブル
2次元Arnoldスクランブルは、画像全体を1つの行列として扱う点で1次元版と同様ですが、変換式は同じです。手順は以下の通りです。
- パラメータa, bを選択(例:a=3, b=5)。
- 画像をn×n行列に変換。
- 各ピクセル座標(x,y)に対し、x' = (a*x + y) mod n, y' = (b*x + (a*b+1)*y) mod n を適用。
- 所定回数反復。
- 行列を画像に戻して保存。復号は逆変換。
この手法は信頼性の高い画像カオス化手法であり、セキュリティと機密性を向上させます。