画像を変形する方法とかありますか?

解決


keye  URL  2005-01-16 19:48:33  No: 12729

画像って、正方形、長方形だけじゃないですか
これを、台形とかに変形させることってできますか?
やはり、StretchDrawで、一行ずつサイズ変更するしかないのでしょうか?


Mr.XRAY  URL  2005-01-16 21:00:10  No: 12730

>やはり、StretchDrawで、一行ずつサイズ変更するしかないのでしょうか?

???

こういうことをしたいのでょうか.
http://homepage2.nifty.com/Mr_XRAY/Halbow/VCL01.html#VChap1-4


keye  URL  2005-01-16 21:47:26  No: 12731

返信ありがとうございますが
説明不足名ものですいません
http://1yk1.com/image.png
このようなので分かりますでしょうか?
よろしくお願いいたします


Mr.XRAY  URL  2005-01-16 22:27:24  No: 12732

何となくわかりました.
これは,線形? または非線形の変換関数を用意してできるかも知れません.
ただし,私の手にはおえません.

Cマガジンの1月号に記事があるようです.
http://www.cmagazine.jp/contents/200501.html

の連載記事の「グラフィック処理技法」です.

また,非線形の変換例が中村拓男さんのDHGLのサンプルにもあったような
記憶があります.
http://www.asahi-net.or.jp/%7EHA3T-NKMR/DGS/index.htm

>http://1yk1.com/image.png
これだったら線形変換とリージョンを組合わせるとできるのかな?


keye  URL  2005-01-16 23:06:07  No: 12733

そうですか
じゃあ最初書いたみたいに
StretchDrawでピンクを縦何ピクセルにサイズ変更して
青、黄緑...がいいのでしょうか?


kkk  2005-01-17 10:11:52  No: 12734

graphics32でサンプルがあります。
http://graphics32.org/wiki/
最新バージョンは1.7です。
ちょっと古いバージョンのコンパイル済みサンプルは以下にあります。
http://www.g32.org/graphics32/  のexamples.zip
examplesの中のTransformEx.exeのProjectiveというので変形のデモが見れます。


Mr.XRAY  URL  2005-01-18 06:37:20  No: 12735

どうも線形変換だけではできないようですね.
残念ながら,具体的なコードを示すことはできないのですが,

http://1yk1.com/image.png

のような変形が,今回限りであれば,やはり1ラインづつ縮小・拡大の
計算をするのが早そうです.縮小・拡大のアルゴリズムは,例えば
・・内挿法(名前は失念.昔CTの画像などでやったはずなのですが)
などがあるようです.DelphiのStrechDrawなどのソースを参考にしても
いいかも知れません.

また,上記の変形に限らず,いろいろな変形をしたいのであれは,自分
でコーディングするより,他の方の,kkkさんのgraphics32は詳しく知り
ませんが,OpenGLなども使えそうです.

OpenGLは,例えば,新規プロジェクトを作成して以下のURLの6-15.のコードをUnit1.pasに置換えて実行すると,ある程度はどんなことができるかが分
かるのではないとか思います.これは,射影変換,つまり,図形をみる空間
の位置を変えてみた時の形を表示することになります.
(簡単にいうと遠近法みたいな感じかも...)

http://www.wakayama-u.ac.jp/~tokoi/opengl/delphi.html

なお,実際に,画像をOpenGLで表示するには,画像のピクセルデータを
OpneGLで扱えるように,ピクセルの配列に代入して図形データを作成する
必要があります.


keye  URL  2005-01-18 07:57:33  No: 12736

kkkさん、Mr.XRAYさん
貴重な情報ありがとうございました
中2で関係代名詞をやっと終えたとこですので
英語はあんまりよく分かりませんでした
> やはり1ラインづつ縮小・拡大の計算をするのが早そうです
そうすることにします

ともかくこんな僕のために
いろいろご指導いただきありがとうございました
参考にしてもっと勉強することにします


ウォレス  2005-01-18 18:12:57  No: 12737

数学はサッパリですが、アフィン変換で台形変形はできるみたいです。

iamge1、image2、buttonn1を貼り付けて、以下のコードで確認しました。
上記のような台形にするにはパラメータを適宜いじらないと駄目ですねぇ

useseとtype節に下記

//----------------------------------------------------------
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, Math;

type
    TRGBTripleArray = array[0 .. High(Integer) div 3 - 1] of RGBTRIPLE;
    PRGBTripleArray = ^TRGBTripleArray; //配列型のポインタ

//------------------------------------------------------------

procedure TForm1.Button1Click(Sender: TObject);
var
  Ps,Pd: PRGBTripleArray;
  x,y :Integer;
  R0,G0,B0 :Short;
  xd,yd,xd2,yd2 : Integer;
  a,b,c,d,e,f :double;

