Автор: Иаиа Аиа, 10 Июня 2010 в 13:20, дипломная работа
Технология создания морфинга изображений в Delphi
Морфинг — это видеоэффект, заключающийся в плавном перетекании одного изображения в другое. Иногда морфингом называют эффект наплыва, когда одна сцена затемняется или затуманивается, а вторая в это время проявляется все резче и сменяет первую. Однако лучше разделять эти понятия. В отличие от наплыва, морфинг обеспечивает соответствие характерных (наиболее привлекающих внимание) точек и контуров начального и конечного изображений. Например, преобразование одного лица в другое, при котором задается соответствие положения характерных точек глаз, носа и т.д.
for j := 0 to tab_bool_h -1 do begin
ism := false;
for i := 0 to tab_bool_w -1 do begin
if (tab_bool[tab_bool_w - i -1][j]) then begin
imax := tab_bool_w - i -1;
ism := true;
break;
end;
end;
if (ism) then begin
ismn := false;
for i:=0 to imax do begin
if (ismn) then begin tab_bool[i][j] := true;
end else begin if (tab_bool[i][j]) then ismn := true; end;
end;
end;
end;
end;
После
завершения расставления точек матрица
сохраняется, нажатием на кнопку «Сохранить
мтрицу» (Shape), с помощью процедуры:
procedure TForm1.SaveAClick(Sender:
TObject);
Причем
временные данные записываются в
глобальный массив расстановки точек
сетки:
count := 1;
for i:=1 to 9 do begin
for j:= 1 to 9 do begin
byteArray[count] := LesPointsA_x[i,j,ab];
byteArray2[count] := LesPointsA_y[i,j,ab];
count := count+1;
end;
end;
Матрица
записывается в указанном файле:
AssignFile(myFile, saveDialog1.FileName);
ReWrite(myFile, 81);
BlockWrite(myFile, byteArray, 1);
BlockWrite(myFile, byteArray2, 1);
CloseFile(myFile);
end;
end;
При
нажатии на кнопку «Начать», запускается
процедура TForm1.
for frame := 1 to frame_n-1 do begin
statusbar1.SimpleText := 'Compute '+inttostr(frame) + ' / ' + inttostr(frame_n-1)
+ '.';
Lanim[frame] := TBitmap.Create;
Lanim[frame].PixelFormat := pf24bit;
Lanim[frame].Width := 240; Lanim[frame].Height:=240;
RwBmpA := TBitmap.Create; RwBmpB := TBitmap.Create;
RwBmpA.PixelFormat := pf24bit;
RwBmpB.PixelFormat := pf24bit;
RwBmpA.Width := 240; RwBmpA.Height := 240;
RwBmpB.Width := 240; RwBmpB.Height := 240;
for i:= 1 to 8 do begin
for j:=1 to 8 do begin
k := frame/frame_n;
ModeAutoPoints[4,0] := LesPointsA_x[i][j][1];
ModeAutoPoints[4,1] := LesPointsA_y[i][j][1];
ModeAutoPoints[5,0] := LesPointsA_x[i+1][j][1];
ModeAutoPoints[5,1] := LesPointsA_y[i+1][j][1];
ModeAutoPoints[6,0] := LesPointsA_x[i+1][j+1][1];
ModeAutoPoints[6,1] := LesPointsA_y[i+1][j+1][1];
ModeAutoPoints[7,0] := LesPointsA_x[i][j+1][1];
ModeAutoPoints[7,1] := LesPointsA_y[i][j+1][1];
ModeAutoPoints[0,0] := round(LesPointsA_x[i][j][1] + (LesPointsA_x[i][j][2] - LesPointsA_x[i][j][1]) * k );
ModeAutoPoints[0,1] := round(LesPointsA_y[i][j][1] + (LesPointsA_y[i][j][2] - LesPointsA_y[i][j][1]) * k );
ModeAutoPoints[1,0] := round(LesPointsA_x[i+1][j][1] + (LesPointsA_x[i+1][j][2] - LesPointsA_x[i+1][j][1])* k );
ModeAutoPoints[1,1] := round(LesPointsA_y[i+1][j][1] + (LesPointsA_y[i+1][j][2] - LesPointsA_y[i+1][j][1])* k );
ModeAutoPoints[2,0] := round(LesPointsA_x[i+1][j+1][
ModeAutoPoints[2,1] := round(LesPointsA_y[i+1][j+1][
ModeAutoPoints[3,0] := round(LesPointsA_x[i][j+1][1] + (LesPointsA_x[i][j+1][2] - LesPointsA_x[i][j+1][1])* k );
ModeAutoPoints[3,1] := round(LesPointsA_y[i][j+1][1] + (LesPointsA_y[i][j+1][2]
- LesPointsA_y[i][j+1][1])* k );
ReshapeProcess();
DrawPoly(ModeAutoPoints[0,0],
ModeAutoPoints[2,0],
for i2:= 0 to tab_bool_w-1 do begin
for j2:=0 to tab_bool_h-1 do begin
if (tab_bool[i2,j2]) then begin
x := tmp_min_x + i2;
y := tmp_min_y + j2;
x_org := round( (a*x+b*y+c) / (g*x+h*y+1) );
y_org := round( (d*x+e*y+f) / (g*x+h*y+1) );
RwBmpA.Canvas.Pixels[x,y] := OrigBmpA.Canvas.Pixels[x_org,
end;
end;
end;
k := (frame_n-frame)/frame_n;
ModeAutoPoints[4,0] := LesPointsA_x[i][j][2];
ModeAutoPoints[4,1] := LesPointsA_y[i][j][2];
ModeAutoPoints[5,0] := LesPointsA_x[i+1][j][2];
ModeAutoPoints[5,1] := LesPointsA_y[i+1][j][2];
ModeAutoPoints[6,0] := LesPointsA_x[i+1][j+1][2];
ModeAutoPoints[6,1] := LesPointsA_y[i+1][j+1][2];
ModeAutoPoints[7,0] := LesPointsA_x[i][j+1][2];
ModeAutoPoints[7,1] := LesPointsA_y[i][j+1][2];
ModeAutoPoints[0,0] := round(LesPointsA_x[i][j][2] + (LesPointsA_x[i][j][1] - LesPointsA_x[i][j][2]) * k );
ModeAutoPoints[0,1] := round(LesPointsA_y[i][j][2] + (LesPointsA_y[i][j][1] - LesPointsA_y[i][j][2]) * k );
ModeAutoPoints[1,0] := round(LesPointsA_x[i+1][j][2] + (LesPointsA_x[i+1][j][1] - LesPointsA_x[i+1][j][2])* k );
ModeAutoPoints[1,1] := round(LesPointsA_y[i+1][j][2] + (LesPointsA_y[i+1][j][1] - LesPointsA_y[i+1][j][2])* k );
ModeAutoPoints[2,0] := round(LesPointsA_x[i+1][j+1][
ModeAutoPoints[2,1] := round(LesPointsA_y[i+1][j+1][
ModeAutoPoints[3,0] := round(LesPointsA_x[i][j+1][2] + (LesPointsA_x[i][j+1][1] - LesPointsA_x[i][j+1][2])* k );
ModeAutoPoints[3,1] := round(LesPointsA_y[i][j+1][2] + (LesPointsA_y[i][j+1][1]
- LesPointsA_y[i][j+1][2])* k );
ReshapeProcess();
DrawPoly(ModeAutoPoints[0,0],
ModeAutoPoints[2,0],
for i2:= 0 to tab_bool_w-1 do begin
for j2:=0 to tab_bool_h-1 do begin
if (tab_bool[i2,j2]) then begin
x := tmp_min_x + i2;
y := tmp_min_y + j2;
x_org := round( (a*x+b*y+c) / (g*x+h*y+1) );
y_org := round( (d*x+e*y+f) / (g*x+h*y+1) );
RwBmpB.Canvas.Pixels[x,y] := OrigBmpB.Canvas.Pixels[x_org,
end;
end;
end;
end;
end;
for j:=0 to 240-1 do begin
ScanSrc := RwBmpA.ScanLine[j];
ScanDest := RwBmpB.ScanLine[j];
for i:=0 to 240-1 do begin
ScanDest[i].rgbtBlue := (ScanDest[i].rgbtBlue*frame + ScanSrc[i].rgbtBlue*(frame_n-
ScanDest[i].rgbtGreen := (ScanDest[i].rgbtGreen*frame + ScanSrc[i].rgbtGreen*(frame_n-
ScanDest[i].rgbtRed := (ScanDest[i].rgbtRed*frame + ScanSrc[i].rgbtRed*(frame_n-
end;
end;
Lanim[frame].Assign(RwBmpB);
RwBmpA.Free; RwBmpB.Free;
end;
Lanim[0] := TBitmap.Create;
Lanim[0].PixelFormat := pf24bit;
Lanim[0].Width := 240;
Lanim[0].Height := 240;
Lanim[frame_n] := TBitmap.Create;
Lanim[frame_n].PixelFormat := pf24bit;
Lanim[frame_n].Width := 240;
Lanim[frame_n].Height := 240;
Lanim[0].Assign(OrigBmpA);
Lanim[frame_n].Assign(
frame_m := frame_n+1;
frame_c := frame_m;
frame_sens := false;
timer1.Enabled := true;
statusbar1.SimpleText := 'Done.';
end;
end;
Запускаем
таймер для просмотра полученного
клипа:
timer1.Enabled
:= true;
Причем
пробегаем по полученному массиву
изображений сначала в одну, затем
в другую сторону и обратно, при
помощи процедуры:
procedure
TForm1.Timer1Timer(Sender: TObject);
При
нажатии на кнопку «остановить процесс»,
процесс морфинга изображений останавливается
на том изображении, где мы остановили
процесс морфинга, с использованием процедуры:
procedure
TForm1.SpeedButton1Click(
begin
timer1.Enabled := false;
end;
В
зависимости от того, сколько кадров
в ролике, полученный ролик можно
импортировать покадрово в формате *.jpeg,
размером 240х240 пикселей, с помощью процедуры:
TForm1.Button1Click(
Причем
путь сохранения указывается нажатием
на «…» с помощью процедуры:
SaveDialog2.Execute;
Edit1.Text:=SaveDialog2.
Так
же можно изменить скорость ролика,
это влияет на качество морфируемого
ролика, с помощью процедуры:
procedure TForm1.TrackBar2Change(Sender: TObject);
begin
timer1.Interval := trackbar2.Position * 10;
end;