2

画像ファイルを MATLAB に読み込んで、一方向に引き延ばそうとしていますが、量は可変 (正弦波) です。これにより、画像にアコーディオン効果が作成されます。私は imresize をいじりましたが、それは画像を線形にサイズ変更するだけです。画像ラインごとに「ストレッチ」の量を変えたいと思います。これを次のコードで伝えようとしました。

periods = 10; % Number of "stretch" cycles
sz = size(original_image,2)/periods;
s = 0;
x = 0;
for index = 1:periods
    B = original_image(:,round(s+1:s+sz));
    if mod(index,2) == 0
        amp = 1.5;
    else
        amp = 0.75;
    end
    xi = size(B,2)*amp;
    new_image(:,x+1:x+xi) = imresize(B, [size(B,1) size(B,2)*amp]);
    s = s + sz;
    x = x+xi;
end

イメージのセグメントが、アコーディオンのように引き伸ばされ、次に圧縮され、引き伸ばされていることがわかります。ただし、各セグメントには均一な量のストレッチがありますが、画像に沿って移動するにつれて、ストレッチが増加してから減少することを望みます。

私の問題に非常に当てはまると思われるチェッカーボードに正弦波変換を適用するMATLABの例も見ましたが、試してみましたが、これを取得して画像に望ましい結果を生成することはできません。どんな助けでも大歓迎です。


アップデート:

回答#1をありがとうございます。私はそれを機能させることができませんでしたが、コードが元のイメージの特定の行のみを呼び出し、他の行は無視されたため、データが失われることに気付きました.

さらに実験した後、以下のコードを開発しました。例としてチェッカーボードを使用しました。面倒ですが、それは仕事を成し遂げます。しかし、実際の高解像度画像でスクリプトを試してみると、非常に遅く、メモリ不足で失敗しました。これは、ループで使用される「imresize」コマンドの数が多すぎるためだと思います。

I = checkerboard(10,50);
I = imrotate(I,90);
[X Y] = size(I);
k = 4; % Number of "cycles"
k = k*2;
x = 1;
y = 2;
z = 2;
F = [];
i = 1;
t = 0;
s = 0;

for j = 1:k/2
    t = t + 1;
    for inc = round(s+1):round(Y/k*t)
        Yi = i + 1;
        F(:,(x:y)) = imresize(I(:,(inc:inc)),[X Yi]);
        x = y + 1;
        y = x + z;
        z = z + 1;
        i = i + 1;
    end
    y = y - 2;
    z = z - 4;
    for inc = round(Y/k*t+1):round(Y/k*(t+1))
        Yi = i - 1;
        F(:,(x:y)) = imresize(I(:,(inc:inc)),[X Yi]);
        x = y + 1;
        y = x + z;
        z = z - 1;
        i = i - 1;
    end
    y = y + 2;
    z = z + 4;

    s = Y/k*(t+1);
    t = t + 1;
end
Fn = imresize(F, [X Y]);
imshow(Fn);

これを達成するためのより簡単な方法を知っている人はいますか? 上記のコードを実行すると、達成しようとしている効果を確認できます。残念ながら、上記の方法では、「ストレッチ」の振幅を調整することはできず、「サイクル」の数または頻度のみを調整できます。これに関するヘルプもいただければ幸いです。どうもありがとう!

4

1 に答える 1

1

これが私がそれにアプローチする方法です:

  1. 最終画像 F の各点の座標が、サイズ (M,N) の初期画像 I にどのようにマップされるかを決定します。

    水平方向にのみストレッチしたいので、最終画像の点 (xF,yF) を指定すると、その点は初期画像の (xI,yI) になり、xI と yI は次のように取得できます。

    yI = yF;
    xI = xF + L sin(xF K);

    ノート:

    • これらの式は、xI が [1:N] の範囲内にあることを保証しないため、クロッピングを追加する必要があります。
    • K は、アコーディオン効果に含めるしわの数を制御します。たとえば、しわが 1 つだけ必要な場合、K は 2*pi/N になります。
    • L 適用するストレッチの量を制御します
  2. 次に、画像 I から画像 F を 1 の変換で単純に表現します。

すべてをまとめると、以下のコードはサンプル画像 I を作成し、次のように画像 F を生成します。

  % Generate a sample input image
  N=500;
  xF=1:N;
  I=(1:4)'*xF/N*50;

  % Set the parameters for your accordion transform
  K=2*pi/N;
  L=100;

  % Apply the transform
  F=I(:, round(min(N*ones(1,N), max(ones(1,N), (xF + L*sin(xF*K))))) );

  % Display the input and output images side by side
  image(I);
  figure;
  image(F);

この正確なコードを実行すると、次のようになります。

ここに画像の説明を入力

ご覧のとおり、右の最終的な画像は左の画像の中央部分を引き伸ばしており、しわが 1 つあるアコーディオン効果が得られています。

K と L をいじって式を調整し、必要な正確な効果を得ることができますが、変換を行列形式で表現することにより、MATLAB がコードをわずか数秒で実行することに注意してください。1 つ重要な点があるとすれば、できる限り for ループや複雑な処理に近づかないようにすることです。

楽しむ!

于 2013-03-08T02:39:17.007 に答える