begin

  a := 0.1;
  b := 0.7;
  c := 0.001;
  d := 0.7;
  e := 0.1;
  f := 0.001;

  //image1にbitmapロード
  Form1.Image1.Picture.LoadFromFile('花4.bmp');

  //image2のプロパティを適当に・・・
  Form1.Image2.Picture.Bitmap.PixelFormat := pf24bit;
  Form1.Image2.Picture.Bitmap.Width  := Form1.Image2.Width ;
  Form1.Image2.Picture.Bitmap.Height := Form1.Image2.Height;

  for y := 0 to Form1.Image1.Picture.Bitmap.Height-1 do
  begin
    //元絵のピクセルRGBを取得
    Ps := Form1.Image1.Picture.Bitmap.ScanLine[y];

    for x := 0 to Form1.Image1.Picture.Bitmap.Width -1 do
    begin
      //元絵のピクセルRGBを取得
      R0 := Ps[x].rgbtRed;
      G0 := Ps[x].rgbtGreen;
      B0 := Ps[x].rgbtBlue;
      //アフィン変換(の筈?)
      xd  := round(x*a + y*b + c*x*y);
      yd  := round(x*d + y*e + f*x*y);

      //添え字の溢れチェック
      yd  := Max(Min(Form1.Image2.Picture.Bitmap.Height-1, yd  ), 0);
      yd2 := Max(Min(Form1.Image2.Picture.Bitmap.Height-1, yd+1), 0);

      xd  := Max(Min(Form1.Image2.Picture.Bitmap.Width -1, xd  ), 0);
      xd2 := Max(Min(Form1.Image2.Picture.Bitmap.Width -1, xd+1), 0);

      //ちょっと大きめ(合計4ピクセル)に描画。
      Pd    := Form1.Image2.Picture.Bitmap.ScanLine[yd];
      Pd[xd] .rgbtRed  := R0;
      Pd[xd] .rgbtGreen:= G0;
      Pd[xd] .rgbtBlue := B0;
      Pd[xd2].rgbtRed  := R0;
      Pd[xd2].rgbtGreen:= G0;
      Pd[xd2].rgbtBlue := B0;

      Pd    := Form1.Image2.Picture.Bitmap.ScanLine[yd2];
      Pd[xd] .rgbtRed  := R0;
      Pd[xd] .rgbtGreen:= G0;
      Pd[xd] .rgbtBlue := B0;
      Pd[xd2].rgbtRed  := R0;
      Pd[xd2].rgbtGreen:= G0;
      Pd[xd2].rgbtBlue := B0;
    end;
  end;

end;


ウォレス  2005-01-18 18:19:37  No: 12738

我ながら酷い。

×iamge1
○image1

×buttonn1
○button1

×usese
○uses

あと、花4.bmp  っていうのは適当に変えないと駄目ですね・・・


Mr.XRAY  URL  2005-01-19 21:27:57  No: 12739

>数学はサッパリですが、アフィン変換で台形変形はできるみたいです。

なるほど,1ラインづつアフィン変換していく方法ですね.


kkk  2005-01-19 21:51:54  No: 12740

私も専門家ではないのであれなんですが・・・
アフィン変換は並行四辺形での変換になりますので上のサンプルとちょっと違うような気がします。
この場合アフィン変換で処理するとひずみが多くなるのでは?
射影変換かな?(アフィン変換は射影変換の一部?)という気がします。
graphics32  http://graphics32.org/wiki/  に両方の変換が入っていますので確認してみてはいかがでしょう。
TAffineTransformation/TProjectiveTransformationがあります。


Mr.XRAY  URL  2005-01-20 05:31:13  No: 12741

>TAffineTransformation/TProjectiveTransformationがあります。

確認してみました.kkkさんはgraphics32使いですか?
graphics32のヘルプをみました.確かに.実際にデモを動作させていませ
んが.参考のために引用しておきます.

graphics32.HelpのTProjectiveTransformationのページから引用.
(ここには具体的な例図があり,このデモもDLファイルにあります)

-------引用開始-------

Description
This class specifies an arbitrary projective transformation. It transforms a rectangle from the source image into quadrilateral, defined by 4 points:

-------引用終了-------


ウォレス  2005-01-20 08:10:26  No: 12742

失礼しました。
アフィン変換は、線の平行性が保持され、投影変換(ProjectiveTransform)が平行性が保たれない変換でした。

座標の計算式さえ分かれば(当たり前?)写像するだけなのですが。

DirectXやOpenGLを使うと超高速で処理できるんでしょうが、これらで最近傍でない、補完した写像が得られるのかどうかは、知りません。

どなたか、親切な解説をしていただけると助かります。


Mr.XRAY  URL  2005-01-20 08:45:04  No: 12743

>どなたか、親切な解説をしていただけると助かります。

私も解説が欲しいですね.先のgraphic32はデモあり,ヘルプも充実して
いるようですが,OpenGLの関数の解説というのはSGIのサイトにあるんで
しょうか(自分で調べればわかるかもしれませんが).

ネット上では,最近はDirectXがはやっている様にも見受けられますが...


ウォレス  2005-01-20 09:21:59  No: 12744

Grpahics32のデモ、見ました。
ちょっと信じられないほど速いですね〜
「Tbitmapより100倍速い」と書いてありますが、本当にそうかも。

一応、単純な動的2次元配列とTBitmapで同じサイズ(500x500など)のアクセス速度を比較した事がありますが、結論は「scanlineが効率的に行われるアクセス(つまり水平一括→垂直1進む)では速度は全く変わらない」でした。
この経験からするとデモの速さはかなり不思議なんですが、やはり素人の悲しさで、理屈が思いつきません。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加