    (*********************************************************************
     *                                                                   *
     *  Borland Delphi 4,5,6,7 API for                                   *
     *  Intel Open Source Computer Vision Library                        *
     *                                                                   *
     *                                                                   *
     *  Portions created by Intel Corporation are                        *
     *  Copyright (C) 2000, Intel Corporation, all rights reserved.      *
     *                                                                   *
     *  The original files are: CV.h, CVTypes.h, highgui.h               *        
     *                                                                   *
     *                                                                   *
     *  The original Pascal code is: OpenCV.pas,  released 29 May 2003.  *                                 
     *                                                                   *
     *  The initial developer of the Pascal code is Vladimir Vasilyev    *        
     *                  home page : http://www.nextnow.com               *
     *                  email     : Vladimir@nextnow.com                 *
     *                              W-develop@mtu-net.ru                 *
     *                                                                   *
     *  Contributors: Andrey Klimov                                      *
     *                                                                   *
     *  You may retrieve the latest version of this file here:           *
     *                             http://www.nextnow.com                *
     *                                                                   *
     *                                                                   *
     *  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 OpenCV;

{$A+,Z+}
{$ASSERTIONS on}

interface

uses
  Windows,Sysutils,IPL;

const
 cvDLL = 'CV.DLL';
 HighGUI_DLL='HighGUI.DLL';

 
 CV_32F = 4;
 CV_32FC1 = CV_32F + 0*8;

 CV_MAT_TYPE_MASK = 31;
 CV_MAT_MAGIC_VAL = $42420000;
 CV_MAT_CONT_FLAG_SHIFT = 9;
 CV_MAT_CONT_FLAG = 1 shl CV_MAT_CONT_FLAG_SHIFT;

 CV_MAT_CN_MASK = 3 shl 3;
 CV_MAT_DEPTH_MASK = 7;

 CV_RODRIGUES_M2V = 0;
 CV_RODRIGUES_V2M = 1;


 CV_LU  = 0;
 CV_SVD = 1;


 CV_RGB2GRAY = 7;
type

  PCvVect32f = PSingle;
  TCvVect32fArr=array of Single;

  PCvMatr32f = PSingle;
  TCvMatr32fArr=array of Single;
  
  TIntegerArr=array of Integer;
  
  PCvArr = Pointer;

  CvSize = record
            width  : integer;
            height : integer;
           end;
  TCvSize = CvSize;
  PCvSize = ^TCvSize;

  CvPoint2D32f = record
                    x : Single;
                    y : Single;
                 end;
  TCvPoint2D32f = CvPoint2D32f;
  PCvPoint2D32f = ^TCvPoint2D32f;
  TCvPoint2D32fArr=array of TCvPoint2D32f;


  CvPoint3D32f = record
                    x : Single;
                    y : Single;
                    z : Single;
                 end;
  TCvPoint3D32f = CvPoint3D32f;
  PCvPoint3D32f = ^TCvPoint3D32f;
  TCvPoint3D32fArr=array of TCvPoint3D32f;

  TMatData = record
               ptr: PUCHAR;
             end;

  CvMat = record
            type_    : Integer;
            step     : Integer;
            refcount : PInteger;
            data     : TMatData;
            rows     : Integer;
            cols     : Integer;
          end;
  TCvMat = CvMat;
  PCvMat = ^TCvMat;


//******************************** Memory storage ****************************************/
Type
  PCvMemBlock = ^TCvMemBlock;
  CvMemBlock = Record
                 prev : PCvMemBlock;
                 next : PCvMemBlock;
               end;
  TCvMemBlock = CvMemBlock;

Const CV_STORAGE_MAGIC_VAL = $42890000;

Type
  PCvMemStorage = ^TCvMemStorage;               
  CvMemStorage = Record
                   signature : integer;
                   bottom    : PCvMemBlock;   //* first allocated block */
                   top       : PCvMemBlock;   //* current memory block - top of the stack */
                   parent    : PCvMemStorage; //* borrows new blocks from */
                   block_size: integer;       //* block size */
                   free_space: integer;       //* free space in the current block */
                 end;
  TCvMemStorage = CvMemStorage;               
{\******************************** Memory storage ****************************************}
  

//*********************************** CvTermCriteria *************************************/
Const
 CV_TERMCRIT_ITER = 1;
 CV_TERMCRIT_NUMB = CV_TERMCRIT_ITER;
 CV_TERMCRIT_EPS  = 2;

Type
  CvTermCriteria  = Record
                      type_   : integer;  { may be combination of CV_TERMCRIT_ITER, CV_TERMCRIT_EPS }
                      maxIter : integer;
                      epsilon : double;
                    end;
  TCvTermCriteria = CvTermCriteria;                  
{\*********************************** CvTermCriteria *************************************}
                    
  
 Procedure cvFindExtrinsicCameraParams( numPoints         : integer;
                                        imageSize         : TCvSize;
                                        imagePoints32f    : PCvPoint2D32f;
                                        objectPoints32f   : PCvPoint3D32f;
                                        focalLength32f    : PCvVect32f;
                                        principalPoint32f : TCvPoint2D32f;
                                        distortion32f     : PCvVect32f;
                                        rotVect32f        : PCvVect32f;
                                        transVect32f      : PCvVect32f 
                                        ); cdecl;


{ Calibrates camera using multiple views of calibration pattern }
 Procedure  cvCalibrateCamera( numImages         : Integer;        //int           
                               numPoints         : PInteger;       //int*          
                               imageSize         : TCvSize;        //CvSize        
                               imagePoints32f    : PCvPoint2D32f;  //CvPoint2D32f* 
                               objectPoints32f   : PCvPoint3D32f;  //CvPoint3D32f* 
                               distortion32f     : PCvVect32f;     //CvVect32f     
                               cameraMatrix32f   : PCvMatr32f;     //CvMatr32f     
                               transVects32f     : PCvVect32f;     //CvVect32f     
                               rotMatrs32f       : PCvMatr32f;     //CvMatr32f     
                               useIntrinsicGuess : Integer         //int 
                               ); cdecl;

                                        
 Procedure cvRodrigues( rotMatrix : PCVMAT;
                        rotVector : PCVMAT;
                        jacobian  : PCVMAT;
                        convType  : Integer ); cdecl ;


                       
 { Allocates array data }
 Procedure cvCreateData( arr : Pointer ); cdecl;
 { Releases array data  }
 Procedure cvReleaseData(arr : Pointer ); cdecl;



 Function  cvInvert( const A : PCvArr; B : PCvArr; method : integer ) : double; cdecl;
 Function  cvPseudoInverse( const src : PCvArr; dst : PCvArr ) : double;

 Procedure cvMatMulAdd( const  A,B,C : PCvArr;  D : PCvArr ); cdecl;
 Procedure cvMatMul( A,B,D : PCvArr );


 Function  cvMat_( rows, cols, type_: Integer; data : Pointer ):TCvMat;
 Function  cvmGet( const mat : PCvMat; i, j : integer): Single;
 Procedure cvmSet( mat : PCvMat; i, j : integer; val: Single);

 Function  cvSize_( width, height : integer ) : TcvSize;


 { load image from file 
   iscolor: >0 - output image is always color,
             0 - output image is always grayscale,
            <0 - output image is color or grayscale dependending on the file }
 Function  cvLoadImage( const filename : PChar; iscolor : integer=1) : PIplImage; cdecl;
 Function  cvSaveImage( const filename : PChar; const image : Pointer) : integer; cdecl;


 { Allocates and initializes IplImage header }
 Function cvCreateImageHeader( size : TCvSize; depth, channels : integer ) : PIplImage; cdecl;
 { Releases (i.e. deallocates) IPL image header  : void  cvReleaseImageHeader( IplImage** image );}
 Procedure cvReleaseImageHeader( var image : PIplImage ); cdecl;
 { Releases IPL image header and data }
 Procedure cvReleaseImage(  var image : PIplImage ); cdecl;
 { Creates a copy of IPL image (widthStep may differ). }
 Function  cvCloneImage( const image : PIplImage ) : PIplImage; cdecl;


 { Converts input array from one color space to another. }
 Procedure cvCvtColor( const src : Pointer; dst : Pointer; colorCvtCode : integer );  cdecl;


 { Creates new memory storage.
   block_size == 0 means that default, somewhat optimal size, is used (currently, it is 64K). }
 Function  cvCreateMemStorage( block_size : integer =0) : PCvMemStorage; cdecl;
 { Releases memory storage. All the children of a parent must be released before
   the parent. A child storage returns all the blocks to parent when it is released  }
 Procedure cvReleaseMemStorage( var storage : PCvMemStorage ); cdecl;


 { Detects corners on a chess-board - "brand" OpenCV calibration pattern }
 Function  cvFindChessBoardCornerGuesses( const arr          : Pointer;
                                                thresh       : Pointer;
                                                storage      : PCvMemStorage;
                                                etalon_size  : TCvSize;
                                                corners      : PCvPoint2D32f;
                                                corner_count : PInteger ) : integer;  cdecl;

 {  Adjust corner position using some sort of gradient search }
 Procedure  cvFindCornerSubPix( const src         : Pointer;
                                      corners     : PCvPoint2D32f;
                                      count       : integer;
                                      win         : TCvSize;
                                      zero_zone   : TCvSize;
                                      criteria    : TCvTermCriteria ); cdecl;

                                              
implementation

 
 Procedure cvCreateData;                  external cvDLL name 'cvCreateData';
 Procedure cvReleaseData;                 external cvDLL name 'cvReleaseData';

 Function  cvCreateImageHeader;           external cvDLL name 'cvCreateImageHeader';
 Procedure cvReleaseImageHeader;          external cvDLL name 'cvReleaseImageHeader';
 Procedure cvReleaseImage;                external cvDLL name 'cvReleaseImage';


 Procedure cvCalibrateCamera;             external cvDLL name 'cvCalibrateCamera';
  
 Procedure cvFindExtrinsicCameraParams;   external cvDLL name 'cvFindExtrinsicCameraParams';
 Procedure cvRodrigues;                   external cvDLL name 'cvRodrigues';
 Function  cvInvert;                      external cvDLL name 'cvInvert';
 Procedure cvMatMulAdd;                   external cvDLL name 'cvMatMulAdd';
 Procedure cvCvtColor;                    external cvDLL name 'cvCvtColor';
 Function  cvCloneImage;                  external cvDLL name 'cvCloneImage';
 
 Function  cvCreateMemStorage;            external cvDLL name 'cvCreateMemStorage';
 Procedure cvReleaseMemStorage;           external cvDLL name 'cvReleaseMemStorage';

 Function  cvFindChessBoardCornerGuesses; external cvDLL name 'cvFindChessBoardCornerGuesses';
 Procedure cvFindCornerSubPix;            external cvDLL name 'cvFindCornerSubPix';

 
 Function  cvLoadImage; external HighGUI_DLL name 'cvLoadImage';
 Function  cvSaveImage; external HighGUI_DLL name 'cvSaveImage';

 
 Procedure cvMatMul( A,B,D : PCvArr );
 begin
    cvMatMulAdd(A,B,nil,D);
 end;


 function CV_MAT_TYPE( flags : integer): integer;
 begin
    Result:=(flags and CV_MAT_TYPE_MASK);
 end;

 function CV_MAT_DEPTH( flags : integer): integer;
 begin
    Result:=(flags and CV_MAT_DEPTH_MASK);
 end;

 function CV_MAT_CN( flags : integer): integer;
 begin
    Result:=((flags and CV_MAT_CN_MASK) shr 3)+1;
 end;

 function CV_ELEM_SIZE( type_ : integer): integer;
 begin
    Result:=(CV_MAT_CN(type_) shl (($e90 shr CV_MAT_DEPTH(type_)*2) and 3));
 end;

 function cvMat_( rows : Integer; cols : Integer; type_: Integer; data : Pointer) : CvMat ;
 begin
    type_:= CV_MAT_TYPE(type_);
    Result.type_:= CV_MAT_MAGIC_VAL or CV_MAT_CONT_FLAG or type_;
    Result.cols := cols;
    Result.rows := rows;
    Result.step := Result.cols*CV_ELEM_SIZE(type_);
    Result.data.ptr := PUCHAR(data);
    Result.refcount := nil;
 end;

 
 Function cvmGet( const mat : PCvMat; i, j : integer): Single;
 var
  type_ : integer;
  ptr   : PUCHAR;
  pf    : PSingle;
 begin
    type_:= CV_MAT_TYPE(mat.type_);
    assert(  ( i<mat.rows) and (j<mat.cols) );

    if type_ = CV_32FC1 then begin
       ptr:=mat.data.ptr;
       inc(ptr, mat.step*i+ sizeOf(Single)*j);
       pf:=PSingle(ptr);
       Result:=pf^;
    end;

 end;


 Procedure cvmSet( mat : PCvMat; i, j : integer; val: Single  );
 var
  type_ : integer;
  ptr   : PUCHAR;
  pf    : PSingle;
 begin
    type_:= CV_MAT_TYPE(mat.type_);
    assert(  ( i<mat.rows) and (j<mat^.cols) );

    if type_ = CV_32FC1 then begin
       ptr:=mat.data.ptr;
       inc(ptr, mat.step*i+ sizeOf(Single)*j);
       pf:=PSingle(ptr);
       pf^:=val;
    end;

 end;

 Function cvPseudoInverse( const src : PCvArr; dst : PCvArr ) : double;
 begin
    cvInvert( src, dst, CV_SVD );
 end;


 Function cvSize_( width, height : integer ) : TcvSize;
 begin
    Result.width:=width;
    Result.height:=height;
 end;
 
end.


