fixed conflicts
authoredgarriba <edgar.riba@gmail.com>
Thu, 7 Aug 2014 10:41:47 +0000 (12:41 +0200)
committeredgarriba <edgar.riba@gmail.com>
Thu, 7 Aug 2014 10:41:47 +0000 (12:41 +0200)
1  2 
modules/calib3d/src/solvepnp.cpp

@@@ -112,76 -98,217 +112,79 @@@ bool cv::solvePnP( InputArray _opoints
      return false;
  }
  
 -namespace cv
 +class PnPRansacCallback : public PointSetRegistrator::Callback
  {
 -    namespace pnpransac
 -    {
 -        const int MIN_POINTS_COUNT = 4;
 -
 -        static void project3dPoints(const Mat& points, const Mat& rvec, const Mat& tvec, Mat& modif_points)
 -        {
 -            modif_points.create(1, points.cols, CV_32FC3);
 -            Mat R(3, 3, CV_64FC1);
 -            Rodrigues(rvec, R);
 -            Mat transformation(3, 4, CV_64F);
 -            Mat r = transformation.colRange(0, 3);
 -            R.copyTo(r);
 -            Mat t = transformation.colRange(3, 4);
 -            tvec.copyTo(t);
 -            transform(points, modif_points, transformation);
 -        }
 -
 -        struct CameraParameters
 -        {
 -            void init(Mat _intrinsics, Mat _distCoeffs)
 -            {
 -                _intrinsics.copyTo(intrinsics);
 -                _distCoeffs.copyTo(distortion);
 -            }
 -            Mat intrinsics;
 -            Mat distortion;
 -        };
 +public:
  
 -        struct Parameters
 -        {
 -            int iterationsCount;
 -            float reprojectionError;
 -            int minInliersCount;
 -            bool useExtrinsicGuess;
 -            int flags;
 -            CameraParameters camera;
 -        };
 -
 -        template <typename OpointType, typename IpointType>
 -        static void pnpTask(const std::vector<char>& pointsMask, const Mat& objectPoints, const Mat& imagePoints,
 -                     const Parameters& params, std::vector<int>& inliers, Mat& rvec, Mat& tvec,
 -                     const Mat& rvecInit, const Mat& tvecInit, Mutex& resultsMutex)
 -        {
 -            Mat modelObjectPoints(1, MIN_POINTS_COUNT, CV_MAKETYPE(DataDepth<OpointType>::value, 3));
 -            Mat modelImagePoints(1, MIN_POINTS_COUNT, CV_MAKETYPE(DataDepth<IpointType>::value, 2));
 -            for (int i = 0, colIndex = 0; i < (int)pointsMask.size(); i++)
 -            {
 -                if (pointsMask[i])
 -                {
 -                    Mat colModelImagePoints = modelImagePoints(Rect(colIndex, 0, 1, 1));
 -                    imagePoints.col(i).copyTo(colModelImagePoints);
 -                    Mat colModelObjectPoints = modelObjectPoints(Rect(colIndex, 0, 1, 1));
 -                    objectPoints.col(i).copyTo(colModelObjectPoints);
 -                    colIndex = colIndex+1;
 -                }
 -            }
 -
 -            //filter same 3d points, hang in solvePnP
 -            double eps = 1e-10;
 -            int num_same_points = 0;
 -            for (int i = 0; i < MIN_POINTS_COUNT; i++)
 -                for (int j = i + 1; j < MIN_POINTS_COUNT; j++)
 -                {
 -                    if (norm(modelObjectPoints.at<Vec<OpointType,3> >(0, i) - modelObjectPoints.at<Vec<OpointType,3> >(0, j)) < eps)
 -                        num_same_points++;
 -                }
 -            if (num_same_points > 0)
 -                return;
 +    PnPRansacCallback(Mat _cameraMatrix=Mat(3,3,CV_64F), Mat _distCoeffs=Mat(4,1,CV_64F), int _flags=cv::ITERATIVE,
 +            bool _useExtrinsicGuess=false, Mat _rvec=Mat(), Mat _tvec=Mat() )
 +        : cameraMatrix(_cameraMatrix), distCoeffs(_distCoeffs), flags(_flags), useExtrinsicGuess(_useExtrinsicGuess),
 +          rvec(_rvec), tvec(_tvec) {}
  
 -            Mat localRvec, localTvec;
 -            rvecInit.copyTo(localRvec);
 -            tvecInit.copyTo(localTvec);
 -
 -            solvePnP(modelObjectPoints, modelImagePoints, params.camera.intrinsics, params.camera.distortion, localRvec, localTvec,
 -                     params.useExtrinsicGuess, params.flags);
 +    /* Pre: True */
 +    /* Post: compute _model with given points an return number of found models */
 +    int runKernel( InputArray _m1, InputArray _m2, OutputArray _model ) const
 +    {
 +        Mat opoints = _m1.getMat(), ipoints = _m2.getMat();
  
 -            std::vector<Point_<OpointType> > projected_points;
 -            projected_points.resize(objectPoints.cols);
 -            projectPoints(objectPoints, localRvec, localTvec, params.camera.intrinsics, params.camera.distortion, projected_points);
 +        bool correspondence = cv::solvePnP( _m1, _m2, cameraMatrix, distCoeffs,
 +                                            rvec, tvec, useExtrinsicGuess, flags );
  
 -            Mat rotatedPoints;
 -            project3dPoints(objectPoints, localRvec, localTvec, rotatedPoints);
 +        Mat _local_model;
 +        cv::hconcat(rvec, tvec, _local_model);
 +        _local_model.copyTo(_model);
  
 -            std::vector<int> localInliers;
 -            for (int i = 0; i < objectPoints.cols; i++)
 -            {
 -                //Although p is a 2D point it needs the same type as the object points to enable the norm calculation
 -                Point_<OpointType> p((OpointType)imagePoints.at<Vec<IpointType,2> >(0, i)[0],
 -                                     (OpointType)imagePoints.at<Vec<IpointType,2> >(0, i)[1]);
 -                if ((norm(p - projected_points[i]) < params.reprojectionError)
 -                    && (rotatedPoints.at<Vec<OpointType,3> >(0, i)[2] > 0)) //hack
 -                {
 -                    localInliers.push_back(i);
 -                }
 -            }
 +        return correspondence;
 +    }
  
 -            if (localInliers.size() > inliers.size())
 -            {
 -                resultsMutex.lock();
 +    /* Pre: True */
 +    /* Post: fill _err with projection errors */
 +    void computeError( InputArray _m1, InputArray _m2, InputArray _model, OutputArray _err ) const
 +    {
  
 -                inliers.clear();
 -                inliers.resize(localInliers.size());
 -                memcpy(&inliers[0], &localInliers[0], sizeof(int) * localInliers.size());
 -                localRvec.copyTo(rvec);
 -                localTvec.copyTo(tvec);
 +        Mat opoints = _m1.getMat(), ipoints = _m2.getMat(), model = _model.getMat();
  
 -                resultsMutex.unlock();
 -            }
 -        }
 +        int i, count = opoints.cols;
 +        Mat _rvec = model.col(0);
 +        Mat _tvec = model.col(1);
  
 -        static void pnpTask(const std::vector<char>& pointsMask, const Mat& objectPoints, const Mat& imagePoints,
 -            const Parameters& params, std::vector<int>& inliers, Mat& rvec, Mat& tvec,
 -            const Mat& rvecInit, const Mat& tvecInit, Mutex& resultsMutex)
 -        {
 -            CV_Assert(objectPoints.depth() == CV_64F ||  objectPoints.depth() == CV_32F);
 -            CV_Assert(imagePoints.depth() == CV_64F ||  imagePoints.depth() == CV_32F);
 -            const bool objectDoublePrecision = objectPoints.depth() == CV_64F;
 -            const bool imageDoublePrecision = imagePoints.depth() == CV_64F;
 -            if(objectDoublePrecision)
 -            {
 -                if(imageDoublePrecision)
 -                    pnpTask<double, double>(pointsMask, objectPoints, imagePoints, params, inliers, rvec, tvec, rvecInit, tvecInit, resultsMutex);
 -                else
 -                    pnpTask<double, float>(pointsMask, objectPoints, imagePoints, params, inliers, rvec, tvec, rvecInit, tvecInit, resultsMutex);
 -            }
 -            else
 -            {
 -                if(imageDoublePrecision)
 -                    pnpTask<float, double>(pointsMask, objectPoints, imagePoints, params, inliers, rvec, tvec, rvecInit, tvecInit, resultsMutex);
 -                else
 -                    pnpTask<float, float>(pointsMask, objectPoints, imagePoints, params, inliers, rvec, tvec, rvecInit, tvecInit, resultsMutex);
 -            }
 -        }
 -        class PnPSolver
 -        {
 -        public:
 -            void operator()( const BlockedRange& r ) const
 -            {
 -                std::vector<char> pointsMask(objectPoints.cols, 0);
 -                memset(&pointsMask[0], 1, MIN_POINTS_COUNT );
 -                for( int i=r.begin(); i!=r.end(); ++i )
 -                {
 -                    generateVar(pointsMask);
 -                    pnpTask(pointsMask, objectPoints, imagePoints, parameters,
 -                            inliers, rvec, tvec, initRvec, initTvec, syncMutex);
 -                    if ((int)inliers.size() >= parameters.minInliersCount)
 -                    {
 -#ifdef HAVE_TBB
 -                        tbb::task::self().cancel_group_execution();
 -#else
 -                        break;
 -#endif
 -                    }
 -                }
 -            }
 -            PnPSolver(const Mat& _objectPoints, const Mat& _imagePoints, const Parameters& _parameters,
 -                      Mat& _rvec, Mat& _tvec, std::vector<int>& _inliers):
 -            objectPoints(_objectPoints), imagePoints(_imagePoints), parameters(_parameters),
 -            rvec(_rvec), tvec(_tvec), inliers(_inliers)
 -            {
 -                rvec.copyTo(initRvec);
 -                tvec.copyTo(initTvec);
 +        Mat projpoints(count, 2, CV_32FC1);
 +        cv::projectPoints(opoints, _rvec, _tvec, cameraMatrix, distCoeffs, projpoints);
  
 -                generator.state = theRNG().state; //to control it somehow...
 -            }
 -        private:
 -            PnPSolver& operator=(const PnPSolver&);
 +        const Point2f* ipoints_ptr = ipoints.ptr<Point2f>();
 +        const Point2f* projpoints_ptr = projpoints.ptr<Point2f>();
  
 -            const Mat& objectPoints;
 -            const Mat& imagePoints;
 -            const Parameters& parameters;
 -            Mat &rvec, &tvec;
 -            std::vector<int>& inliers;
 -            Mat initRvec, initTvec;
 +        _err.create(count, 1, CV_32FC1);
 +        float* err = _err.getMat().ptr<float>();
  
 -            static RNG generator;
 -            static Mutex syncMutex;
 +        for ( i = 0; i < count; ++i)
 +            err[i] = cv::norm( ipoints_ptr[i] - projpoints_ptr[i] );
  
 -            void generateVar(std::vector<char>& mask) const
 -            {
 -                int size = (int)mask.size();
 -                for (int i = 0; i < size; i++)
 -                {
 -                    int i1 = generator.uniform(0, size);
 -                    int i2 = generator.uniform(0, size);
 -                    char curr = mask[i1];
 -                    mask[i1] = mask[i2];
 -                    mask[i2] = curr;
 -                }
 -            }
 -        };
 +    }
  
 -        Mutex PnPSolver::syncMutex;
 -        RNG PnPSolver::generator;
  
 -    }
 -}
 +    Mat cameraMatrix;
 +    Mat distCoeffs;
 +    int flags;
 +    bool useExtrinsicGuess;
 +    Mat rvec;
 +    Mat tvec;
 +};
  
 -void cv::solvePnPRansac(InputArray _opoints, InputArray _ipoints,
 +bool cv::solvePnPRansac(InputArray _opoints, InputArray _ipoints,
                          InputArray _cameraMatrix, InputArray _distCoeffs,
                          OutputArray _rvec, OutputArray _tvec, bool useExtrinsicGuess,
 -                        int iterationsCount, float reprojectionError, int minInliersCount,
 +                        int iterationsCount, float reprojectionError, float confidence,
                          OutputArray _inliers, int flags)
  {
 +
      Mat opoints = _opoints.getMat(), ipoints = _ipoints.getMat();
 -    Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat();
 +
 +    int npoints = std::max(opoints.checkVector(3, CV_32F), opoints.checkVector(3, CV_64F));
 +    CV_Assert( npoints >= 0 && npoints == std::max(ipoints.checkVector(2, CV_32F), ipoints.checkVector(2, CV_64F)) );
  
      CV_Assert(opoints.isContinuous());
      CV_Assert(opoints.depth() == CV_32F || opoints.depth() == CV_64F);