    (*********************************************************************
     *  main                                                             *
     *                                                                   *
     *   Camera Calibration project                                      *
     *   by Vladimir Vasilyev                                            *
     *   home page : http://www.nextnow.com                              *
     *   email     : Vladimir@nextnow.com                                *
     *               W-develop@mtu-net.ru                                *
     *                                                                   *
     *                                                                   *
     *   To compilate the project you need:                              *
     *   FlatStyle    :  http://www.flatstyle2k.net/                     *
     *   DsPack2.3    :  http://www.progdigy.com/                        *
     *   GlScene      :  http://glscene.sourceforge.net/index.php        *
     *                                                                   *
     *                                                                   *
     *                                                                   *
     *                                                                   *
     *                                                                   *
     *                                                                   *
     *  The contents of this file are used with permission, subject to   *
     *  the Mozilla Public License Version 1.1 (the "License"); you may  *
     *  not use this file except in compliance with the License. You may *
     *  obtain a copy of the License at                                  *
     *  http://www.mozilla.org/MPL/MPL-1.1.html                          *
     *                                                                   *
     *  Software distributed under the License is distributed on an      *
     *  "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or   *
     *  implied. See the License for the specific language governing     *
     *  rights and limitations under the License.                        *
     *                                                                   *
     *********************************************************************)


unit main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, DSUtil, StdCtrls, DSPack, DirectShow9, Menus, ExtCtrls,
  GR32_Image,GR32,GR32_Layers,GR32_LowLevel,G32_WConvolution,ActiveX,
  TFlatEditUnit, TFlatSpinEditUnit, ExtDlgs, Buttons;

type
  TMainForm = class(TForm)
    FilterGraph: TFilterGraph;
    MainMenu1: TMainMenu;
    Devices: TMenuItem;
    Filter: TFilter;
    SampleGrabber: TSampleGrabber;
    ImgView: TImgView32;
    Run1: TMenuItem;
    SnapShort1: TMenuItem;
    StartCollectImages1: TMenuItem;
    Calibrate1: TMenuItem;
    Timer1: TTimer;
    SaveDialog: TSaveDialog;
    Panel2: TPanel;
    Panel4: TPanel;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    IdSpinEdit: TFlatSpinEditInteger;
    TimeSpinEdit: TFlatSpinEditInteger;
    MaxSpinEdit: TFlatSpinEditInteger;
    RowSpinEdit: TFlatSpinEditInteger;
    ColSpinEdit: TFlatSpinEditInteger;
    Panel1: TPanel;
    VideoWindow: TVideoWindow;
    SpeedButton9: TSpeedButton;
    SpeedButton1: TSpeedButton;
    About1: TMenuItem;
    Label6: TLabel;
    SquareWidthEdit: TFlatSpinEditFloat;
    Label7: TLabel;
    xDistEdit: TFlatSpinEditFloat;
    Label8: TLabel;
    yDistEdit: TFlatSpinEditFloat;
    Label9: TLabel;
    fEdit: TFlatSpinEditFloat;
    WidthEdit: TFlatSpinEditInteger;
    Label10: TLabel;
    Label11: TLabel;
    HeightEdit: TFlatSpinEditInteger;
    File1: TMenuItem;
    Load1: TMenuItem;
    SavePresets1: TMenuItem;
    OpenPictureDialog: TOpenPictureDialog;
    LoadImage1: TMenuItem;
    SaveImageAs1: TMenuItem;
    N1: TMenuItem;
    SavePictureDialog: TSavePictureDialog;
    N2: TMenuItem;
    N3: TMenuItem;
    FindExtrinsin1: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure SampleGrabberBuffer( sender: TObject; SampleTime: Double;
                                   pBuffer: PByte; BufferLen: Integer  );
    procedure SnapShotClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure SnapShort1Click(Sender: TObject);
    procedure StartCollectImages1Click(Sender: TObject);
    procedure Calibrate1Click(Sender: TObject);
    procedure IdSpinEditChange(Sender: TObject);
    procedure TimeSpinEditChange(Sender: TObject);
    procedure RowSpinEditChange(Sender: TObject);
    procedure ColSpinEditChange(Sender: TObject);
    procedure SpeedButton9Click(Sender: TObject);
    procedure SpeedButton1Click(Sender: TObject);
    procedure SaveImageAs1Click(Sender: TObject);
    procedure LoadImage1Click(Sender: TObject);
    procedure FindExtrinsin1Click(Sender: TObject);
    procedure SavePresets1Click(Sender: TObject);
    procedure Load1Click(Sender: TObject);
  private
    Bitmap : TBitmap;
  
    LoadedFileName  : String;
  
    function  GetBitmap32(Bitmap: TBitmap32; Buffer: PByte; BufferLen: Integer): boolean;overload;
    function  GetBitmap32(Bitmap: TBitmap32): boolean;overload;
    procedure Buffer2Bitmap32(Buffer: PByte; BufferLen: Integer;  pBits: PByte);
    function  DoProcessCurrent(FileName: String): boolean;
    procedure DoProcessBitmap(Bitmap: TBitmap);
    procedure EnabledConrols(val: Boolean);
    procedure DoFindExtrinsicCameraParams;
    procedure OpenPicFile(FileName: String);
    procedure Draw2DPoint2fArr(Arr: T2DPoint2fArr);
    { Déclarations privées }
  public
    { Déclarations publiques }
    procedure OnSelectDevice(sender: TObject);
  end;

