--- /dev/null
+/*M///////////////////////////////////////////////////////////////////////////////////////
+//
+// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
+//
+// By downloading, copying, installing or using the software you agree to this license.
+// If you do not agree to this license, do not download, install,
+// copy or use the software.
+//
+//
+// Intel License Agreement
+// For Open Source Computer Vision Library
+//
+// Copyright (C) 2000, Intel Corporation, all rights reserved.
+// Third party copyrights are property of their respective owners.
+//
+// Redistribution and use in source and binary forms, with or without modification,
+// are permitted provided that the following conditions are met:
+//
+// * Redistribution's of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistribution's in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * The name of Intel Corporation may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// This software is provided by the copyright holders and contributors "as is" and
+// any express or implied warranties, including, but not limited to, the implied
+// warranties of merchantability and fitness for a particular purpose are disclaimed.
+// In no event shall the Intel Corporation or contributors be liable for any direct,
+// indirect, incidental, special, exemplary, or consequential damages
+// (including, but not limited to, procurement of substitute goods or services;
+// loss of use, data, or profits; or business interruption) however caused
+// and on any theory of liability, whether in contract, strict liability,
+// or tort (including negligence or otherwise) arising in any way out of
+// the use of this software, even if advised of the possibility of such damage.
+//
+//M*/
+
+#include "_cvaux.h"
+//#include "cvtypes.h"
+//#include <float.h>
+//#include <limits.h>
+//#include "cv.h"
+//#include "highgui.h"
+
+#include <stdio.h>
+
+/* Valery Mosyagin */
+
+/* ===== Function for find corresponding between images ===== */
+
+/* Create feature points on image and return number of them. Array points fills by found points */
+int icvCreateFeaturePoints(IplImage *image, CvMat *points, CvMat *status)
+{
+ int foundFeaturePoints = 0;
+ IplImage *grayImage = 0;
+ IplImage *eigImage = 0;
+ IplImage *tmpImage = 0;
+ CvPoint2D32f *cornerPoints = 0;
+
+ CV_FUNCNAME( "icvFeatureCreatePoints" );
+ __BEGIN__;
+
+ /* Test for errors */
+ if( image == 0 || points == 0 )
+ {
+ CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
+ }
+
+ /* Test image size */
+ int w,h;
+ w = image->width;
+ h = image->height;
+
+ if( w <= 0 || h <= 0)
+ {
+ CV_ERROR( CV_StsOutOfRange, "Size of image must be > 0" );
+ }
+
+ /* Test for matrices */
+ if( !CV_IS_MAT(points) )
+ {
+ CV_ERROR( CV_StsUnsupportedFormat, "Input parameter points must be a matrix" );
+ }
+
+ int needNumPoints;
+ needNumPoints = points->cols;
+ if( needNumPoints <= 0 )
+ {
+ CV_ERROR( CV_StsOutOfRange, "Number of need points must be > 0" );
+ }
+
+ if( points->rows != 2 )
+ {
+ CV_ERROR( CV_StsOutOfRange, "Number of point coordinates must be == 2" );
+ }
+
+ if( status != 0 )
+ {
+ /* If status matrix exist test it for correct */
+ if( !CV_IS_MASK_ARR(status) )
+ {
+ CV_ERROR( CV_StsUnsupportedFormat, "Statuses must be a mask arrays" );
+ }
+
+ if( status->cols != needNumPoints )
+ {
+ CV_ERROR( CV_StsUnmatchedSizes, "Size of points and statuses must be the same" );
+ }
+
+ if( status->rows !=1 )
+ {
+ CV_ERROR( CV_StsUnsupportedFormat, "Number of rows of status must be 1" );
+ }
+ }
+
+ /* Create temporary images */
+ CV_CALL( grayImage = cvCreateImage(cvSize(w,h), 8,1) );
+ CV_CALL( eigImage = cvCreateImage(cvSize(w,h),32,1) );
+ CV_CALL( tmpImage = cvCreateImage(cvSize(w,h),32,1) );
+
+ /* Create points */
+ CV_CALL( cornerPoints = (CvPoint2D32f*)cvAlloc( sizeof(CvPoint2D32f) * needNumPoints) );
+
+ int foundNum;
+ double quality;
+ double minDist;
+
+ cvCvtColor(image,grayImage, CV_BGR2GRAY);
+
+ foundNum = needNumPoints;
+ quality = 0.01;
+ minDist = 5;
+ cvGoodFeaturesToTrack(grayImage, eigImage, tmpImage, cornerPoints, &foundNum, quality, minDist);
+
+ /* Copy found points to result */
+ int i;
+ for( i = 0; i < foundNum; i++ )
+ {
+ cvmSet(points,0,i,cornerPoints[i].x);
+ cvmSet(points,1,i,cornerPoints[i].y);
+ }
+
+ /* Set status if need */
+ if( status )
+ {
+ for( i = 0; i < foundNum; i++ )
+ {
+ status->data.ptr[i] = 1;
+ }
+
+ for( i = foundNum; i < needNumPoints; i++ )
+ {
+ status->data.ptr[i] = 0;
+ }
+ }
+
+ foundFeaturePoints = foundNum;
+
+ __END__;
+
+ /* Free allocated memory */
+ cvReleaseImage(&grayImage);
+ cvReleaseImage(&eigImage);
+ cvReleaseImage(&tmpImage);
+ cvFree(&cornerPoints);
+
+ return foundFeaturePoints;
+}
+
+/*-------------------------------------------------------------------------------------*/
+
+/* For given points1 (with pntStatus) on image1 finds corresponding points2 on image2 and set pntStatus2 for them */
+/* Returns number of corresponding points */
+int icvFindCorrForGivenPoints( IplImage *image1,/* Image 1 */
+ IplImage *image2,/* Image 2 */
+ CvMat *points1,
+ CvMat *pntStatus1,
+ CvMat *points2,
+ CvMat *pntStatus2,
+ int useFilter,/*Use fundamental matrix to filter points */
+ double threshold)/* Threshold for good points in filter */
+{
+ int resNumCorrPoints = 0;
+ CvPoint2D32f* cornerPoints1 = 0;
+ CvPoint2D32f* cornerPoints2 = 0;
+ char* status = 0;
+ float* errors = 0;
+ CvMat* tmpPoints1 = 0;
+ CvMat* tmpPoints2 = 0;
+ CvMat* pStatus = 0;
+ IplImage *grayImage1 = 0;
+ IplImage *grayImage2 = 0;
+ IplImage *pyrImage1 = 0;
+ IplImage *pyrImage2 = 0;
+
+ CV_FUNCNAME( "icvFindCorrForGivenPoints" );
+ __BEGIN__;
+
+ /* Test input data for errors */
+
+ /* Test for null pointers */
+ if( image1 == 0 || image2 == 0 ||
+ points1 == 0 || points2 == 0 ||
+ pntStatus1 == 0 || pntStatus2 == 0)
+ {
+ CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
+ }
+
+ /* Test image size */
+ int w,h;
+ w = image1->width;
+ h = image1->height;
+
+ if( w <= 0 || h <= 0)
+ {
+ CV_ERROR( CV_StsOutOfRange, "Size of image1 must be > 0" );
+ }
+
+ if( image2->width != w || image2->height != h )
+ {
+ CV_ERROR( CV_StsUnmatchedSizes, "Size of images must be the same" );
+ }
+
+ /* Test for matrices */
+ if( !CV_IS_MAT(points1) || !CV_IS_MAT(points2) ||
+ !CV_IS_MAT(pntStatus1) || !CV_IS_MAT(pntStatus2) )
+ {
+ CV_ERROR( CV_StsUnsupportedFormat, "Input parameters (points and status) must be a matrices" );
+ }
+
+ /* Test type of status matrices */
+ if( !CV_IS_MASK_ARR(pntStatus1) || !CV_IS_MASK_ARR(pntStatus2) )
+ {
+ CV_ERROR( CV_StsUnsupportedFormat, "Statuses must be a mask arrays" );
+ }
+
+ /* Test number of points */
+ int numPoints;
+ numPoints = points1->cols;
+
+ if( numPoints <= 0 )
+ {
+ CV_ERROR( CV_StsOutOfRange, "Number of points1 must be > 0" );
+ }
+
+ if( points2->cols != numPoints || pntStatus1->cols != numPoints || pntStatus2->cols != numPoints )
+ {
+ CV_ERROR( CV_StsUnmatchedSizes, "Number of points and statuses must be the same" );
+ }
+
+ if( points1->rows != 2 || points2->rows != 2 )
+ {
+ CV_ERROR( CV_StsOutOfRange, "Number of points coordinates must be 2" );
+ }
+
+ if( pntStatus1->rows != 1 || pntStatus2->rows != 1 )
+ {
+ CV_ERROR( CV_StsOutOfRange, "Status must be a matrix 1xN" );
+ }
+ /* ----- End test ----- */
+
+
+ /* Compute number of visible points on image1 */
+ int numVisPoints;
+ numVisPoints = cvCountNonZero(pntStatus1);
+
+ if( numVisPoints > 0 )
+ {
+ /* Create temporary images */
+ /* We must use iplImage againts hughgui images */
+
+/*
+ CvvImage grayImage1;
+ CvvImage grayImage2;
+ CvvImage pyrImage1;
+ CvvImage pyrImage2;
+*/
+
+ /* Create Ipl images */
+ CV_CALL( grayImage1 = cvCreateImage(cvSize(w,h),8,1) );
+ CV_CALL( grayImage2 = cvCreateImage(cvSize(w,h),8,1) );
+ CV_CALL( pyrImage1 = cvCreateImage(cvSize(w,h),8,1) );
+ CV_CALL( pyrImage2 = cvCreateImage(cvSize(w,h),8,1) );
+
+ CV_CALL( cornerPoints1 = (CvPoint2D32f*)cvAlloc( sizeof(CvPoint2D32f)*numVisPoints) );
+ CV_CALL( cornerPoints2 = (CvPoint2D32f*)cvAlloc( sizeof(CvPoint2D32f)*numVisPoints) );
+ CV_CALL( status = (char*)cvAlloc( sizeof(char)*numVisPoints) );
+ CV_CALL( errors = (float*)cvAlloc( 2 * sizeof(float)*numVisPoints) );
+
+ int i;
+ for( i = 0; i < numVisPoints; i++ )
+ {
+ status[i] = 1;
+ }
+
+ /* !!! Need test creation errors */
+ /*
+ if( !grayImage1.Create(w,h,8)) EXIT;
+ if( !grayImage2.Create(w,h,8)) EXIT;
+ if( !pyrImage1. Create(w,h,8)) EXIT;
+ if( !pyrImage2. Create(w,h,8)) EXIT;
+ */
+
+ cvCvtColor(image1,grayImage1,CV_BGR2GRAY);
+ cvCvtColor(image2,grayImage2,CV_BGR2GRAY);
+
+ /*
+ grayImage1.CopyOf(image1,0);
+ grayImage2.CopyOf(image2,0);
+ */
+
+ /* Copy points good points from input data */
+ uchar *stat1 = pntStatus1->data.ptr;
+ uchar *stat2 = pntStatus2->data.ptr;
+
+ int curr = 0;
+ for( i = 0; i < numPoints; i++ )
+ {
+ if( stat1[i] )
+ {
+ cornerPoints1[curr].x = (float)cvmGet(points1,0,i);
+ cornerPoints1[curr].y = (float)cvmGet(points1,1,i);
+ curr++;
+ }
+ }
+
+ /* Define number of levels of pyramid */
+ cvCalcOpticalFlowPyrLK( grayImage1, grayImage2,
+ pyrImage1, pyrImage2,
+ cornerPoints1, cornerPoints2,
+ numVisPoints, cvSize(10,10), 3,
+ status, errors,
+ cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03),
+ 0/*CV_LKFLOW_PYR_A_READY*/ );
+
+
+ memset(stat2,0,sizeof(uchar)*numPoints);
+
+ int currVis = 0;
+ int totalCorns = 0;
+
+ /* Copy new points and set status */
+ /* stat1 may not be the same as stat2 */
+ for( i = 0; i < numPoints; i++ )
+ {
+ if( stat1[i] )
+ {
+ if( status[currVis] && errors[currVis] < 1000 )
+ {
+ stat2[i] = 1;
+ cvmSet(points2,0,i,cornerPoints2[currVis].x);
+ cvmSet(points2,1,i,cornerPoints2[currVis].y);
+ totalCorns++;
+ }
+ currVis++;
+ }
+ }
+
+ resNumCorrPoints = totalCorns;
+
+ /* Filter points using RANSAC */
+ if( useFilter )
+ {
+ resNumCorrPoints = 0;
+ /* Use RANSAC filter for found points */
+ if( totalCorns > 7 )
+ {
+ /* Create array with good points only */
+ CV_CALL( tmpPoints1 = cvCreateMat(2,totalCorns,CV_64F) );
+ CV_CALL( tmpPoints2 = cvCreateMat(2,totalCorns,CV_64F) );
+
+ /* Copy just good points */
+ int currPoint = 0;
+ for( i = 0; i < numPoints; i++ )
+ {
+ if( stat2[i] )
+ {
+ cvmSet(tmpPoints1,0,currPoint,cvmGet(points1,0,i));
+ cvmSet(tmpPoints1,1,currPoint,cvmGet(points1,1,i));
+
+ cvmSet(tmpPoints2,0,currPoint,cvmGet(points2,0,i));
+ cvmSet(tmpPoints2,1,currPoint,cvmGet(points2,1,i));
+
+ currPoint++;
+ }
+ }
+
+ /* Compute fundamental matrix */
+ CvMat fundMatr;
+ double fundMatr_dat[9];
+ fundMatr = cvMat(3,3,CV_64F,fundMatr_dat);
+
+ CV_CALL( pStatus = cvCreateMat(1,totalCorns,CV_32F) );
+
+ int num = cvFindFundamentalMat(tmpPoints1,tmpPoints2,&fundMatr,CV_FM_RANSAC,threshold,0.99,pStatus);
+ if( num > 0 )
+ {
+ int curr = 0;
+ /* Set final status for points2 */
+ for( i = 0; i < numPoints; i++ )
+ {
+ if( stat2[i] )
+ {
+ if( cvmGet(pStatus,0,curr) == 0 )
+ {
+ stat2[i] = 0;
+ }
+ curr++;
+ }
+ }
+ resNumCorrPoints = curr;
+ }
+ }
+ }
+ }
+
+ __END__;
+
+ /* Free allocated memory */
+ cvFree(&cornerPoints1);
+ cvFree(&cornerPoints2);
+ cvFree(&status);
+ cvFree(&errors);
+ cvFree(&tmpPoints1);
+ cvFree(&tmpPoints2);
+ cvReleaseMat( &pStatus );
+ cvReleaseImage( &grayImage1 );
+ cvReleaseImage( &grayImage2 );
+ cvReleaseImage( &pyrImage1 );
+ cvReleaseImage( &pyrImage2 );
+
+ return resNumCorrPoints;
+}
+/*-------------------------------------------------------------------------------------*/
+int icvGrowPointsAndStatus(CvMat **oldPoints,CvMat **oldStatus,CvMat *addPoints,CvMat *addStatus,int addCreateNum)
+{
+ /* Add to existing points and status arrays new points or just grow */
+ CvMat *newOldPoint = 0;
+ CvMat *newOldStatus = 0;
+ int newTotalNumber = 0;
+
+ CV_FUNCNAME( "icvGrowPointsAndStatus" );
+ __BEGIN__;
+
+ /* Test for errors */
+ if( oldPoints == 0 || oldStatus == 0 )
+ {
+ CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
+ }
+
+ if( *oldPoints == 0 || *oldStatus == 0 )
+ {
+ CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
+ }
+
+ if( !CV_IS_MAT(*oldPoints))
+ {
+ CV_ERROR( CV_StsUnsupportedFormat, "oldPoints must be a pointer to a matrix" );
+ }
+
+ if( !CV_IS_MASK_ARR(*oldStatus))
+ {
+ CV_ERROR( CV_StsUnsupportedFormat, "oldStatus must be a pointer to a mask array" );
+ }
+
+ int oldNum;
+ oldNum = (*oldPoints)->cols;
+ if( oldNum < 1 )
+ {
+ CV_ERROR( CV_StsOutOfRange, "Number of old points must be > 0" );
+ }
+
+ /* Define if need number of add points */
+ int addNum;
+ addNum = 0;
+ if( addPoints != 0 && addStatus != 0 )
+ {/* We have aditional points */
+ if( CV_IS_MAT(addPoints) && CV_IS_MASK_ARR(addStatus) )
+ {
+ addNum = addPoints->cols;
+ if( addStatus->cols != addNum )
+ {
+ CV_ERROR( CV_StsOutOfRange, "Number of add points and statuses must be the same" );
+ }
+ }
+ }
+
+ /* */
+
+ int numCoord;
+ numCoord = (*oldPoints)->rows;
+ newTotalNumber = oldNum + addNum + addCreateNum;
+
+ if( newTotalNumber )
+ {
+ /* Free allocated memory */
+ newOldPoint = cvCreateMat(numCoord,newTotalNumber,CV_64F);
+ newOldStatus = cvCreateMat(1,newTotalNumber,CV_8S);
+
+ /* Copy old values to */
+ int i;
+
+ /* Clear all values */
+ cvZero(newOldPoint);
+ cvZero(newOldStatus);
+
+ for( i = 0; i < oldNum; i++ )
+ {
+ int currCoord;
+ for( currCoord = 0; currCoord < numCoord; currCoord++ )
+ {
+ cvmSet(newOldPoint,currCoord,i,cvmGet(*oldPoints,currCoord,i));
+ }
+ newOldStatus->data.ptr[i] = (*oldStatus)->data.ptr[i];
+ }
+
+ /* Copy additional points and statuses */
+ if( addNum )
+ {
+ for( i = 0; i < addNum; i++ )
+ {
+ int currCoord;
+ for( currCoord = 0; currCoord < numCoord; currCoord++ )
+ {
+ cvmSet(newOldPoint,currCoord,i+oldNum,cvmGet(addPoints,currCoord,i));
+ }
+ newOldStatus->data.ptr[i+oldNum] = addStatus->data.ptr[i];
+ //cvmSet(newOldStatus,0,i,cvmGet(addStatus,0,i));
+ }
+ }
+
+ /* Delete previous data */
+ cvReleaseMat(oldPoints);
+ cvReleaseMat(oldStatus);
+
+ /* copy pointers */
+ *oldPoints = newOldPoint;
+ *oldStatus = newOldStatus;
+
+ }
+ __END__;
+
+ return newTotalNumber;
+}
+/*-------------------------------------------------------------------------------------*/
+int icvRemoveDoublePoins( CvMat *oldPoints,/* Points on prev image */
+ CvMat *newPoints,/* New points */
+ CvMat *oldStatus,/* Status for old points */
+ CvMat *newStatus,
+ CvMat *origStatus,
+ float threshold)/* Status for new points */
+{
+
+ CvMemStorage* storage = 0;
+ CvSubdiv2D* subdiv = 0;
+ CvSeq* seq = 0;
+
+ int originalPoints = 0;
+
+ CV_FUNCNAME( "icvRemoveDoublePoins" );
+ __BEGIN__;
+
+ /* Test input data */
+ if( oldPoints == 0 || newPoints == 0 ||
+ oldStatus == 0 || newStatus == 0 || origStatus == 0 )
+ {
+ CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
+ }
+
+ if( !CV_IS_MAT(oldPoints) || !CV_IS_MAT(newPoints) )
+ {
+ CV_ERROR( CV_StsUnsupportedFormat, "Input parameters points must be a matrices" );
+ }
+
+ if( !CV_IS_MASK_ARR(oldStatus) || !CV_IS_MASK_ARR(newStatus) || !CV_IS_MASK_ARR(origStatus) )
+ {
+ CV_ERROR( CV_StsUnsupportedFormat, "Input parameters statuses must be a mask array" );
+ }
+
+ int oldNumPoints;
+ oldNumPoints = oldPoints->cols;
+ if( oldNumPoints < 0 )
+ {
+ CV_ERROR( CV_StsOutOfRange, "Number of oldPoints must be >= 0" );
+ }
+
+ if( oldStatus->cols != oldNumPoints )
+ {
+ CV_ERROR( CV_StsUnmatchedSizes, "Number of old Points and old Statuses must be the same" );
+ }
+
+ int newNumPoints;
+ newNumPoints = newPoints->cols;
+ if( newNumPoints < 0 )
+ {
+ CV_ERROR( CV_StsOutOfRange, "Number of newPoints must be >= 0" );
+ }
+
+ if( newStatus->cols != newNumPoints )
+ {
+ CV_ERROR( CV_StsUnmatchedSizes, "Number of new Points and new Statuses must be the same" );
+ }
+
+ if( origStatus->cols != newNumPoints )
+ {
+ CV_ERROR( CV_StsUnmatchedSizes, "Number of new Points and new original Status must be the same" );
+ }
+
+ if( oldPoints->rows != 2)
+ {
+ CV_ERROR( CV_StsOutOfRange, "OldPoints must have 2 coordinates >= 0" );
+ }
+
+ if( newPoints->rows != 2)
+ {
+ CV_ERROR( CV_StsOutOfRange, "NewPoints must have 2 coordinates >= 0" );
+ }
+
+ if( oldStatus->rows != 1 || newStatus->rows != 1 || origStatus->rows != 1 )
+ {
+ CV_ERROR( CV_StsOutOfRange, "Statuses must have 1 row" );
+ }
+
+ /* we have points on image and wants add new points */
+ /* use subdivision for find nearest points */
+
+ /* Define maximum and minimum X and Y */
+ float minX,minY;
+ float maxX,maxY;
+
+ minX = minY = FLT_MAX;
+ maxX = maxY = FLT_MIN;
+
+ int i;
+
+ for( i = 0; i < oldNumPoints; i++ )
+ {
+ if( oldStatus->data.ptr[i] )
+ {
+ float x = (float)cvmGet(oldPoints,0,i);
+ float y = (float)cvmGet(oldPoints,1,i);
+
+ if( x < minX )
+ minX = x;
+
+ if( x > maxX )
+ maxX = x;
+
+ if( y < minY )
+ minY = y;
+
+ if( y > maxY )
+ maxY = y;
+ }
+ }
+
+ for( i = 0; i < newNumPoints; i++ )
+ {
+ if( newStatus->data.ptr[i] )
+ {
+ float x = (float)cvmGet(newPoints,0,i);
+ float y = (float)cvmGet(newPoints,1,i);
+
+ if( x < minX )
+ minX = x;
+
+ if( x > maxX )
+ maxX = x;
+
+ if( y < minY )
+ minY = y;
+
+ if( y > maxY )
+ maxY = y;
+ }
+ }
+
+
+ /* Creare subdivision for old image */
+ storage = cvCreateMemStorage(0);
+// subdiv = cvCreateSubdivDelaunay2D( cvRect( 0, 0, size.width, size.height ), storage );
+ subdiv = cvCreateSubdivDelaunay2D( cvRect( cvRound(minX)-5, cvRound(minY)-5, cvRound(maxX-minX)+10, cvRound(maxY-minY)+10 ), storage );
+ seq = cvCreateSeq( 0, sizeof(*seq), sizeof(CvPoint2D32f), storage );
+
+ /* Insert each point from first image */
+ for( i = 0; i < oldNumPoints; i++ )
+ {
+ /* Add just exist points */
+ if( oldStatus->data.ptr[i] )
+ {
+ CvPoint2D32f pt;
+ pt.x = (float)cvmGet(oldPoints,0,i);
+ pt.y = (float)cvmGet(oldPoints,1,i);
+
+ CvSubdiv2DPoint* point;
+ point = cvSubdivDelaunay2DInsert( subdiv, pt );
+ }
+ }
+
+
+ /* Find nearest points */
+ /* for each new point */
+ int flag;
+ for( i = 0; i < newNumPoints; i++ )
+ {
+ flag = 0;
+ /* Test just exist points */
+ if( newStatus->data.ptr[i] )
+ {
+ flag = 1;
+ /* Let this is a good point */
+ //originalPoints++;
+
+ CvPoint2D32f pt;
+
+ pt.x = (float)cvmGet(newPoints,0,i);
+ pt.y = (float)cvmGet(newPoints,1,i);
+
+ CvSubdiv2DPoint* point = cvFindNearestPoint2D( subdiv, pt );
+
+ if( point )
+ {
+ /* Test distance of found nearest point */
+ double minDistance = icvSqDist2D32f( pt, point->pt );
+
+ if( minDistance < threshold*threshold )
+ {
+ /* Point is double. Turn it off */
+ /* Set status */
+ //newStatus->data.ptr[i] = 0;
+
+ /* No this is a double point */
+ //originalPoints--;
+ flag = 0;
+ }
+ }
+ }
+ originalPoints += flag;
+ origStatus->data .ptr[i] = (uchar)flag;
+ }
+
+ __END__;
+
+ cvReleaseMemStorage( &storage );
+
+
+ return originalPoints;
+
+
+}
+
+void icvComputeProjectMatrix(CvMat* objPoints,CvMat* projPoints,CvMat* projMatr);
+
+/*-------------------------------------------------------------------------------------*/
+void icvComputeProjectMatrixStatus(CvMat *objPoints4D,CvMat *points2,CvMat *status, CvMat *projMatr)
+{
+ /* Compute number of good points */
+ int num = cvCountNonZero(status);
+
+ /* Create arrays */
+ CvMat *objPoints = 0;
+ objPoints = cvCreateMat(4,num,CV_64F);
+
+ CvMat *points2D = 0;
+ points2D = cvCreateMat(2,num,CV_64F);
+
+ int currVis = 0;
+ int i;
+#if 1
+ FILE *file;
+ file = fopen("d:\\test\\projStatus.txt","w");
+#endif
+ int totalNum = objPoints4D->cols;
+ for( i = 0; i < totalNum; i++ )
+ {
+ fprintf(file,"%d (%d) ",i,status->data.ptr[i]);
+ if( status->data.ptr[i] )
+ {
+
+#if 1
+ double X,Y,Z,W;
+ double x,y;
+ X = cvmGet(objPoints4D,0,i);
+ Y = cvmGet(objPoints4D,1,i);
+ Z = cvmGet(objPoints4D,2,i);
+ W = cvmGet(objPoints4D,3,i);
+
+ x = cvmGet(points2,0,i);
+ y = cvmGet(points2,1,i);
+ fprintf(file,"%d (%lf %lf %lf %lf) - (%lf %lf)",i,X,Y,Z,W,x,y );
+#endif
+ cvmSet(objPoints,0,currVis,cvmGet(objPoints4D,0,i));
+ cvmSet(objPoints,1,currVis,cvmGet(objPoints4D,1,i));
+ cvmSet(objPoints,2,currVis,cvmGet(objPoints4D,2,i));
+ cvmSet(objPoints,3,currVis,cvmGet(objPoints4D,3,i));
+
+ cvmSet(points2D,0,currVis,cvmGet(points2,0,i));
+ cvmSet(points2D,1,currVis,cvmGet(points2,1,i));
+
+ currVis++;
+ }
+
+ fprintf(file,"\n");
+ }
+
+#if 1
+ fclose(file);
+#endif
+
+ icvComputeProjectMatrix(objPoints,points2D,projMatr);
+
+ /* Free allocated memory */
+ cvReleaseMat(&objPoints);
+ cvReleaseMat(&points2D);
+}
+
+
+
+/*-------------------------------------------------------------------------------------*/
+/* For given N images
+ we have corresponding points on N images
+ computed projection matrices
+ reconstructed 4D points
+
+ we must to compute
+
+
+*/
+
+void icvAddNewImageToPrevious____(
+ IplImage *newImage,//Image to add
+ IplImage *oldImage,//Previous image
+ CvMat *oldPoints,// previous 2D points on prev image (some points may be not visible)
+ CvMat *oldPntStatus,//Status for each point on prev image
+ CvMat *objPoints4D,//prev 4D points
+ CvMat *newPoints, //Points on new image corr for prev
+ CvMat *newPntStatus,// New point status for new image
+ CvMat *newFPoints2D1,//new feature points on prev image
+ CvMat *newFPoints2D2,//new feature points on new image
+ CvMat *newFPointsStatus,
+ CvMat *newProjMatr,
+ int useFilter,
+ double threshold)//New projection matrix
+{
+ CvMat *points2 = 0;
+ CvMat *status = 0;
+ CvMat *newFPointsStatusTmp = 0;
+
+ //CV_FUNCNAME( "icvAddNewImageToPrevious____" );
+ __BEGIN__;
+
+ /* First found correspondence points for images */
+
+ /* Test input params */
+
+ int numPoints;
+ numPoints = oldPoints->cols;
+
+ /* Allocate memory */
+
+ points2 = cvCreateMat(2,numPoints,CV_64F);
+ status = cvCreateMat(1,numPoints,CV_8S);
+ newFPointsStatusTmp = cvCreateMat(1, newFPoints2D1->cols,CV_8S);
+
+ int corrNum;
+ corrNum = icvFindCorrForGivenPoints( oldImage,/* Image 1 */
+ newImage,/* Image 2 */
+ oldPoints,
+ oldPntStatus,
+ points2,
+ status,
+ useFilter,/*Use fundamental matrix to filter points */
+ threshold);/* Threshold for good points in filter */
+
+ cvCopy(status,newPntStatus);
+ cvCopy(points2,newPoints);
+
+ CvMat projMatr;
+ double projMatr_dat[12];
+ projMatr = cvMat(3,4,CV_64F,projMatr_dat);
+
+ if( corrNum >= 6 )
+ {/* We can compute projection matrix */
+// icvComputeProjectMatrix(objPoints4D,points2,&projMatr);
+ icvComputeProjectMatrixStatus(objPoints4D,points2,status,&projMatr);
+ cvCopy(&projMatr,newProjMatr);
+
+ /* Create new points and find correspondence */
+ icvCreateFeaturePoints(newImage, newFPoints2D2,newFPointsStatus);
+
+ /* Good if we test new points before find corr points */
+
+ /* Find correspondence for new found points */
+ icvFindCorrForGivenPoints( newImage,/* Image 1 */
+ oldImage,/* Image 2 */
+ newFPoints2D2,
+ newFPointsStatus,//prev status
+ newFPoints2D1,
+ newFPointsStatusTmp,//new status
+ useFilter,/*Use fundamental matrix to filter points */
+ threshold);/* Threshold for good points in filter */
+
+ /* We generated new points on image test for exist points */
+
+ /* Remove all new double points */
+
+ int origNum;
+ /* Find point of old image */
+ origNum = icvRemoveDoublePoins( oldPoints,/* Points on prev image */
+ newFPoints2D1,/* New points */
+ oldPntStatus,/* Status for old points */
+ newFPointsStatusTmp,
+ newFPointsStatusTmp,//orig status
+ 20);/* Status for new points */
+
+ /* Find double points on new image */
+ origNum = icvRemoveDoublePoins( newPoints,/* Points on prev image */
+ newFPoints2D2,/* New points */
+ newPntStatus,/* Status for old points */
+ newFPointsStatusTmp,
+ newFPointsStatusTmp,//orig status
+ 20);/* Status for new points */
+
+
+
+ /* Add all new good points to result */
+
+
+ /* Copy new status to old */
+ cvCopy(newFPointsStatusTmp,newFPointsStatus);
+
+
+ }
+
+
+
+ __END__;
+
+ /* Free allocated memory */
+
+ return;
+}
+/*-------------------------------------------------------------------------------------*/
+//int icvDelete//
+//CreateGood
+
+/*-------------------------------------------------------------------------------------*/
+int icvDeleteSparsInPoints( int numImages,
+ CvMat **points,
+ CvMat **status,
+ CvMat *wasStatus)/* status of previous configuration */
+{
+ /* Delete points which no exist on any of images */
+ /* numImages - number of images */
+ /* points - arrays of points for each image. Changing */
+ /* status - arrays of status for each image. Changing */
+ /* Function returns number of common points */
+
+ int comNumber = 0;
+ CV_FUNCNAME( "icvDeleteSparsInPoints" );
+ __BEGIN__;
+
+ /* Test for errors */
+ if( numImages < 1 )
+ {
+ CV_ERROR( CV_StsOutOfRange, "Number of images must be more than 0" );
+ }
+
+ if( points == 0 || status == 0 )
+ {
+ CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
+ }
+ int numPoints;
+
+ numPoints = points[0]->cols;
+ ////////// TESTS //////////
+
+ int numCoord;
+ numCoord = points[0]->rows;// !!! may be number of coordinates is not correct !!!
+
+ int i;
+ int currExistPoint;
+ currExistPoint = 0;
+
+ if( wasStatus )
+ {
+ cvZero(wasStatus);
+ }
+
+ int currImage;
+ for( i = 0; i < numPoints; i++ )
+ {
+ int flag = 0;
+ for( currImage = 0; currImage < numImages; currImage++ )
+ {
+ flag |= status[currImage]->data.ptr[i];
+ }
+
+ if( flag )
+ {
+ /* Current point exists */
+ /* Copy points and status */
+ if( currExistPoint != i )/* Copy just if different */
+ {
+ for( currImage = 0; currImage < numImages; currImage++ )
+ {
+ /* Copy points */
+ for( int currCoord = 0; currCoord < numCoord; currCoord++ )
+ {
+ cvmSet(points[currImage],currCoord,currExistPoint, cvmGet(points[currImage],currCoord,i) );
+ }
+
+ /* Copy status */
+ status[currImage]->data.ptr[currExistPoint] = status[currImage]->data.ptr[i];
+ }
+ }
+ if( wasStatus )
+ {
+ wasStatus->data.ptr[i] = 1;
+ }
+
+ currExistPoint++;
+
+ }
+ }
+
+ /* Rest of final status of points must be set to 0 */
+ for( i = currExistPoint; i < numPoints; i++ )
+ {
+ for( currImage = 0; currImage < numImages; currImage++ )
+ {
+ status[currImage]->data.ptr[i] = 0;
+ }
+ }
+
+ comNumber = currExistPoint;
+
+ __END__;
+ return comNumber;
+}
+
+#if 0
+/*-------------------------------------------------------------------------------------*/
+void icvGrowPointsArray(CvMat **points)
+{
+
+
+}
+
+/*-------------------------------------------------------------------------------------*/
+void icvAddNewArrayPoints()
+{
+
+}
+
+/*-------------------------------------------------------------------------------------*/
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////
+
+/* Add image to existing images and corr points */
+#if 0
+/* Returns: 1 if new image was added good */
+/* 0 image was not added. Not enought corr points */
+int AddImageToStruct( IplImage *newImage,//Image to add
+ IplImage *oldImage,//Previous image
+ CvMat *oldPoints,// previous 2D points on prev image (some points may be not visible)
+ CvMat *oldPntStatus,//Status for each point on prev image
+ CvMat *objPoints4D,//prev 4D points
+ CvMat *newPntStatus,// New point status for new image
+ CvMat *newPoints,//New corresponding points on new image
+ CvMat *newPoints2D1,//new points on prev image
+ CvMat *newPoints2D2,//new points on new image
+ CvMat *newProjMatr);//New projection matrix
+{
+
+ /* Add new image. Create new corr points */
+ /* Track exist points from oldImage to newImage */
+ /* Create new vector status */
+ CvMat *status;
+ int numPoints = oldPoints->cols;
+ status = cvCreateMat(1,numPoints,CV_64F);
+ /* Copy status */
+ cvConvert(pntStatus,status);
+
+ int corrNum = FindCorrForGivenPoints(oldImage,newImage,oldPoints,newPoints,status);
+
+ /* Status has new status of points */
+
+ CvMat projMatr;
+ double projMatr_dat[12];
+ projMatr = cvMat(3,4,CV_64F,projMatr_dat);
+
+ /* If number of corr points is 6 or more can compute projection matrix */
+ if( corrNum >= 6)
+ {
+ /* Compute projection matrix for new image using corresponding points */
+ icvComputeProjectMatrix(objPoints4D,newPoints,&projMatr);
+
+ CvMat *tmpPoints;
+ /* Create new points and find correspondence */
+ int num = FindFeaturePoints(newImage, &tmpPoints);
+ if( num > 0 )
+ {
+ CvMat *newPoints;
+ newPoints = cvCreateMat(2,num,CV_64F);
+ CvMat *status;
+ status = cvCreateMat(1,num,CV_64F);
+ /* Set status for all points */
+ int i;
+ for( i = 0; i < num; i++ )
+ {
+ cvmSet(status,0,i,1.0);
+ }
+
+ int corrNum2 = FindCorrForGivenPoints(oldImage,newImage,tmpPoints,newPoints,status);
+
+ /* !!! Filter points using projection matrices or not ??? */
+
+ /* !!! Need to filter nearest points */
+
+ /* Add new found points to exist points and optimize again */
+ CvMat *new2DPoints;
+ CvMat *newStatus;
+
+ /* add new status to old status */
+
+
+
+
+
+ }
+ else
+ {
+ /* No new points were found */
+ }
+ }
+ else
+ {
+ /* We can't compute projection matrix for new image */
+ return 0;
+ }
+
+}
+#endif