cvfundam.cpp.svn-base

来自「非结构化路识别」· SVN-BASE 代码 · 共 2,143 行 · 第 1/5 页

SVN-BASE
2,143
字号
                            cvGetCol(corrLines2,&lin2,i);
                            double dist1,dist2;
                            dist1 = fabs(cvDotProduct(&pnt1,&lin1));
                            dist2 = fabs(cvDotProduct(&pnt2,&lin2));
                            flags[i] = ( dist1 < threshold && dist2 < threshold )?1:0;
                            numGoodPoints += flags[i];
                        }
                    }
                }

                if( numGoodPoints > maxGoodPoints )
                {/* good matrix */
                    cvCopy(&fund7,&bestFund);
                    maxGoodPoints = numGoodPoints;
                    /* copy best flags */
                    int i;
                    for(i=0;i<numPoint;i++)
                    {
                        bestFlags[i] = flags[i];
                    }

                    /* Recompute new number of need steps */

			        /* Adaptive number of samples to count*/
			        double ep = 1 - (double)numGoodPoints / (double)numPoint;
                    if( ep == 1 )
                    {
                        ep = 0.5;//if there is not good points set ration of outliers to 50%
                    }
            
			        double newNumSamples = log(1-p) / log(1-pow(1-ep,7));

                    if( newNumSamples < (double)NumSamples )
                    {
                        NumSamples = cvRound(newNumSamples);
                    }

                }
            }
            
            wasCount++;
        }

        /* we have best 7-point fundamental matrix. */
        /* and best points */
        /* use these points to improve matrix */

        /* collect best points */
        /* copy points */
        
        /* Test number of points. And if number >=8 improove found fundamental matrix  */

        if( maxGoodPoints < 7 )
        {
            /* Fundamental matrix not found */
            numFundMatr = 0;
        }
        else
        {
            if( maxGoodPoints > 7 )
            {
                /* Found >= 8 point. Improove matrix */
                int i;
                int currPnt;
                currPnt = 0;

                for( i = 0; i < numPoint; i++ )
                {
                    if( bestFlags[i] )
                    {
                        CvMat wPnt;
                        CvMat bestPnt;
                        cvGetCol( wpoints1,&wPnt, i );
                        cvGetCol( bestPoints1,&bestPnt, currPnt );
                        cvCopy(&wPnt,&bestPnt);
                        cvGetCol( wpoints2,&wPnt, i );
                        cvGetCol( bestPoints2,&bestPnt, currPnt );
                        cvCopy(&wPnt,&bestPnt);
                        currPnt++;
                    }
                }

                CvMat wbestPnts1;
                CvMat wbestPnts2;

                cvGetSubArr( bestPoints1, &wbestPnts1, cvRect(0,0,maxGoodPoints,3) );
                cvGetSubArr( bestPoints2, &wbestPnts2, cvRect(0,0,maxGoodPoints,3) );

                /* best points was collectet. Improve fundamental matrix */
                /* Just use 8-point algorithm */
                double impFundMatr_dat[9];
                CvMat impFundMatr;
                impFundMatr = cvMat(3,3,CV_64F,impFundMatr_dat);
                numFundMatr = icvComputeFundamental8Point(&wbestPnts1,&wbestPnts2,&impFundMatr);

                cvConvert(&impFundMatr,fundMatr);        
                //cvConvert(&bestFund,fundMatr); // This line must be deleted
            }
            else
            {
                /* 7 point. Just copy to result */
                cvConvert(&bestFund,fundMatr);
                numFundMatr = 1;
            }

            /* copy flag to status if need */
            if( status )
            {
                for( int i = 0; i < numPoint; i++)
                {
                    cvmSet(status,0,i,(double)bestFlags[i]);
                }
            }
        }


    }

    __END__;

    /* free allocated memory */
    
    cvReleaseMat(&corrLines1);
    cvReleaseMat(&corrLines2);
    cvReleaseMat(&wpoints1);
    cvReleaseMat(&wpoints2);
    cvReleaseMat(&bestPoints1);
    cvReleaseMat(&bestPoints2);
    cvFree((void**)&flags);
    cvFree((void**)&bestFlags);

    return numFundMatr;
}//icvComputeFundamentalRANSAC

/*=====================================================================================*/

void icvCompPointLineDists(CvMat* points,CvMat* lines,CvMat* distances)
{/* Line must be normalized */
    
    int numPoints;
    numPoints = points->cols;
    if( numPoints != lines->cols && numPoints != distances->cols )
    {
        //printf("Size if arrays not equals\n");
        return;//error
    }

    int i;
    for( i = 0; i < numPoints; i++ )
    {
        CvMat pnt;
        CvMat lin;
        cvGetCol(points,&pnt,i);
        cvGetCol(lines,&lin,i);
        double dist;
        dist = fabs(cvDotProduct(&pnt,&lin));
        cvmSet(distances,0,i,dist);
    }

    return;
}