var
  MainForm : TMainForm;

  SysDev    : TSysDevEnum;

    CurrentImageId  : Integer;
    CanContinue     : Boolean;
    RowCount,
    ColCount        : Integer;
    squarewidth,
    xDist,
    yDist,
    f               : Double;
    ImageWidth,
    ImageHeight     : Integer;
    
    CurrentFileName : String;
    CallBackChecked : Boolean;

  
implementation
 Uses Pathes, cvAccess, OpenCV, ArrTools, ResultsUnit, GLUnit, IniFiles;
     
{$R *.dfm}


//this is from GR32_Filters
const
  SEmptySource = 'The source is nil';
  SEmptyDestination = 'Destination is nil';
procedure CheckParams(Dst, Src: TBitmap32);
begin
  if Src = nil then raise Exception.Create(SEmptySource);
  if Dst = nil then raise Exception.Create(SEmptyDestination);
  Dst.SetSize(Src.Width, Src.Height);
end;
//\this is from GR32_Filters

procedure TMainForm.FormCreate(Sender: TObject);
var
  i: integer;
  Device: TMenuItem;
begin
  Bitmap:=TBitmap.Create;

  CurrentImageId:=0;
  CanContinue:=true;
  RowCount:=RowSpinEdit.Value;
  ColCount:=ColSpinEdit.Value;
      
  SysDev:= TSysDevEnum.Create(CLSID_VideoInputDeviceCategory);
  if SysDev.CountFilters > 0 then
    for i := 0 to SysDev.CountFilters - 1 do
    begin
      Device := TMenuItem.Create(Devices);
      Device.Caption := SysDev.Filters[i].FriendlyName;
      Device.Tag := i;
      Device.OnClick := OnSelectDevice;
      Devices.Add(Device);
    end;
end;

procedure TMainForm.EnabledConrols( val : Boolean);
begin
 Run1.Enabled:=val;
end;

procedure TMainForm.OnSelectDevice(sender: TObject);
var
  CaptureGraph: ICaptureGraphBuilder2;
  SourceFilter, DestFilter,GrabberFilter: IBaseFilter;
   
