求图像的一些扭曲算法(100分)

  • 主题发起人 主题发起人 xjch
  • 开始时间 开始时间
X

xjch

Unregistered / Unconfirmed
GUEST, unregistred user!
如上:有几种都行
 
是个高难度的问题呀!
 
你这个问题我想可以这样解决。
1、将图象上每个点由(x,y)转换到(r,sita){即转换止极坐标}
2、根据你要变化的要求,对r,sita进行修正,
例如,一个圆上所有点r是相同的,x=r1cos(sita);y=r2sin(sita)
r1=r2;而一个椭圆r1<>r2;利用这一原理,把坐标由极坐标转回直角坐标
时,就可以达到桶形状和枕形状变形的目的。
另外使两个sita不一样应该可以实现扭曲的变形,我没有详细推导,
你实验一下看是不是可行。
 
to: delphikj
能帮我写个例子吗?
 
学一点数学,这是平面到立体的变换!
 
是线性代数吗?
 
你只是能把直线扭成曲线,就能做到!!!!!!
 
to xjch
一般的坐标变换的知识就可以用的。现在我有事情,看可能到星期天如果有空做一个例子实验一下。
不过原理上,我上面应该可以实现的。
 
这个是fastbmp中的例子:
procedure TMainForm.Twist(var Bmp, Dst: TBitmap; Amount: integer);
var
fxmid, fymid: Single;
txmid, tymid: Single;
fx, fy: Single;
tx2, ty2: Single;
r: Single;
theta: Single;
ifx, ify: integer;
dx, dy: Single;
OFFSET: Single;
ty, tx: Integer;
weight_x, weight_y: array[0..1] of Single;
weight: Single;
new_red, new_green: Integer;
new_blue: Integer;
total_red, total_green: Single;
total_blue: Single;
ix, iy: Integer;
sli, slo: PBytearray;

function ArcTan2(xt, yt: Single): Single;
begin
if xt = 0 then
if yt > 0 then
Result := Pi / 2
else
Result := -(Pi / 2)
else
begin
Result := ArcTan(yt / xt);
if xt < 0 then
Result := Pi + ArcTan(yt / xt);
end;
end;

begin
OFFSET := -(Pi / 2);
dx := Bmp.Width - 1;
dy := Bmp.Height - 1;
r := Sqrt(dx * dx + dy * dy);
tx2 := r;
ty2 := r;
txmid := (Bmp.Width - 1) / 2; //Adjust these to move center of rotation
tymid := (Bmp.Height - 1) / 2; //Adjust these to move ......
fxmid := (Bmp.Width - 1) / 2;
fymid := (Bmp.Height - 1) / 2;
if tx2 >= Bmp.Width then
tx2 := Bmp.Width - 1;
if ty2 >= Bmp.Height then
ty2 := Bmp.Height - 1;
for ty := 0 to Round(ty2) do
begin
for tx := 0 to Round(tx2) do
begin
dx := tx - txmid;
dy := ty - tymid;
r := Sqrt(dx * dx + dy * dy);
if r = 0 then
begin
fx := 0;
fy := 0;
end
else
begin
theta := ArcTan2(dx, dy) - r / Amount - OFFSET;
fx := r * Cos(theta);
fy := r * Sin(theta);
end;
fx := fx + fxmid;
fy := fy + fymid;

ify := Trunc(fy);
ifx := Trunc(fx);
// Calculate the weights.
if fy >= 0 then
begin
weight_y[1] := fy - ify;
weight_y[0] := 1 - weight_y[1];
end
else
begin
weight_y[0] := -(fy - ify);
weight_y[1] := 1 - weight_y[0];
end;
if fx >= 0 then
begin
weight_x[1] := fx - ifx;
weight_x[0] := 1 - weight_x[1];
end
else
begin
weight_x[0] := -(fx - ifx);
Weight_x[1] := 1 - weight_x[0];
end;

if ifx < 0 then
ifx := Bmp.Width - 1 - (-ifx mod Bmp.Width)
else if ifx > Bmp.Width - 1 then
ifx := ifx mod Bmp.Width;
if ify < 0 then
ify := Bmp.Height - 1 - (-ify mod Bmp.Height)
else if ify > Bmp.Height - 1 then
ify := ify mod Bmp.Height;

total_red := 0.0;
total_green := 0.0;
total_blue := 0.0;
for ix := 0 to 1 do
begin
for iy := 0 to 1 do
begin
if ify + iy < Bmp.Height then
sli := Bmp.scanline[ify + iy]
else
sli := Bmp.scanline[Bmp.Height - ify -
iy];
if ifx + ix < Bmp.Width then
begin
new_red := sli[(ifx + ix) * 3];
new_green := sli[(ifx + ix) * 3 + 1];
new_blue := sli[(ifx + ix) * 3 + 2];
end
else
begin
new_red := sli[(Bmp.Width - ifx - ix)
* 3];
new_green := sli[(Bmp.Width - ifx -
ix) * 3 +
1];
new_blue := sli[(Bmp.Width - ifx - ix)
* 3 +
2];
end;
weight := weight_x[ix] * weight_y[iy];
total_red := total_red + new_red * weight;
total_green := total_green + new_green *
weight;
total_blue := total_blue + new_blue * weight;
end;
end;
slo := Dst.scanline[ty];
slo[tx * 3] := Round(total_red);
slo[tx * 3 + 1] := Round(total_green);
slo[tx * 3 + 2] := Round(total_blue);
end;
end;end;
 
多谢大家,我已经成功做出PHOTOSHOP中的置换功能了。
不过我所需要的不是这个,我想把它做成动画。
 
这个功能我已经做好了。谢谢大家的帮助。
 
怎么样动态的显示出来,就像漂动一样。
 
后退
顶部