/*=====================================================================================*/



#define _compVals( v1, v2 )  ((v1) < (v2))

/* Create function to sort vector */
CV_IMPLEMENT_QSORT( _SortCvMatVect, double, _compVals )

/*=====================================================================================*/
int icvComputeFundamentalLMedS(    CvMat* points1,CvMat* points2,
                                    CvMat* fundMatr,
                                    double threshold,/* Threshold for good points */
									double p,/* Probability of good result. */
                                    CvMat* status)    
{
    CvMat* wpoints1 = 0;
    CvMat* wpoints2 = 0;
    CvMat* corrLines1 = 0;
    CvMat* corrLines2 = 0;
    CvMat* bestPoints1 = 0;
    CvMat* bestPoints2 = 0;
    CvMat* dists1 = 0;
    CvMat* dists2 = 0;
    CvMat* distsSq1 = 0;
    CvMat* distsSq2 = 0;
    CvMat* allDists = 0;

    int* flags = 0;
    int* bestFlags = 0;
    int numFundMatr = 0;
    
    CV_FUNCNAME( "icvComputeFundamentalLMedS" );
    __BEGIN__;

    /* Test correct of input data */

    if( !CV_IS_MAT(points1) || !CV_IS_MAT(points2)|| !CV_IS_MAT(fundMatr))
    {
        CV_ERROR(CV_StsBadPoint,"Not a matrixes");
    }

    int numPoint;
    numPoint = points1->cols;
    
    int type;
    type = points1->type;
    
    if( numPoint != points2->cols )
    {
        CV_ERROR( CV_StsBadSize, "Number of points not equal" );
    }
    if( numPoint < 8 )
    {
        CV_ERROR( CV_StsBadSize, "Number of points must be >= 8" );
    }

    if( points1->rows != 2 && points1->rows != 3 )
    {
        CV_ERROR( CV_StsBadSize, "Number of coordinates of points1 must be 2 or 3" );
    }

    if( points2->rows != 2 && points2->rows != 3 )
    {
        CV_ERROR( CV_StsBadSize, "Number of coordinates of points2 must be 2 or 3" );
    }

    if( fundMatr->rows != 3 || fundMatr->cols != 3 )
    {
        CV_ERROR( CV_StsBadSize, "Size of fundMatr must be 3x3" );
    }

    if( status )
    {/* status is present test it */
        if( !CV_IS_MAT(status) )
        {
            CV_ERROR(CV_StsBadPoint,"status is not a matrix");
        }

        if( status->cols != numPoint || status->rows != 1 )
        {
            CV_ERROR(CV_StsBadPoint,"Size of status must be 1xN");
        }
    }
       
    /* We will choose adaptive number of N (samples) */

    /* Convert points to 64F working points */

    CV_CALL( flags = (int*)cvAlloc(numPoint * sizeof(int)) );
    CV_CALL( bestFlags = (int*)cvAlloc(numPoint * sizeof(int)) );
    CV_CALL( wpoints1 = cvCreateMat(3,numPoint,CV_64F) );
    CV_CALL( wpoints2 = cvCreateMat(3,numPoint,CV_64F) );
    CV_CALL( corrLines1 = cvCreateMat(3,numPoint,CV_64F));
    CV_CALL( corrLines2 = cvCreateMat(3,numPoint,CV_64F));
    CV_CALL( bestPoints1 = cvCreateMat(3,numPoint,CV_64F));
    CV_CALL( bestPoints2 = cvCreateMat(3,numPoint,CV_64F));
    CV_CALL( dists1 = cvCreateMat(1,numPoint,CV_64F));
    CV_CALL( dists2 = cvCreateMat(1,numPoint,CV_64F));
    CV_CALL( distsSq1 = cvCreateMat(1,numPoint,CV_64F));
    CV_CALL( distsSq2 = cvCreateMat(1,numPoint,CV_64F));
    CV_CALL( allDists = cvCreateMat(1,numPoint,CV_64F));

    icvMake3DPoints(points1,wpoints1);
    icvMake3DPoints(points2,wpoints2);
    
    {
        int NumSamples = 500;//Maximux number of steps
        int wasCount = 0;  //count of choosing samples

		double goodMean = FLT_MAX;
		double currMean;

        int numGoodPoints = 0;

        double bestFund_dat[9];
        CvMat  bestFund;
        bestFund = cvMat(3,3,CV_64F,bestFund_dat);

        /* choosen points */        
        while( wasCount < NumSamples )
        {
            /* select samples */
            int randNumbs[7];
            int i;
            int newnum;
            int pres;
            for( i = 0; i < 7; i++ )
            {
                do
                {
                    newnum = rand()%numPoint;

                    /* test this number */
                    pres = 0;
                    int test;
                    for( test = 0; test < i; test++ )
                    {
                        if( randNumbs[test] == newnum )
                        {
                            pres = 1;
                            break;
                        }
                    }
                }
                while( pres );
                randNumbs[i] = newnum;
            }
            /* random numbers of points was generated */
            /* select points */

            double selPoints1_dat[2*7];
            double selPoints2_dat[2*7];
            CvMat selPoints1;
            CvMat selPoints2;
            selPoints1 = cvMat(2,7,CV_64F,selPoints1_dat);
            selPoints2 = cvMat(2,7,CV_64F,selPoints2_dat);
            /* copy points */
            int t;
            for( t = 0; t < 7; t++ )
            {
                double x,y;
                x = cvmGet(wpoints1,0,randNumbs[t]);
                y = cvmGet(wpoints1,1,randNumbs[t]);
                cvmSet(&selPoints1,0,t,x);
                cvmSet(&selPoints1,1,t,y);
                
                x = cvmGet(wpoints2,0,randNumbs[t]);
                y = cvmGet(wpoints2,1,randNumbs[t]);
                cvmSet(&selPoints2,0,t,x);
                cvmSet(&selPoints2,1,t,y);
            }
            /* Compute fundamental matrix using 7-points algorithm */

            double fundTriple_dat[27];
            CvMat fundTriple;
            fundTriple = cvMat(9,3,CV_64F,fundTriple_dat);

            int numFund = icvComputeFundamental7Point(&selPoints1,&selPoints2,&fundTriple);

            //double fund7_dat[9];
            CvMat fund7;
            //fund7 = cvMat(3,3,CV_64F,fund7_dat);

            /* get sub matrix */
            for( int currFund = 0; currFund < numFund; currFund++ )
            {

                cvGetSubArr(&fundTriple,&fund7,cvRect(0,currFund*3,3,3));
                {
				    /* Compute median error for this matrix */
				    {
                        icvComputeCorrespondEpilines(wpoints1,2,&fund7,corrLines2);
                        icvComputeCorrespondEpilines(wpoints2,1,&fund7,corrLines1);

					    icvCompPointLineDists(wpoints1,corrLines1,dists1);
					    icvCompPointLineDists(wpoints2,corrLines2,dists2);

					    /* add distances for points (d1*d1+d2*d2) */
					    cvMul(dists1,dists1,distsSq1);
					    cvMul(dists2,dists2,distsSq2);

					    cvAdd(distsSq1,distsSq2,allDists);

					    /* sort distances */
					    _SortCvMatVect(allDists->data.db,numPoint,0);

					    /* get median error */
					    currMean = allDists->data.db[numPoint/2];
				    }
                }

                if( currMean < goodMean )
                {/* good matrix */
                    cvCopy(&fund7,&bestFund);
                    goodMean = currMean;

                    /* Compute number of good points using threshold */
                    int i;
                    numGoodPoints = 0;
                    for( i = 0 ; i < numPoint; i++ )
                    {
                        if( dists1->data.db[i] < threshold && dists2->data.db[i] < threshold )
                        {
                            numGoodPoints++;
                        }
                    }


                    /* Compute adaptive number of steps */
			        double ep = 1 - (double)numGoodPoints / (double)numPoint;
                    if( ep == 1 )
                    {
                        ep = 0.5;//if there is not good points set ration of outliers to 50%
                    }

			        double newNumSamples = log(1-p) / log(1-pow(1-ep,7));
                    if( newNumSamples < (double)NumSamples )
                    {
                        NumSamples = cvRound(newNumSamples);
                    }
                }
            }

            wasCount++;
        }

        /* Select just good points using threshold */
        /* Compute distances for all points for best fundamental matrix */

        /* Test if we have computed fundamental matrix*/
        if( goodMean == FLT_MAX )
        {
            numFundMatr = 0;

        }
        else
        {/* we have computed fundamental matrix */
		    {
                icvComputeCorrespondEpilines(wpoints1,2,&bestFund,corrLines2);
                icvComputeCorrespondEpilines(wpoints2,1,&bestFund,corrLines1);

			    icvCompPointLineDists(wpoints1,corrLines1,dists1);
			    icvCompPointLineDists(wpoints2,corrLines2,dists2);

                /* test dist for each point and set status for each point if need */
                int i;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?