begin

  EnabledConrols(true);

  FilterGraph.ClearGraph;
  FilterGraph.Active := false;
  Filter.BaseFilter.Moniker := SysDev.GetMoniker(TMenuItem(Sender).tag);
  FilterGraph.Active := true;
  FilterGraph.QueryInterface(ICaptureGraphBuilder2, CaptureGraph);
  Filter.QueryInterface(IBaseFilter, SourceFilter);
  SampleGrabber.QueryInterface(IBaseFilter, GrabberFilter);
  VideoWindow.QueryInterface(IBaseFilter, DestFilter);
  
  CaptureGraph.RenderStream(nil, nil, SourceFilter, GrabberFilter, DestFilter);

  //CaptureGraph.RenderStream(nil, nil, SourceFilter, nil, DestFilter);

  FilterGraph.Play;
  CaptureGraph := nil;
  SourceFilter := nil;
  DestFilter   := nil;
end;

procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  SysDev.Free;
  FilterGraph.ClearGraph;
  FilterGraph.Active := false;
end;

procedure TMainForm.SampleGrabberBuffer(sender: TObject;
          SampleTime: Double; pBuffer: PByte; BufferLen: Integer);
const
  LastTickCount : Cardinal=0;	        
begin

  if CallBackChecked then
  begin
    //Image.Canvas.Lock;
    Bitmap.Canvas.Lock;
    try
      //SampleGrabber.GetBitmap(Image.Picture.Bitmap, pBuffer, BufferLen);


      if GetTickCount-LastTickCount<TimeSpinEdit.Value then Exit;
      
      SampleGrabber.GetBitmap(Bitmap, pBuffer, BufferLen);
      ImgView.Bitmap.Assign(Bitmap);
      
      DoProcessBitmap(Bitmap);

      LastTickCount:=GetTickCount;
      
      

      //GetBitmap32(ImgView.Bitmap, pBuffer, BufferLen);
    finally
      //Image.Canvas.Unlock;
      Bitmap.Canvas.Unlock;
    end;
  end;

end;



Procedure TMainForm.Buffer2Bitmap32( Buffer: PByte; BufferLen : longint ; pBits: PByte );
  Var
    Y : byte;
  Begin
    if (Buffer = nil) or (BufferLen = 0) or (pBits=nil)  then Exit;
    while BufferLen>0 do begin
          
          pBits^:= Buffer^;
          inc(pBits);
          inc(Buffer);

          pBits^:= Buffer^;
          inc(pBits);
          inc(Buffer);

          pBits^:= Buffer^;
          inc(pBits);
          inc(Buffer);

          inc(pBits);
          
          dec(BufferLen,3);
    end;
 end;


procedure Flip(Src: TBitmap32);
var
  j         : integer;
  A, B, buf : PColor32;
  sz,bsz    : cardinal;
begin
  sz  := Src.Width;
  bsz := sz shl 2;
  GetMem(buf, sz shl 2);
  A := Src.PixelPtr[0, 0];
  B := Src.PixelPtr[0, Src.Height - 1];
  for j := 0 to Src.Height shr 1 - 1 do
  begin

    MoveLongword(A^, buf^, sz);
    MoveLongword(B^, A^, sz);
    MoveLongword(buf^, B^, sz);

    Inc(A, sz);
    Dec(B, sz);
  end;
  FreeMem(buf, sz shl 2);
  //Src.Changed;
