fixed bug in ORB_GPU, behavior in the absence of keypoints found (Bug #1831)
This commit is contained in:
		@@ -63,7 +63,7 @@ void cv::gpu::ORB_GPU::mergeKeyPoints(GpuMat&) { throw_nogpu(); }
 | 
			
		||||
 | 
			
		||||
#else /* !defined (HAVE_CUDA) */
 | 
			
		||||
 | 
			
		||||
namespace cv { namespace gpu { namespace device 
 | 
			
		||||
namespace cv { namespace gpu { namespace device
 | 
			
		||||
{
 | 
			
		||||
    namespace orb
 | 
			
		||||
    {
 | 
			
		||||
@@ -345,8 +345,8 @@ namespace
 | 
			
		||||
        9,-7, 10,-2/*mean (0.124978), correlation (0.549846)*/,
 | 
			
		||||
        7,0, 12,-2/*mean (0.127002), correlation (0.537452)*/,
 | 
			
		||||
        -1,-6, 0,-11/*mean (0.127148), correlation (0.547401)*/
 | 
			
		||||
    };    
 | 
			
		||||
 
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    void initializeOrbPattern(const Point* pattern0, Mat& pattern, int ntuples, int tupleSize, int poolSize)
 | 
			
		||||
    {
 | 
			
		||||
        RNG rng(0x12345678);
 | 
			
		||||
@@ -356,7 +356,7 @@ namespace
 | 
			
		||||
 | 
			
		||||
        int* pattern_x_ptr = pattern.ptr<int>(0);
 | 
			
		||||
        int* pattern_y_ptr = pattern.ptr<int>(1);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < ntuples; i++)
 | 
			
		||||
        {
 | 
			
		||||
            for (int k = 0; k < tupleSize; k++)
 | 
			
		||||
@@ -386,8 +386,8 @@ namespace
 | 
			
		||||
    {
 | 
			
		||||
        // we always start with a fixed seed,
 | 
			
		||||
        // to make patterns the same on each run
 | 
			
		||||
        RNG rng(0x34985739); 
 | 
			
		||||
                             
 | 
			
		||||
        RNG rng(0x34985739);
 | 
			
		||||
 | 
			
		||||
        for (int i = 0; i < npoints; i++)
 | 
			
		||||
        {
 | 
			
		||||
            pattern[i].x = rng.uniform(-patchSize / 2, patchSize / 2 + 1);
 | 
			
		||||
@@ -400,11 +400,11 @@ cv::gpu::ORB_GPU::ORB_GPU(int nFeatures, float scaleFactor, int nLevels, int edg
 | 
			
		||||
    nFeatures_(nFeatures), scaleFactor_(scaleFactor), nLevels_(nLevels), edgeThreshold_(edgeThreshold), firstLevel_(firstLevel), WTA_K_(WTA_K),
 | 
			
		||||
    scoreType_(scoreType), patchSize_(patchSize),
 | 
			
		||||
    fastDetector_(DEFAULT_FAST_THRESHOLD)
 | 
			
		||||
{    
 | 
			
		||||
{
 | 
			
		||||
    // fill the extractors and descriptors for the corresponding scales
 | 
			
		||||
    float factor = 1.0f / scaleFactor_;
 | 
			
		||||
    float n_desired_features_per_scale = nFeatures_ * (1.0f - factor) / (1.0f - std::pow(factor, nLevels_));
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    n_features_per_level_.resize(nLevels_);
 | 
			
		||||
    size_t sum_n_features = 0;
 | 
			
		||||
    for (int level = 0; level < nLevels_ - 1; ++level)
 | 
			
		||||
@@ -420,7 +420,7 @@ cv::gpu::ORB_GPU::ORB_GPU(int nFeatures, float scaleFactor, int nLevels, int edg
 | 
			
		||||
    vector<int> u_max(half_patch_size + 1);
 | 
			
		||||
    for (int v = 0; v <= half_patch_size * std::sqrt(2.f) / 2 + 1; ++v)
 | 
			
		||||
        u_max[v] = cvRound(std::sqrt(static_cast<float>(half_patch_size * half_patch_size - v * v)));
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    // Make sure we are symmetric
 | 
			
		||||
    for (int v = half_patch_size, v_0 = 0; v >= half_patch_size * std::sqrt(2.f) / 2; --v)
 | 
			
		||||
    {
 | 
			
		||||
@@ -431,7 +431,7 @@ cv::gpu::ORB_GPU::ORB_GPU(int nFeatures, float scaleFactor, int nLevels, int edg
 | 
			
		||||
    }
 | 
			
		||||
    CV_Assert(u_max.size() < 32);
 | 
			
		||||
    cv::gpu::device::orb::loadUMax(&u_max[0], static_cast<int>(u_max.size()));
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    // Calc pattern
 | 
			
		||||
    const int npoints = 512;
 | 
			
		||||
    Point pattern_buf[npoints];
 | 
			
		||||
@@ -441,15 +441,15 @@ cv::gpu::ORB_GPU::ORB_GPU(int nFeatures, float scaleFactor, int nLevels, int edg
 | 
			
		||||
        pattern0 = pattern_buf;
 | 
			
		||||
        makeRandomPattern(patchSize_, pattern_buf, npoints);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    CV_Assert(WTA_K_ == 2 || WTA_K_ == 3 || WTA_K_ == 4);    
 | 
			
		||||
 | 
			
		||||
    CV_Assert(WTA_K_ == 2 || WTA_K_ == 3 || WTA_K_ == 4);
 | 
			
		||||
 | 
			
		||||
    Mat h_pattern;
 | 
			
		||||
 | 
			
		||||
    if (WTA_K_ == 2)
 | 
			
		||||
    {
 | 
			
		||||
        h_pattern.create(2, npoints, CV_32SC1);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        int* pattern_x_ptr = h_pattern.ptr<int>(0);
 | 
			
		||||
        int* pattern_y_ptr = h_pattern.ptr<int>(1);
 | 
			
		||||
 | 
			
		||||
@@ -466,7 +466,7 @@ cv::gpu::ORB_GPU::ORB_GPU(int nFeatures, float scaleFactor, int nLevels, int edg
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pattern_.upload(h_pattern);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    blurFilter = createGaussianFilter_GPU(CV_8UC1, Size(7, 7), 2, 2, BORDER_REFLECT_101);
 | 
			
		||||
 | 
			
		||||
    blurForDescriptor = false;
 | 
			
		||||
@@ -497,7 +497,7 @@ void cv::gpu::ORB_GPU::buildScalePyramids(const GpuMat& image, const GpuMat& mas
 | 
			
		||||
        ensureSizeIsEnough(sz, image.type(), imagePyr_[level]);
 | 
			
		||||
        ensureSizeIsEnough(sz, CV_8UC1, maskPyr_[level]);
 | 
			
		||||
        maskPyr_[level].setTo(Scalar::all(255));
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        // Compute the resized image
 | 
			
		||||
        if (level != firstLevel_)
 | 
			
		||||
        {
 | 
			
		||||
@@ -544,7 +544,7 @@ namespace
 | 
			
		||||
        //this is only necessary if the keypoints size is greater than the number of desired points.
 | 
			
		||||
        if (count > n_points)
 | 
			
		||||
        {
 | 
			
		||||
            if (n_points == 0) 
 | 
			
		||||
            if (n_points == 0)
 | 
			
		||||
            {
 | 
			
		||||
                keypoints.release();
 | 
			
		||||
                return;
 | 
			
		||||
@@ -563,18 +563,24 @@ void cv::gpu::ORB_GPU::computeKeyPointsPyramid()
 | 
			
		||||
 | 
			
		||||
    keyPointsPyr_.resize(nLevels_);
 | 
			
		||||
    keyPointsCount_.resize(nLevels_);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    for (int level = 0; level < nLevels_; ++level)
 | 
			
		||||
    {
 | 
			
		||||
        keyPointsCount_[level] = fastDetector_.calcKeyPointsLocation(imagePyr_[level], maskPyr_[level]);
 | 
			
		||||
 | 
			
		||||
        if (keyPointsCount_[level] == 0)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        ensureSizeIsEnough(3, keyPointsCount_[level], CV_32FC1, keyPointsPyr_[level]);
 | 
			
		||||
 | 
			
		||||
        GpuMat fastKpRange = keyPointsPyr_[level].rowRange(0, 2);
 | 
			
		||||
        keyPointsCount_[level] = fastDetector_.getKeyPoints(fastKpRange);
 | 
			
		||||
 | 
			
		||||
        if (keyPointsCount_[level] == 0)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        int n_features = static_cast<int>(n_features_per_level_[level]);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        if (scoreType_ == ORB::HARRIS_SCORE)
 | 
			
		||||
        {
 | 
			
		||||
            // Keep more points than necessary as FAST does not give amazing corners
 | 
			
		||||
@@ -582,7 +588,7 @@ void cv::gpu::ORB_GPU::computeKeyPointsPyramid()
 | 
			
		||||
 | 
			
		||||
            // Compute the Harris cornerness (better scoring than FAST)
 | 
			
		||||
            HarrisResponses_gpu(imagePyr_[level], keyPointsPyr_[level].ptr<short2>(0), keyPointsPyr_[level].ptr<float>(1), keyPointsCount_[level], 7, HARRIS_K, 0);
 | 
			
		||||
        }        
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //cull to the final desired level, using the new Harris scores or the original FAST scores.
 | 
			
		||||
        cull(keyPointsPyr_[level], keyPointsCount_[level], n_features);
 | 
			
		||||
@@ -612,7 +618,10 @@ void cv::gpu::ORB_GPU::computeDescriptors(GpuMat& descriptors)
 | 
			
		||||
    int offset = 0;
 | 
			
		||||
 | 
			
		||||
    for (int level = 0; level < nLevels_; ++level)
 | 
			
		||||
    {       
 | 
			
		||||
    {
 | 
			
		||||
        if (keyPointsCount_[level] == 0)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        GpuMat descRange = descriptors.rowRange(offset, offset + keyPointsCount_[level]);
 | 
			
		||||
 | 
			
		||||
        if (blurForDescriptor)
 | 
			
		||||
@@ -622,7 +631,7 @@ void cv::gpu::ORB_GPU::computeDescriptors(GpuMat& descriptors)
 | 
			
		||||
            blurFilter->apply(imagePyr_[level], buf_, Rect(0, 0, imagePyr_[level].cols, imagePyr_[level].rows));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        computeOrbDescriptor_gpu(blurForDescriptor ? buf_ : imagePyr_[level], keyPointsPyr_[level].ptr<short2>(0), keyPointsPyr_[level].ptr<float>(2), 
 | 
			
		||||
        computeOrbDescriptor_gpu(blurForDescriptor ? buf_ : imagePyr_[level], keyPointsPyr_[level].ptr<short2>(0), keyPointsPyr_[level].ptr<float>(2),
 | 
			
		||||
            keyPointsCount_[level], pattern_.ptr<int>(0), pattern_.ptr<int>(1), descRange, descriptorSize(), WTA_K_, 0);
 | 
			
		||||
 | 
			
		||||
        offset += keyPointsCount_[level];
 | 
			
		||||
@@ -647,20 +656,23 @@ void cv::gpu::ORB_GPU::mergeKeyPoints(GpuMat& keypoints)
 | 
			
		||||
    ensureSizeIsEnough(ROWS_COUNT, nAllkeypoints, CV_32FC1, keypoints);
 | 
			
		||||
 | 
			
		||||
    int offset = 0;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    for (int level = 0; level < nLevels_; ++level)
 | 
			
		||||
    {
 | 
			
		||||
        if (keyPointsCount_[level] == 0)
 | 
			
		||||
            continue;
 | 
			
		||||
 | 
			
		||||
        float sf = getScale(scaleFactor_, firstLevel_, level);
 | 
			
		||||
 | 
			
		||||
        GpuMat keyPointsRange = keypoints.colRange(offset, offset + keyPointsCount_[level]);        
 | 
			
		||||
        
 | 
			
		||||
        GpuMat keyPointsRange = keypoints.colRange(offset, offset + keyPointsCount_[level]);
 | 
			
		||||
 | 
			
		||||
        float locScale = level != firstLevel_ ? sf : 1.0f;
 | 
			
		||||
 | 
			
		||||
        mergeLocation_gpu(keyPointsPyr_[level].ptr<short2>(0), keyPointsRange.ptr<float>(0), keyPointsRange.ptr<float>(1), keyPointsCount_[level], locScale, 0);
 | 
			
		||||
 | 
			
		||||
        GpuMat range = keyPointsRange.rowRange(2, 4);
 | 
			
		||||
        keyPointsPyr_[level](Range(1, 3), Range(0, keyPointsCount_[level])).copyTo(range);
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        keyPointsRange.row(4).setTo(Scalar::all(level));
 | 
			
		||||
        keyPointsRange.row(5).setTo(Scalar::all(patchSize_ * sf));
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user