2014-05-19 21:29:48 +02:00
// *****************************************************************
// Delphi-OpenCV Demo
// Copyright (C) 2013 Project Delphi-OpenCV
// ****************************************************************
// Contributor:
// laentir Valetov
// email:laex@bk.ru
// ****************************************************************
// You may retrieve the latest version of this file at the GitHub,
// located at git://github.com/Laex/Delphi-OpenCV.git
// ****************************************************************
// 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_1Final.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.
// ***************************************************************
// Original file:
// http://blog.vidikon.com/?p=213
// ***************************************************************
2013-04-14 19:17:55 +02:00
program cv_ExtractSURF;
{$APPTYPE CONSOLE}
{$POINTERMATH ON}
{$R *.res}
uses
System. SysUtils,
2013-05-26 10:50:18 +02:00
Winapi . Windows,
2014-05-22 08:53:48 +02:00
opencv. highgui_c,
opencv. core_c,
opencv. core. types_c,
opencv. imgproc_c,
opencv. imgproc. types_c,
opencv. compat,
opencv. calib3d_c,
opencv. nonfree,
2014-05-19 21:29:48 +02:00
uResourcePaths;
2013-04-14 19:17:55 +02:00
2013-04-18 08:34:16 +02:00
// c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD>
2014-02-24 20:18:30 +01:00
// comparison of the two features
2013-04-14 19:17:55 +02:00
function compareSURFDescriptors( const d1: PSingle ; const d2: PSingle ; best: Double ; length : Integer ) : Double ;
2013-05-21 10:53:30 +02:00
var
2013-04-14 19:17:55 +02:00
total_cost: Double ;
i: Integer ;
t0, t1, t2, t3: Double ;
begin
total_cost : = 0 ;
assert( length mod 4 = 0 ) ;
i : = 0 ;
While i < length - 1 do
begin
t0 : = d1[ i] - d2[ i] ;
t1 : = d1[ i + 1 ] - d2[ i + 1 ] ;
t2 : = d1[ i + 2 ] - d2[ i + 2 ] ;
t3 : = d1[ i + 3 ] - d2[ i + 3 ] ;
total_cost : = total_cost + t0 * t0 + t1 * t1 + t2 * t2 + t3 * t3;
if ( total_cost > best) then
break;
i : = i + 4 ;
end ;
result : = total_cost;
end ;
2013-04-18 08:34:16 +02:00
// c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<> <20> c<EFBFBD> <63> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD> <EFBFBD> c<> <63> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// compares one feature of the scene with all the features
2014-05-19 21:29:48 +02:00
function naiveNearestNeighbor( const vec: PSingle ; laplacian: Integer ; const model_keypoints: pCvSeq;
const model_descriptors: pCvSeq) : Integer ;
2013-04-14 19:17:55 +02:00
Var
length , i, neighbor: Integer ;
d, dist1, dist2: Double ;
reader, kreader: TCvSeqReader;
kp: pCvSURFPoint;
mvec: PSingle ;
begin
length : = model_descriptors. elem_size div sizeof( single ) ;
neighbor : = - 1 ;
dist1 : = 1E6 ;
dist2 : = 1E6 ; ;
2013-04-18 08:34:16 +02:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> c<> <63> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// The initial feature scenes
2013-04-14 19:17:55 +02:00
cvStartReadSeq( model_keypoints, @ kreader, 0 ) ;
cvStartReadSeq( model_descriptors, @ reader, 0 ) ;
2013-04-18 08:34:16 +02:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD> c<> <63> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// Iterating through all features of the scene
2013-04-14 19:17:55 +02:00
for i : = 0 to model_descriptors. total - 1 do
begin
kp : = pCvSURFPoint( kreader. ptr) ;
mvec : = PSingle( reader. ptr) ;
CV_NEXT_SEQ_ELEM( kreader. seq. elem_size, kreader) ;
CV_NEXT_SEQ_ELEM( reader. seq. elem_size, reader) ;
2013-04-18 08:34:16 +02:00
// <20> <> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <20> <> <EFBFBD> <EFBFBD> cc<63> <63> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD>
2014-02-24 20:18:30 +01:00
// To accelerate the first compared Laplacian features
2013-04-14 19:17:55 +02:00
if ( laplacian < > kp. laplacian) then
continue;
2013-04-18 08:34:16 +02:00
// c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD>
2014-02-24 20:18:30 +01:00
// comparison of the features
2013-04-14 19:17:55 +02:00
d : = compareSURFDescriptors( vec, mvec, dist2, length ) ;
if ( d < dist1) then
begin
2013-04-18 08:34:16 +02:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD>
2014-02-24 20:18:30 +01:00
// Found a better match features
2013-04-14 19:17:55 +02:00
dist2 : = dist1;
dist1 : = d;
neighbor : = i;
end
else if ( d < dist2) then
dist2 : = d;
end ;
if ( dist1 < 0.6 * dist2) then
Exit( neighbor) ;
result : = - 1 ;
end ;
2013-04-18 08:34:16 +02:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// Function searches for matching pairs
2014-05-19 21:29:48 +02:00
procedure findPairs( const objectKeypoints: pCvSeq; const objectDescriptors: pCvSeq; const imageKeypoints: pCvSeq;
const imageDescriptors: pCvSeq; Var ptpairs: TArray< Integer > ) ;
2013-04-14 19:17:55 +02:00
var
i: Integer ;
reader, kreader: TCvSeqReader;
kp: pCvSURFPoint;
descriptor: PSingle ;
nearest_neighbor: Integer ;
begin
2013-04-18 08:34:16 +02:00
// <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> cc<63> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// Sets the initial features of object recognition
2013-04-14 19:17:55 +02:00
cvStartReadSeq( objectKeypoints, @ kreader) ;
cvStartReadSeq( objectDescriptors, @ reader) ;
SetLength( ptpairs, 0 ) ;
2013-04-18 08:34:16 +02:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// Iterating through all features of the object
2013-04-14 19:17:55 +02:00
for i : = 0 to objectDescriptors. total - 1 do
begin
kp : = pCvSURFPoint( kreader. ptr) ;
descriptor : = PSingle( reader. ptr) ;
CV_NEXT_SEQ_ELEM( kreader. seq. elem_size, kreader) ;
CV_NEXT_SEQ_ELEM( reader. seq. elem_size, reader) ;
2013-04-18 08:34:16 +02:00
// c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> c<> <20> c<EFBFBD> <63> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <20> <> c<> <63> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// comparison of the current features with all the features of the scene
2013-04-14 19:17:55 +02:00
nearest_neighbor : = naiveNearestNeighbor( descriptor, kp. laplacian, imageKeypoints, imageDescriptors) ;
if ( nearest_neighbor > = 0 ) then
begin
2013-04-18 08:34:16 +02:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD>
2014-02-24 20:18:30 +01:00
// Match the features found
2013-04-14 19:17:55 +02:00
SetLength( ptpairs, length( ptpairs) + 2 ) ;
ptpairs[ High( ptpairs) - 1 ] : = i;
ptpairs[ High( ptpairs) ] : = nearest_neighbor;
end ;
end ;
end ;
2014-02-24 20:18:30 +01:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// Finding rough position of the object
2014-05-19 21:29:48 +02:00
function locatePlanarObject( const objectKeypoints: pCvSeq; const objectDescriptors: pCvSeq; const imageKeypoints: pCvSeq;
const imageDescriptors: pCvSeq; const src_corners: TArray< TCvPoint> ; dst_corners: TArray< TCvPoint> ) : Integer ;
2013-04-14 19:17:55 +02:00
var
h: array [ 0 .. 8 ] of Double ;
_h: TCvMat;
ptpairs: TArray< Integer > ;
pt1, pt2: TArray< TCvPoint2D32f> ;
_pt1, _pt2: TCvMat;
i, n: Integer ;
x, y, _Z, _X, _Y: Double ;
begin
_h : = cvMat( 3 , 3 , CV_64F, @ h) ;
2014-02-24 20:18:30 +01:00
// <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD>
// We are looking for a pair of features on each image that correspond to each other
2013-04-14 19:17:55 +02:00
findPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs) ;
n : = length( ptpairs) div 2 ;
2013-04-18 08:34:16 +02:00
// <20> c<EFBFBD> <63> <20> <> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// If found little pair, then have to go - object not found
2013-04-14 19:17:55 +02:00
if ( n < 4 ) then
Exit( 0 ) ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
SetLength( pt1, n) ;
SetLength( pt2, n) ;
2013-04-18 08:34:16 +02:00
// c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// read the coordinates of the "singular" points
2013-04-14 19:17:55 +02:00
for i : = 0 to n - 1 do
begin
pt1[ i] : = pCvSURFPoint( cvGetSeqElem( objectKeypoints, ptpairs[ i * 2 ] ) ) . pt;
pt2[ i] : = pCvSURFPoint( cvGetSeqElem( imageKeypoints, ptpairs[ i * 2 + 1 ] ) ) . pt;
end ;
2013-04-18 08:34:16 +02:00
// <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// Using computed vectors - creating a matrix
2013-04-14 19:17:55 +02:00
_pt1 : = cvMat( 1 , n, CV_32FC2, @ pt1[ 0 ] ) ;
_pt2 : = cvMat( 1 , n, CV_32FC2, @ pt2[ 0 ] ) ;
2014-02-24 20:18:30 +01:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> c <20> <> <EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
// Find the transformation between the original image and the fact that looking
2013-04-14 19:17:55 +02:00
if ( cvFindHomography( @ _pt1, @ _pt2, @ _h, CV_RANSAC, 5 ) = 0 ) then
Exit( 0 ) ;
2013-04-18 08:34:16 +02:00
// <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> (<28> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> _h) <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2013-04-14 19:17:55 +02:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// Using the values transformation (in the matrix _h) find
// the coordinates of a quadrilateral, indicative of the object
2013-04-14 19:17:55 +02:00
for i : = 0 to 3 do
begin
x : = src_corners[ i] . x;
y : = src_corners[ i] . y;
_Z : = 1 . / ( h[ 6 ] * x + h[ 7 ] * y + h[ 8 ] ) ;
_X : = ( h[ 0 ] * x + h[ 1 ] * y + h[ 2 ] ) * _Z;
_Y : = ( h[ 3 ] * x + h[ 4 ] * y + h[ 5 ] ) * _Z;
dst_corners[ i] : = cvPoint( cvRound( _X) , cvRound( _Y) ) ;
end ;
Exit( 1 ) ;
end ;
Var
object_filename, scene_filename: AnsiString ;
storage: pCvMemStorage;
colors: array [ 0 .. 8 ] of TCvScalar = (
(
val:
(
0 ,
0 ,
2 5 5 ,
0
)
) ,
(
val:
(
0 ,
1 2 8 ,
2 5 5 ,
0
)
) ,
(
val:
(
0 ,
2 5 5 ,
2 5 5 ,
0
)
) ,
(
val:
(
0 ,
2 5 5 ,
0 ,
0
)
) ,
(
val:
(
2 5 5 ,
1 2 8 ,
0 ,
0
)
) ,
(
val:
(
2 5 5 ,
2 5 5 ,
0 ,
0
)
) ,
(
val:
(
2 5 5 ,
0 ,
0 ,
0
)
) ,
(
val:
(
2 5 5 ,
0 ,
2 5 5 ,
0
)
) ,
(
val:
(
2 5 5 ,
2 5 5 ,
2 5 5 ,
0
)
)
) ;
_object, image, object_color: pIplImage;
objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors: pCvSeq;
i: Integer ;
params: TCvSURFParams;
tt: Double ;
src_corners, dst_corners: TArray< TCvPoint> ;
correspond: pIplImage;
r1, r2: TCvPoint;
ptpairs: TArray< Integer > ;
_r1, _r2: pCvSURFPoint;
r: pCvSURFPoint;
center: TCvPoint;
radius: Integer ;
begin
try
initModule_nonfree;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// initialization parameters
2014-05-19 21:29:48 +02:00
object_filename : = iif( ParamCount = 2 , ParamStr( 1 ) , cResourceMedia + 'box.png' ) ;
scene_filename : = iif( ParamCount = 2 , ParamStr( 2 ) , cResourceMedia + 'box_in_scene.png' ) ;
2013-04-14 19:17:55 +02:00
storage : = cvCreateMemStorage( 0 ) ;
cvNamedWindow( 'Object' , 1 ) ;
cvNamedWindow( 'Object Correspond' , 1 ) ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// Loading Images
2013-04-14 19:17:55 +02:00
_object : = cvLoadImage( pcvChar( @ object_filename[ 1 ] ) , CV_LOAD_IMAGE_GRAYSCALE) ;
image : = cvLoadImage( pcvChar( @ scene_filename[ 1 ] ) , CV_LOAD_IMAGE_GRAYSCALE) ;
if ( not Assigned( _object) ) or ( not Assigned( image) ) then
begin
WriteLn( Format( 'Can not load %s and/or %s' , [ object_filename, scene_filename] ) ) ;
WriteLn( 'Usage: find_obj [<object_filename> <scene_filename>]' ) ;
Halt;
end ;
2013-04-18 08:34:16 +02:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<> <63> <EFBFBD> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// Translation grayscale
2013-04-14 19:17:55 +02:00
object_color : = cvCreateImage( cvGetSize( _object) , 8 , 3 ) ;
cvCvtColor( _object, object_color, CV_GRAY2BGR) ;
2014-02-24 20:18:30 +01:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> CvSURFParams c <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> 128 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// Initialization of the structure CvSURFParams c size descriptors 128 items
2013-04-14 19:17:55 +02:00
params : = CvSURFParams( 5 0 0 , 1 ) ;
2014-02-24 20:18:30 +01:00
// <20> <> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD>
// note the time
2013-04-14 19:17:55 +02:00
tt : = cvGetTickCount( ) ;
2013-04-18 08:34:16 +02:00
// <20> <> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> cc<63> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// We are looking for particular object recognition
2013-04-14 19:17:55 +02:00
cvExtractSURF( _object, nil , @ objectKeypoints, @ objectDescriptors, storage, params) ;
WriteLn( Format( 'Object Descriptors: %d' , [ objectDescriptors. total] ) ) ;
2013-04-18 08:34:16 +02:00
// <20> <> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> c<> <63> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// We are looking for particular scenes
2013-04-14 19:17:55 +02:00
cvExtractSURF( image, nil , @ imageKeypoints, @ imageDescriptors, storage, params) ;
WriteLn( Format( 'Image Descriptors: %d' , [ imageDescriptors. total] ) ) ;
2013-04-18 08:34:16 +02:00
// c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> (<28> <20> <> <EFBFBD> <EFBFBD> 167 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> )
2014-02-24 20:18:30 +01:00
// how long it took (I 167 milliseconds)
2013-04-14 19:17:55 +02:00
tt : = cvGetTickCount( ) - tt;
WriteLn( Format( 'Extraction time = %gms' , [ tt / ( cvGetTickFrequency( ) * 1 0 0 0 ) ] ) ) ;
2014-02-24 20:18:30 +01:00
// <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63>
// Set the image borders, within which features will be compared
2013-04-14 19:17:55 +02:00
SetLength( src_corners, 4 ) ;
src_corners[ 0 ] : = cvPoint( 0 , 0 ) ;
src_corners[ 1 ] : = cvPoint( _object. width, 0 ) ;
src_corners[ 2 ] : = cvPoint( _object. width, _object. height) ;
src_corners[ 3 ] : = cvPoint( 0 , _object. height) ;
SetLength( dst_corners, 4 ) ;
2013-04-18 08:34:16 +02:00
// c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> (<28> <20> <> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> c<> <63> <EFBFBD> <EFBFBD> <20> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> )
// <20> <> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <20> <> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// creation of an additional image (it will be a scene and object)
// Run the example and you will understand what I mean
2013-04-14 19:17:55 +02:00
correspond : = cvCreateImage( cvSize( image. width, _object. height + image. height) , 8 , 1 ) ;
cvSetImageROI( correspond, cvRect( 0 , 0 , _object. width, _object. height) ) ;
cvCopy( _object, correspond) ;
cvSetImageROI( correspond, cvRect( 0 , _object. height, correspond. width, correspond. height) ) ;
cvCopy( image, correspond) ;
cvResetImageROI( correspond) ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// Call the function that retrieves the object on the screen
2014-05-19 21:29:48 +02:00
if ( locatePlanarObject( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, src_corners, dst_corners) < > 0 )
then
2013-04-14 19:17:55 +02:00
begin
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// Draw out the desired quadrangle
2013-04-14 19:17:55 +02:00
for i : = 0 to 3 do
begin
r1 : = dst_corners[ i mod 4 ] ;
r2 : = dst_corners[ ( i + 1 ) mod 4 ] ;
cvLine( correspond, cvPoint( r1. x, r1. y + _object. height) , cvPoint( r2. x, r2. y + _object. height) , colors[ 8 ] ) ;
end ;
end ;
2014-02-24 20:18:30 +01:00
// <20> c<EFBFBD> <63> <20> <20> <> <EFBFBD> <EFBFBD> <20> <> c<EFBFBD> <63> <20> <> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> , <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <20> <> , <20> <> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> c<EFBFBD> <63> <EFBFBD> <EFBFBD> 23.3.
2013-04-18 08:34:16 +02:00
// c<> <63> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> c<EFBFBD> <20> c<EFBFBD> c<> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD> <20> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// again finds all the matching pairs of features in both pictures
2013-04-14 19:17:55 +02:00
findPairs( objectKeypoints, objectDescriptors, imageKeypoints, imageDescriptors, ptpairs) ;
2013-04-18 08:34:16 +02:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD> <20> <> <20> <> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2014-02-24 20:18:30 +01:00
// Between pairs of features in the figure are held straight
2013-04-14 19:17:55 +02:00
i : = 0 ;
While i < length( ptpairs) do
begin
_r1 : = pCvSURFPoint( cvGetSeqElem( objectKeypoints, ptpairs[ i] ) ) ;
_r2 : = pCvSURFPoint( cvGetSeqElem( imageKeypoints, ptpairs[ i + 1 ] ) ) ;
2014-02-24 20:18:30 +01:00
cvLine( correspond, cvPointFrom32f( _r1. pt) , cvPoint( cvRound( _r2. pt. x) , cvRound( _r2. pt. y + _object. height) ) , colors[ 8 ] ) ;
2013-04-14 19:17:55 +02:00
i : = i + 2 ;
end ;
2013-04-18 08:34:16 +02:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> c<EFBFBD> <63> <EFBFBD> <EFBFBD> 23.4.
2013-04-14 19:17:55 +02:00
cvShowImage( 'Object Correspond' , correspond) ;
2013-04-18 08:34:16 +02:00
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> c<EFBFBD> <63> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> c<EFBFBD> <63> <EFBFBD> <EFBFBD> (<28> <> c. 23.5)
2014-02-24 20:18:30 +01:00
// Highlight features of circles
2013-04-14 19:17:55 +02:00
for i : = 0 to objectKeypoints. total - 1 do
begin
r : = pCvSURFPoint( cvGetSeqElem( objectKeypoints, i) ) ;
center. x : = cvRound( r. pt. x) ;
center. y : = cvRound( r. pt. y) ;
radius : = cvRound( r. size * 1.2 / 9 * 2 ) ;
cvCircle( object_color, center, radius, colors[ 0 ] , 1 , 8 , 0 ) ;
end ;
cvShowImage( 'Object' , object_color) ;
cvWaitKey( 0 ) ;
cvDestroyAllWindows;
except
on E: Exception do
WriteLn( E. ClassName, ': ' , E. Message ) ;
end ;
end .