end;
 
  function TMainForm.GetBitmap32(Bitmap: TBitmap32; Buffer: PByte; BufferLen: Integer): boolean;
  var
    hr         : HRESULT;
    BMIHeader  : TBitmapInfoHeader;
    AMediaType : TAMMediaType;
    buf        : pointer;
  begin
    result := false;
    if ((Buffer = nil) or (BufferLen = 0)) then exit;
    if not assigned(Bitmap) then exit;
    hr := SampleGrabber.SampleGrabber.GetConnectedMediaType(AMediaType);
    if (hr <> S_OK) then exit;
    if IsEqualGUID(AMediaType.majortype, MEDIATYPE_Video) then
    begin
      case Amediatype.formattype.D1 of
        $05589F80: BMIHeader := PVideoInfoHeader(Amediatype.pbFormat)^.bmiHeader;
        $F72A76A0: BMIHeader := PVideoInfoHeader2(Amediatype.pbFormat)^.bmiHeader;
      end;
      Bitmap.SetSize(BMIHeader.biWidth,BMIHeader.biHeight);
      Move(buffer^, Pointer(Bitmap.Bits)^, BufferLen);
      Flip(Bitmap);
      
    end;
    FreeMediaType(@AMediaType);
  end;

 
  Function TMainForm.GetBitmap32(Bitmap : TBitmap32): boolean;
  Var
    hr         : HRESULT;
    BMIHeader  : TBitmapInfoHeader;
    BufferSize : longint;
    AMediaType : TAMMediaType;
    buffer     : pointer;

  begin
    result := false;
     
    if not assigned(Bitmap) then exit;
    if not assigned(SampleGrabber.SampleGrabber) then exit;
    hr := SampleGrabber.SampleGrabber.GetConnectedMediaType(AMediaType);
    if (hr <> S_OK) then exit;
    try
    if IsEqualGUID(AMediaType.majortype, MEDIATYPE_Video) then
    begin
      case Amediatype.formattype.D1 of
        $05589F80: BMIHeader := PVideoInfoHeader(Amediatype.pbFormat)^.bmiHeader;
        $F72A76A0: BMIHeader := PVideoInfoHeader2(Amediatype.pbFormat)^.bmiHeader;
      end;
      Bitmap.SetSize(BMIHeader.biWidth,BMIHeader.biHeight);
      HR := SampleGrabber.SampleGrabber.GetCurrentBuffer(BufferSize,Pointer(Bitmap.Bits));
      if (hr <> S_OK) then exit;
      Flip(Bitmap);

      {
      hr:= SampleGrabber.SampleGrabber.GetCurrentBuffer(BufferSize, nil);
      if (hr <> S_OK) then exit;

      GetMem(Buffer, BufferSize);
      try
         hr:= SampleGrabber.SampleGrabber.GetCurrentBuffer(BufferSize, Buffer);
         if (hr <> S_OK) then exit;
      
         Buffer2Bitmap32(buffer,BufferSize, Pointer(Bitmap.Bits) ) ;
         Bitmap.Changed;

       finally
         FreeMem(Buffer,BufferSize);
       end;
       } 
    end;

    result:= True;

    finally
       FreeMediaType(@AMediaType);
    end;
    
  end;



procedure TMainForm.SnapShotClick(Sender: TObject);
begin
 //SampleGrabber.GetBitmap(Image.Picture.Bitmap);
 //Image.Picture.SaveToFile('Sample.bmp');

 SampleGrabber.GetBitmap(Bitmap);
 ImgView.Bitmap.Assign(Bitmap);
 Bitmap.SaveToFile('Sample.bmp');

 //GetBitmap32(ImgView.Bitmap);
end;

procedure TMainForm.SnapShort1Click(Sender: TObject);
begin
 SnapShotClick(nil);
end;

procedure TMainForm.DoProcessBitmap(Bitmap : TBitmap);
Var
 FileName : String;
begin
 CanContinue:=false;

      FileName:=GetName('Out',Format('Sample%d.bmp',[CurrentImageId]) );
      Bitmap.SaveToFile(FileName);

      if DoProcessCurrent(FileName) then begin
         inc(CurrentImageId);
         IdSpinEdit.Value:=CurrentImageId;
         if CurrentImageId>MaxSpinEdit.Value then begin
            //Timer1.Enabled:=false;
             CallBackChecked:=false; 
         end;   
      end   
         else DeleteFile(FileName);

 CanContinue:=true;
 
end;

Function TMainForm.DoProcessCurrent( FileName : String ) : boolean;
Var
 i,j,k,n,m   : integer;
 CornerArr   : T2DPoint2fArr;
 Res         : Boolean;
