画像って、正方形、長方形だけじゃないですか
これを、台形とかに変形させることってできますか?
やはり、StretchDrawで、一行ずつサイズ変更するしかないのでしょうか?
>やはり、StretchDrawで、一行ずつサイズ変更するしかないのでしょうか?
???
こういうことをしたいのでょうか.
http://homepage2.nifty.com/Mr_XRAY/Halbow/VCL01.html#VChap1-4
返信ありがとうございますが
説明不足名ものですいません
http://1yk1.com/image.png
このようなので分かりますでしょうか?
よろしくお願いいたします
何となくわかりました.
これは,線形? または非線形の変換関数を用意してできるかも知れません.
ただし,私の手にはおえません.
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
これだったら線形変換とリージョンを組合わせるとできるのかな?
そうですか
じゃあ最初書いたみたいに
StretchDrawでピンクを縦何ピクセルにサイズ変更して
青、黄緑...がいいのでしょうか?
graphics32でサンプルがあります。
http://graphics32.org/wiki/
最新バージョンは1.7です。
ちょっと古いバージョンのコンパイル済みサンプルは以下にあります。
http://www.g32.org/graphics32/ のexamples.zip
examplesの中のTransformEx.exeのProjectiveというので変形のデモが見れます。
どうも線形変換だけではできないようですね.
残念ながら,具体的なコードを示すことはできないのですが,
のような変形が,今回限りであれば,やはり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で扱えるように,ピクセルの配列に代入して図形データを作成する
必要があります.
kkkさん、Mr.XRAYさん
貴重な情報ありがとうございました
中2で関係代名詞をやっと終えたとこですので
英語はあんまりよく分かりませんでした
> やはり1ラインづつ縮小・拡大の計算をするのが早そうです
そうすることにします
ともかくこんな僕のために
いろいろご指導いただきありがとうございました
参考にしてもっと勉強することにします
数学はサッパリですが、アフィン変換で台形変形はできるみたいです。
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;
我ながら酷い。
×iamge1
○image1
×buttonn1
○button1
×usese
○uses
あと、花4.bmp っていうのは適当に変えないと駄目ですね・・・
>数学はサッパリですが、アフィン変換で台形変形はできるみたいです。
なるほど,1ラインづつアフィン変換していく方法ですね.
私も専門家ではないのであれなんですが・・・
アフィン変換は並行四辺形での変換になりますので上のサンプルとちょっと違うような気がします。
この場合アフィン変換で処理するとひずみが多くなるのでは?
射影変換かな?(アフィン変換は射影変換の一部?)という気がします。
graphics32 http://graphics32.org/wiki/ に両方の変換が入っていますので確認してみてはいかがでしょう。
TAffineTransformation/TProjectiveTransformationがあります。
>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:
-------引用終了-------
失礼しました。
アフィン変換は、線の平行性が保持され、投影変換(ProjectiveTransform)が平行性が保たれない変換でした。
座標の計算式さえ分かれば(当たり前?)写像するだけなのですが。
DirectXやOpenGLを使うと超高速で処理できるんでしょうが、これらで最近傍でない、補完した写像が得られるのかどうかは、知りません。
どなたか、親切な解説をしていただけると助かります。
>どなたか、親切な解説をしていただけると助かります。
私も解説が欲しいですね.先のgraphic32はデモあり,ヘルプも充実して
いるようですが,OpenGLの関数の解説というのはSGIのサイトにあるんで
しょうか(自分で調べればわかるかもしれませんが).
ネット上では,最近はDirectXがはやっている様にも見受けられますが...
Grpahics32のデモ、見ました。
ちょっと信じられないほど速いですね〜
「Tbitmapより100倍速い」と書いてありますが、本当にそうかも。
一応、単純な動的2次元配列とTBitmapで同じサイズ(500x500など)のアクセス速度を比較した事がありますが、結論は「scanlineが効率的に行われるアクセス(つまり水平一括→垂直1進む)では速度は全く変わらない」でした。
この経験からするとデモの速さはかなり不思議なんですが、やはり素人の悲しさで、理屈が思いつきません。
ツイート | ![]() |