begin
 Result:=False;
    
    Res:=FindChessBoardCorner(FileName,RowCount,ColCount,CornerArr );
    if not Res then begin
       Beep;
       Exit;
    end;

    FileName:=ChangeFileExt(FileName,'.ocv');
    SaveArr(fileName,CornerArr);
    CurrentFileName:=FileName;
    
 Result:=true;
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
 Bitmap.free;
end;


procedure TMainForm.StartCollectImages1Click(Sender: TObject);
begin
 RowCount:=RowSpinEdit.Value;
 ColCount:=ColSpinEdit.Value;

 //Timer1.Enabled:=true;
 CallBackChecked:=true; 
end;

procedure TMainForm.Calibrate1Click(Sender: TObject);
Var
 i,j,n,pos,
 NumImages,
 numPoints   : Integer;
 Dir, 
 fileName    : string;
 S,CR        : String;
 PointArr    : TPoint2fArr;
 DistrArr,
 CameraMArr  : T2DPoint1fArr;
 CrossPointArr   : T2DPoint2fArr;
begin

 NumImages:=MaxSpinEdit.Value;
 RowCount:=RowSpinEdit.Value;
 ColCount:=ColSpinEdit.Value;
 
 numPoints:=RowCount*ColCount;
 
 Dir:='Out';
 
 SetLength(PointArr, numPoints*NumImages);

 for n:=0 to NumImages-1 do begin
     fileName:=GetName( Dir, format('Sample%d.ocv',[n]) );
     LoadArr(fileName,CrossPointArr);

     Assert(Length(CrossPointArr)=RowCount );
     Assert(Length(CrossPointArr[0])=ColCount );
     
     for i:=0 to RowCount-1 do
         for j:=0 to ColCount-1 do begin
             pos:=n*numPoints + i*ColCount+j;
             PointArr[pos]:=CrossPointArr[i,j];
         end;
 end;

                                     //SONY DFW-SX900
 squarewidth:=SquareWidthEdit.Value; // 27.4; {mm}
 xdist:=xDistEdit.Value/1000;        //4.65e-3;     {mm}
 ydist:=yDistEdit.Value/1000;        //4.65e-3;     {mm}
 f:=fEdit.Value;                     //12.5;        {mm}
 ImageWidth:=WidthEdit.Value;
 ImageHeight:=HeightEdit.Value;
 
 
 CalibrateCamera( PointArr,
                  NumImages,RowCount,ColCount,
                  squarewidth,
                  xDist, yDist,f,
                  ImageWidth,ImageHeight,
                  DistrArr, CameraMArr );


 CameraMArr[0,0]:=CameraMArr[0,0]*xDist;
 CameraMArr[1,1]:=CameraMArr[1,1]*yDist;
 
 CR:=#13#10#13#10;
 S:=(Print2DArr(DistrArr)+CR+
     Print2DArr(CameraMArr)
     );

 if not Assigned(ResultsForm) then
    ResultsForm:=TResultsForm.Create(Application);
 ResultsForm.Show;
 ResultsForm.Memo1.Text:=S;


end;

procedure TMainForm.IdSpinEditChange(Sender: TObject);
begin
 CurrentImageId:=IdSpinEdit.Value;
end;

procedure TMainForm.TimeSpinEditChange(Sender: TObject);
begin
 //Timer1.Interval:=TimeSpinEdit.Value;
end;

procedure TMainForm.RowSpinEditChange(Sender: TObject);
begin
 RowCount:=RowSpinEdit.Value;
end;

procedure TMainForm.ColSpinEditChange(Sender: TObject);
begin
 ColCount:=ColSpinEdit.Value;
end;


procedure TMainForm.SpeedButton9Click(Sender: TObject);
begin
 VideoWindow.FullScreen:=SpeedButton9.Down;
end;

procedure TMainForm.SpeedButton1Click(Sender: TObject);
begin
//SampleGrabber.GetBitmap(Image.Picture.Bitmap);
 //Image.Picture.SaveToFile('Sample.bmp');

 SampleGrabber.GetBitmap(Bitmap);
 ImgView.Bitmap.Assign(Bitmap);
 Bitmap.SaveToFile('Sample.bmp');

 //GetBitmap32(ImgView.Bitmap);
end;

procedure TMainForm.OpenPicFile(FileName : String);
begin
   LoadedFileName:=FileName;
   ImgView.Bitmap.LoadFromFile(FileName);
end;


procedure TMainForm.Draw2DPoint2fArr( Arr : T2DPoint2fArr );
Var
 Dst : TBitmap32;
 B   : TBitmapLayer;
 i,j,x,y : integer;
begin
 Dst:=TBitmap32.Create;

 Dst.Font.Color:=clLime;
 Dst.UpdateFont;

 try
    CheckParams(Dst,ImgView.Bitmap);

    // îáîçíà÷èòü óçëû
     for i:=0 to High(Arr) do //arr1
         for j:=0 to High(Arr[i]) do begin //arr2

             x:=Round( Arr[i,j].x );
             y:=Round( Arr[i,j].y );

             Dst.PixelS[x,y]:=clWhite32;
             Circle(Dst,x,y,10,clWhite32);

             //Dst.TextOut(x,y,format('%d/%d',[i,j]) );

             if (x-8>=0)and(y-8>=0)and
                (x-8<Dst.Width)and(y-8<Dst.Height) then
                Dst.RenderText(x-8,y-8,format('%d/%d',[i,j]),0, clRed32 );
         end;

    ImgView.Layers.Clear;
    B := TBitmapLayer.Create(ImgView.Layers);
    with B do
    try
      Bitmap.Assign(Dst);
      Bitmap.DrawMode := dmBlend;
      Bitmap.MasterAlpha:=150;
      Scaled := True;
      Location := FloatRect(0,0,ImgView.Bitmap.Width,ImgView.Bitmap.Height);
    except
      Free;
      raise;
    end;

 finally
    Dst.free;
 end;

end;


procedure TMainForm.DoFindExtrinsicCameraParams;
Var
 FileName     : String;

 i,j,k,n,m    : integer;
 RArr,
 TArr,
 MArr,
 InvMArr      : T2DPoint1fArr;
 S,S_,CR,CRCR : String;
 a, b, g      : single;
 CornerArr    : T2DPoint2fArr;
 Res          : Boolean;
begin
 RowCount:=RowSpinEdit.Value;
 ColCount:=ColSpinEdit.Value;
                                     //SONY DFW-SX900
 squarewidth:=SquareWidthEdit.Value; // 27.4; {mm}
 xdist:=xDistEdit.Value/1000;        //4.65e-3;     {mm}
 ydist:=yDistEdit.Value/1000;        //4.65e-3;     {mm}
 f:=fEdit.Value;                     //12.5;        {mm}

 OpenPictureDialog.InitialDir:=GetName('');
 OpenPictureDialog.FilterIndex:=1;
 if OpenPictureDialog.Execute then begin
    FileName:=OpenPictureDialog.FileName;
    OpenPicFile(FileName);

    Res:=FindExtrinsicCameraParams( FileName,RowCount,ColCount,
                                    squarewidth,
                                    xDist, yDist,f,
                                    RArr, TArr, MArr, InvMArr,
                                    CornerArr );
    if not Res then begin
       Beep;
       Exit;
    end;

    {
    FileName:=GetFirstToken(FileName,'.');
    FileName:=FileName+'.ocv';
    SaveArr(fileName,CornerArr);
    }
    
    Draw2DPoint2fArr(CornerArr);
    
    S_:='';
    if GetAngles(RArr,a, b, g) then
       S_:=format(' a=%.2f  b=%.2f g=%.2f',[a,b,g]);


    if not Assigned(GLForm) then
       GLForm:=TGLForm.Create(Application);    
    With GLForm.DummyCube2 do begin
         Position.SetPoint( TArr[0,0],TArr[0,1],TArr[0,2] );

         Direction.SetVector( 0,0,1 );
         Up.SetVector( 0,1,0 );

         Direction.SetVector( RArr[0,2],RArr[1,2],RArr[2,2] );//z
         Direction.Normalize;

         Up.SetVector( RArr[0,1],RArr[1,1],RArr[2,1] );//y
         Up.Normalize;
    end;

    CR:=#13#10;
    CRCR:=#13#10#13#10;

    S:=('Rotation Matrix'+CR+
        Print2DArr(RArr)+CRCR+
        'Translation Vector'+CR+
        Print2DArr(TArr)+CRCR+
        'Homographi Matrix'+CR+
        Print2DArr(MArr)+CRCR+
        'PseudoInverse Homographi Matrix'+CR+
        Print2DArr(InvMArr)+CRCR+
        S_);


    if not Assigned(ResultsForm) then
       ResultsForm:=TResultsForm.Create(Application);
    ResultsForm.Show;
    ResultsForm.Memo1.Text:=S;
   
 end;

end;


procedure TMainForm.SaveImageAs1Click(Sender: TObject);
Var
 FileName : String;
begin
 SavePictureDialog.InitialDir:=GetName('');
 if SavePictureDialog.Execute then begin
    FileName:=SavePictureDialog.FileName;
    Bitmap.SaveToFile(FileName);
 end;   
end;

procedure TMainForm.LoadImage1Click(Sender: TObject);
Var
 FileName : String;
begin
 OpenPictureDialog.InitialDir:=GetName('');
 OpenPictureDialog.FilterIndex:=1;
 if OpenPictureDialog.Execute then begin
    FileName:=OpenPictureDialog.FileName;
    OpenPicFile(FileName);
 end;   
end;

procedure TMainForm.FindExtrinsin1Click(Sender: TObject);
begin
 DoFindExtrinsicCameraParams;
end;

procedure TMainForm.SavePresets1Click(Sender: TObject);
begin
 With TIniFile.Create(GetName('Data','PreSets.ini')) do
 try
    
    WriteInteger('Main','Time',      TimeSpinEdit.Value);
    WriteInteger('Main','NumImages', MaxSpinEdit.Value);
    WriteInteger('Main','RowCount',  RowSpinEdit.Value);
    WriteInteger('Main','ColCount',  ColSpinEdit.Value);

    WriteFloat('Main','squarewidth', SquareWidthEdit.Value);
    WriteFloat('Main','xdist',       xDistEdit.Value);
    WriteFloat('Main','ydist',       yDistEdit.Value);
    WriteFloat('Main','f',           fEdit.Value);
    
    WriteInteger('Main','ImageWidth',  WidthEdit.Value);
    WriteInteger('Main','ImageHeight', HeightEdit.Value); 
  
 
 Finally
   Free;
 end;
 
end;

procedure TMainForm.Load1Click(Sender: TObject);
begin
 With TIniFile.Create(GetName('Data','PreSets.ini')) do
 try
    
  TimeSpinEdit.Value := ReadInteger('Main','Time',1500);        
  MaxSpinEdit.Value  := ReadInteger('Main','NumImages',20);   
  RowSpinEdit.Value  := ReadInteger('Main','RowCount',6);    
  ColSpinEdit.Value  := ReadInteger('Main','ColCount',8);    

  SquareWidthEdit.Value := ReadFloat('Main','squarewidth',27.4);   
  xDistEdit.Value       := ReadFloat('Main','xdist',4.65);         
  yDistEdit.Value       := ReadFloat('Main','ydist',4.65);         
  fEdit.Value           := ReadFloat('Main','f', 12.5);            
    
  WidthEdit.Value   := ReadInteger('Main','ImageWidth',1280);  
  HeightEdit.Value  := ReadInteger('Main','ImageHeight',960); 
 
 Finally
   Free;
 end;

end;

end.
