Пример #1
0
// Draws matches of keypints from two images on output image.
void ICLASS_API DrawMatches(
	TMat* img1, TCVectorKeyPoint* keypoints1,
	TMat* img2, TCVectorKeyPoint* keypoints2,
	TCVectorDMatch* matches1to2, TMat** outImg)
{
	vector<KeyPoint> k1, k2;	
	for (size_t i = 0; i < keypoints1->size(); i++)
	{
		TKeyPoint K = *keypoints1->at(i);
		k1.push_back(KeyPoint(K.x, K.y, K.size, K.angle, K.response, K.octave, K.class_id));
	}
	for (size_t i = 0; i < keypoints2->size(); i++)
	{
		TKeyPoint K = *keypoints2->at(i);
		k2.push_back(KeyPoint(K.x, K.y, K.size, K.angle, K.response, K.octave, K.class_id));
	}
	
	vector<DMatch> m1to2;
	for (size_t i = 0; i < matches1to2->size(); i++)
	{
		TDMatch K = *matches1to2->at(i);
		m1to2.push_back(DMatch(K.queryIdx, K.trainIdx, K.imgIdx, K.distance));
	}
	
	Mat oImg;
	drawMatches(*img1->Mat(), k1, *img2->Mat(), k2, m1to2, oImg);

	*outImg = new TMat(oImg);
};
    TFGeometry1D* TFGeometry1D::createQuad(const cgt::vec2& interval, const cgt::col4& leftColor, const cgt::col4& rightColor) {
        cgtAssert(interval.x >= 0.f && interval.y <= 1.f, "Interval out of bounds");

        std::vector<KeyPoint> keyPoints;
        keyPoints.push_back(KeyPoint(interval.x, leftColor));
        keyPoints.push_back(KeyPoint(interval.y, rightColor));
        return new TFGeometry1D(keyPoints);
    }
    TFGeometry1D* TFGeometry1D::createDivergingColorMap(const cgt::vec2& interval, const cgt::col4& leftColor, const cgt::col4& rightColor, float bias /*= 0.5f*/) {
        cgtAssert(interval.x >= 0.f && interval.y <= 1.f, "Interval out of bounds, must be in [0, 1].");
        cgtAssert(bias > 0.f && bias < 1.f, "Bias out of bounds, must be in (0, 1).");

        std::vector<KeyPoint> keyPoints;
        keyPoints.push_back(KeyPoint(interval.x, leftColor));
        keyPoints.push_back(KeyPoint(interval.x + (interval.y - interval.x) * bias, cgt::col4(255, 255, 255, 255)));
        keyPoints.push_back(KeyPoint(interval.y, rightColor));
        return new TFGeometry1D(keyPoints);
    }
    TFGeometry1D* TFGeometry1D::createHeatedBodyColorMap(const cgt::vec2& interval /*= cgt::vec2(0.f, 1.f)*/) {
        cgtAssert(interval.x >= 0.f && interval.y <= 1.f, "Interval out of bounds, must be in [0, 1].");

        std::vector<KeyPoint> keyPoints;
        keyPoints.push_back(KeyPoint(interval.x, cgt::col4(0, 0, 0, 255)));
        keyPoints.push_back(KeyPoint(interval.x + (interval.y - interval.x) * 0.35f, cgt::col4(224, 0, 0, 255)));
        keyPoints.push_back(KeyPoint(interval.x + (interval.y - interval.x) * 0.85f, cgt::col4(255, 255, 0, 255)));
        keyPoints.push_back(KeyPoint(interval.y, cgt::col4(255, 255, 255, 255)));
        return new TFGeometry1D(keyPoints);
    }
    TFGeometry2D* TFGeometry2D::createQuad(const cgt::vec2& ll, const cgt::vec2& ur, const cgt::col4& color) {
        cgtAssert(cgt::hand(cgt::greaterThanEqual(ll, cgt::vec2::zero)) && cgt::hand(cgt::lessThanEqual(ur, cgt::vec2(1.f))), "Interval out of bounds");
        cgtAssert(cgt::hand(cgt::lessThan(ll, ur)), "Lower left corner coordinates must be smaller than the upper right ones!");

        std::vector<KeyPoint> keyPoints;
        keyPoints.push_back(KeyPoint(ll, color));
        keyPoints.push_back(KeyPoint(cgt::vec2(ur.x, ll.y), color));
        keyPoints.push_back(KeyPoint(ur, color));
        keyPoints.push_back(KeyPoint(cgt::vec2(ll.x, ur.y), color));
        return new TFGeometry2D(keyPoints);
    }
Пример #6
0
void TestCube::setKeypointsImg3(vector<KeyPoint> &keyPoints) {
  keyPoints.push_back(KeyPoint(Point2f(212, 314), 1));
  keyPoints.push_back(KeyPoint(Point2f(480, 271), 1));
  keyPoints.push_back(KeyPoint(Point2f(778, 306), 1));
  keyPoints.push_back(KeyPoint(Point2f(532, 370), 1));
  keyPoints.push_back(KeyPoint(Point2f(240, 683), 1));
  keyPoints.push_back(KeyPoint(Point2f(529, 818), 1));
  keyPoints.push_back(KeyPoint(Point2f(752, 663), 1));
  keyPoints.push_back(KeyPoint(Point2f(530, 608), 1));
  keyPoints.push_back(KeyPoint(Point2f(765, 493), 1));
}
Пример #7
0
void TestCube::setKeypointsImg2(vector<KeyPoint> &keyPoints) {
  keyPoints.push_back(KeyPoint(Point2f(209, 318), 1));
  keyPoints.push_back(KeyPoint(Point2f(460, 272), 1));
  keyPoints.push_back(KeyPoint(Point2f(770, 302), 1));
  keyPoints.push_back(KeyPoint(Point2f(564, 370), 1));
  keyPoints.push_back(KeyPoint(Point2f(238, 694), 1));
  keyPoints.push_back(KeyPoint(Point2f(556, 816), 1));
  keyPoints.push_back(KeyPoint(Point2f(745, 653), 1));
  keyPoints.push_back(KeyPoint(Point2f(560, 607), 1));
  keyPoints.push_back(KeyPoint(Point2f(757, 486), 1));
}
Пример #8
0
void pkmSIFTImage::allocate(int w, int h)
{
    if(width != w || height != h)
    {
        printf("[pkmSIFTImage]: Reallocating...\n");
        grayImg.allocate(w,h);
        if (bAllocatedCompressedSIFT) {
            delete compressedSiftImg;
            bAllocatedCompressedSIFT = false;
        }

        imageKeypoints.clear();
        for(int i = 0; i < h; i+=stepSize)
        {
            for(int j = 0; j < w; j+=stepSize)
            {
                imageKeypoints.push_back(KeyPoint(Point2f(j,i), cellSize));
            }
        }
    
        descriptorExtractorSurf = new SurfDescriptorExtractor(  4,        // octaves
                                                                2,        // layers
                                                                true );   // extended?
        descriptorExtractor = new SiftDescriptorExtractor(SIFT::DescriptorParams(   1,        // magnification
                                                                                    true,     // normalize?
                                                                                    true),    // recalculate angles?
                                                          SIFT::CommonParams(   4,             // number of octaves
                                                                                2,             // number of octave layers
                                                                                -1,             // first octave
                                                                                0) );          // FIRST_ANGLE = 0, AVERAGE_ANGLE = 1
    }
    width = w;
    height = h;
    
}
Пример #9
0
    void detect( InputArray _image, std::vector<KeyPoint>& keypoints, InputArray _mask )
    {
        CV_INSTRUMENT_REGION()

        std::vector<Point2f> corners;

        if (_image.isUMat())
        {
            UMat ugrayImage;
            if( _image.type() != CV_8U )
                cvtColor( _image, ugrayImage, COLOR_BGR2GRAY );
            else
                ugrayImage = _image.getUMat();

            goodFeaturesToTrack( ugrayImage, corners, nfeatures, qualityLevel, minDistance, _mask,
                                 blockSize, useHarrisDetector, k );
        }
        else
        {
            Mat image = _image.getMat(), grayImage = image;
            if( image.type() != CV_8U )
                cvtColor( image, grayImage, COLOR_BGR2GRAY );

            goodFeaturesToTrack( grayImage, corners, nfeatures, qualityLevel, minDistance, _mask,
                                blockSize, useHarrisDetector, k );
        }

        keypoints.resize(corners.size());
        std::vector<Point2f>::const_iterator corner_it = corners.begin();
        std::vector<KeyPoint>::iterator keypoint_it = keypoints.begin();
        for( ; corner_it != corners.end(); ++corner_it, ++keypoint_it )
            *keypoint_it = KeyPoint( *corner_it, (float)blockSize );

    }
Пример #10
0
void TestCube::setKeypointsImg1(vector<KeyPoint> &keyPoints) {
  keyPoints.push_back(KeyPoint(Point2f(209, 323), 1));
  keyPoints.push_back(KeyPoint(Point2f(440, 272), 1));
  keyPoints.push_back(KeyPoint(Point2f(760, 298), 1));
  keyPoints.push_back(KeyPoint(Point2f(594, 368), 1));
  keyPoints.push_back(KeyPoint(Point2f(238, 705), 1));
  keyPoints.push_back(KeyPoint(Point2f(583, 812), 1));
  keyPoints.push_back(KeyPoint(Point2f(736, 644), 1));
  keyPoints.push_back(KeyPoint(Point2f(588, 604), 1));
}
void KeypointTracker::points2keypoints(const vector<Point2f>& in, vector<KeyPoint>* out)
{
    out->clear();
    out->reserve(in.size());
    for (size_t i = 0; i < in.size(); ++i)
    {
        out->push_back(KeyPoint(in[i], 1));
    }
}
Пример #12
0
void KeyPoint::convert( const std::vector<Point2f>& points2f, std::vector<KeyPoint>& keypoints,
                        float size, float response, int octave, int class_id )
{
    CV_INSTRUMENT_REGION();

    keypoints.resize(points2f.size());
    for( size_t i = 0; i < points2f.size(); i++ )
        keypoints[i] = KeyPoint(points2f[i], size, -1, response, octave, class_id);
}
Пример #13
0
//Takes an xy point and appends that to a keypoint structure
void points2keypoints(const vector<Point2f>& in, vector<KeyPoint>& out)
{
    out.clear();
    out.reserve(in.size());
    for (size_t i = 0; i < in.size(); ++i)
    {
        out.push_back(KeyPoint(in[i], 1));
    }
}
Пример #14
0
void GoodFeaturesToTrackDetector::detectImpl(const Mat& image, const Mat& mask,
        vector<KeyPoint>& keypoints) const {
    vector<Point2f> corners;
    goodFeaturesToTrack(image, corners, maxCorners, qualityLevel, minDistance, mask,
                        blockSize, useHarrisDetector, k);
    keypoints.resize(corners.size());
    vector<Point2f>::const_iterator corner_it = corners.begin();
    vector<KeyPoint>::iterator keypoint_it = keypoints.begin();
    for (; corner_it != corners.end(); ++corner_it, ++keypoint_it) {
        *keypoint_it = KeyPoint(*corner_it, (float)blockSize);
    }
}
Пример #15
0
void MserFeatureDetector::detectImpl(const Mat& image, const Mat& mask, vector<KeyPoint>& keypoints) const {
    vector<vector<Point> > msers;
    mser(image, msers, mask);

    keypoints.resize(msers.size());
    vector<vector<Point> >::const_iterator contour_it = msers.begin();
    vector<KeyPoint>::iterator keypoint_it = keypoints.begin();
    for (; contour_it != msers.end(); ++contour_it, ++keypoint_it) {
        // TODO check transformation from MSER region to KeyPoint
        RotatedRect rect = fitEllipse(Mat(*contour_it));
        *keypoint_it = KeyPoint(rect.center, sqrt(rect.size.height * rect.size.width), rect.angle);
    }
}
Пример #16
0
/**
 * Interpolate real point position and add it to the interesting points if it converges.
 *
 * TODO: Implement interpolation.
 */
void FastHessian::addPoint(Point pt, ResponseLayer *b, ResponseLayer *m, ResponseLayer *t)
{
  double dx, dy, ds;
  interpolate(pt, b, m, t, &dx, &dy, &ds);

  // Following the lead of opensurf and opencv, instead of doing
  // actual interpolation and checking for convergence, we just
  // discard points that do not correspond to the interpolated value.
  //
  // For opencv the cutoff value here is 1, for opensurf it's 0.5.
  if (qAbs(dx) < 0.5f && qAbs(dy) < 0.5f && qAbs(ds) < 0.5f) {
    m_ipoints.append(KeyPoint((pt.x+dx)*t->step(), (pt.y+dy)*t->step(), 1));
  }
}
Пример #17
0
void GFTTDetector::detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask) const
{
    Mat grayImage = image;
    if( image.type() != CV_8U ) cvtColor( image, grayImage, CV_BGR2GRAY );

    vector<Point2f> corners;
    goodFeaturesToTrack( grayImage, corners, nfeatures, qualityLevel, minDistance, mask,
                         blockSize, useHarrisDetector, k );
    keypoints.resize(corners.size());
    vector<Point2f>::const_iterator corner_it = corners.begin();
    vector<KeyPoint>::iterator keypoint_it = keypoints.begin();
    for( ; corner_it != corners.end(); ++corner_it, ++keypoint_it )
    {
        *keypoint_it = KeyPoint( *corner_it, (float)blockSize );
    }
}
    void TFGeometry2D::computeCenterAndSortKeyPoints() {
        if (_keyPoints.empty())
            return;

        cgt::vec2 cPos(0.f);
        cgt::vec4 cCol(0.f);
        for (std::vector<KeyPoint>::const_iterator it = _keyPoints.begin(); it != _keyPoints.end(); ++it) {
            cPos += it->_position;
            cCol += toVec(it->_color);
        }
        cPos /= static_cast<float>(_keyPoints.size());
        cCol /= static_cast<float>(_keyPoints.size());
        _center = KeyPoint(cPos, toCol(cCol));

        std::sort(_keyPoints.begin(), _keyPoints.end(), KeyPointSorter(_center._position));
    }
Пример #19
0
bool bt_scientist::load(MKeyValue& atts) {
	int n = atts.getInt("kpt_size", 0);
	keyPoints.resize(n);
	for (int i = 0; i < n; i++) {
		KPT_ATR_NAME(atrType, "type", i);
		KPT_ATR_NAME(atrPos, "pos", i);
		KPT_ATR_NAME(atrWait, "wait", i);
		keyPoints[i] = KeyPoint(
			kptTypes[atts.getString(atrType, "seek")]
			, atts.getPoint(atrPos)
			, atts.getFloat(atrWait, 0.0f)
		);
	}

	zmin = atts.getFloat("zmin", 100.0f);
	zmax = atts.getFloat("zmax", 0.1f);

	load_bt(atts);
	return true;
}
Пример #20
0
void DenseFeatureDetector::detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask ) const
{
    float curScale = static_cast<float>(initFeatureScale);
    int curStep = initXyStep;
    int curBound = initImgBound;
    for( int curLevel = 0; curLevel < featureScaleLevels; curLevel++ )
    {
        for( int x = curBound; x < image.cols - curBound; x += curStep )
        {
            for( int y = curBound; y < image.rows - curBound; y += curStep )
            {
                keypoints.push_back( KeyPoint(static_cast<float>(x), static_cast<float>(y), curScale) );
            }
        }

        curScale = static_cast<float>(curScale * featureScaleMul);
        if( varyXyStepWithScale ) curStep = static_cast<int>( curStep * featureScaleMul + 0.5f );
        if( varyImgBoundWithScale ) curBound = static_cast<int>( curBound * featureScaleMul + 0.5f );
    }

    KeyPointsFilter::runByPixelsMask( keypoints, mask );
}
Пример #21
0
vector<KeyPoint> NonMaxSup_resize_format(const Mat &response, const float& resizeRatio, const float &scaleKeypoint, const float & orientationKeypoint)
{
    // stupid non-max suppression without any fancy tricks
    vector<KeyPoint> res;
    for(int i=1; i<response.rows-1; ++i)
    {
        const float* pixelinprev = response.ptr<float>(i-1); //previous line
        const float* pixelin = response.ptr<float>(i); //current line
        const float* pixelinnext = response.ptr<float>(i+1); //next line

        for(int j=1; j<response.cols-1; ++j)
        {
            bool bMax = true;
            const float val = *pixelin;//response.at<float>(i,j);

            //for(int ii=-1; ii <= +1; ++ii)
            for(int jj=-1; jj <= +1 && bMax; ++jj)
            {
                if (*(pixelinprev+jj) >= val) bMax = false;
                if (*(pixelin+jj) >= val && jj != 0) bMax = false;
                if (*(pixelinnext+jj) >= val) bMax = false;
            }

            if (bMax)
            {
                res.push_back(KeyPoint(Point2f(j * resizeRatio, i * resizeRatio), scaleKeypoint,orientationKeypoint,val));
            }

            pixelin++;//next
            pixelinnext++;//next
            pixelinprev++;//next

        }            
    }

    return res;
}
Пример #22
0
void FAST_t(InputArray _img, std::vector<KeyPoint>& keypoints, int threshold, bool nonmax_suppression)
{
    Mat img = _img.getMat();
    const int K = patternSize/2, N = patternSize + K + 1;
#if CV_SSE2
    const int quarterPatternSize = patternSize/4;
    (void)quarterPatternSize;
#endif
    int i, j, k, pixel[25];
    makeOffsets(pixel, (int)img.step, patternSize);

    keypoints.clear();

    threshold = std::min(std::max(threshold, 0), 255);

#if CV_SSE2
    __m128i delta = _mm_set1_epi8(-128), t = _mm_set1_epi8((char)threshold), K16 = _mm_set1_epi8((char)K);
    (void)K16;
    (void)delta;
    (void)t;
#endif
    uchar threshold_tab[512];
    for( i = -255; i <= 255; i++ )
        threshold_tab[i+255] = (uchar)(i < -threshold ? 1 : i > threshold ? 2 : 0);

    AutoBuffer<uchar> _buf((img.cols+16)*3*(sizeof(int) + sizeof(uchar)) + 128);
    uchar* buf[3];
    buf[0] = _buf; buf[1] = buf[0] + img.cols; buf[2] = buf[1] + img.cols;
    int* cpbuf[3];
    cpbuf[0] = (int*)alignPtr(buf[2] + img.cols, sizeof(int)) + 1;
    cpbuf[1] = cpbuf[0] + img.cols + 1;
    cpbuf[2] = cpbuf[1] + img.cols + 1;
    memset(buf[0], 0, img.cols*3);

    for(i = 3; i < img.rows-2; i++)
    {
        const uchar* ptr = img.ptr<uchar>(i) + 3;
        uchar* curr = buf[(i - 3)%3];
        int* cornerpos = cpbuf[(i - 3)%3];
        memset(curr, 0, img.cols);
        int ncorners = 0;

        if( i < img.rows - 3 )
        {
            j = 3;
    #if CV_SSE2
            if( patternSize == 16 )
            {
                for(; j < img.cols - 16 - 3; j += 16, ptr += 16)
                {
                    __m128i m0, m1;
                    __m128i v0 = _mm_loadu_si128((const __m128i*)ptr);
                    __m128i v1 = _mm_xor_si128(_mm_subs_epu8(v0, t), delta);
                    v0 = _mm_xor_si128(_mm_adds_epu8(v0, t), delta);

                    __m128i x0 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[0])), delta);
                    __m128i x1 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[quarterPatternSize])), delta);
                    __m128i x2 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[2*quarterPatternSize])), delta);
                    __m128i x3 = _mm_sub_epi8(_mm_loadu_si128((const __m128i*)(ptr + pixel[3*quarterPatternSize])), delta);
                    m0 = _mm_and_si128(_mm_cmpgt_epi8(x0, v0), _mm_cmpgt_epi8(x1, v0));
                    m1 = _mm_and_si128(_mm_cmpgt_epi8(v1, x0), _mm_cmpgt_epi8(v1, x1));
                    m0 = _mm_or_si128(m0, _mm_and_si128(_mm_cmpgt_epi8(x1, v0), _mm_cmpgt_epi8(x2, v0)));
                    m1 = _mm_or_si128(m1, _mm_and_si128(_mm_cmpgt_epi8(v1, x1), _mm_cmpgt_epi8(v1, x2)));
                    m0 = _mm_or_si128(m0, _mm_and_si128(_mm_cmpgt_epi8(x2, v0), _mm_cmpgt_epi8(x3, v0)));
                    m1 = _mm_or_si128(m1, _mm_and_si128(_mm_cmpgt_epi8(v1, x2), _mm_cmpgt_epi8(v1, x3)));
                    m0 = _mm_or_si128(m0, _mm_and_si128(_mm_cmpgt_epi8(x3, v0), _mm_cmpgt_epi8(x0, v0)));
                    m1 = _mm_or_si128(m1, _mm_and_si128(_mm_cmpgt_epi8(v1, x3), _mm_cmpgt_epi8(v1, x0)));
                    m0 = _mm_or_si128(m0, m1);
                    int mask = _mm_movemask_epi8(m0);
                    if( mask == 0 )
                        continue;
                    if( (mask & 255) == 0 )
                    {
                        j -= 8;
                        ptr -= 8;
                        continue;
                    }

                    __m128i c0 = _mm_setzero_si128(), c1 = c0, max0 = c0, max1 = c0;
                    for( k = 0; k < N; k++ )
                    {
                        __m128i x = _mm_xor_si128(_mm_loadu_si128((const __m128i*)(ptr + pixel[k])), delta);
                        m0 = _mm_cmpgt_epi8(x, v0);
                        m1 = _mm_cmpgt_epi8(v1, x);

                        c0 = _mm_and_si128(_mm_sub_epi8(c0, m0), m0);
                        c1 = _mm_and_si128(_mm_sub_epi8(c1, m1), m1);

                        max0 = _mm_max_epu8(max0, c0);
                        max1 = _mm_max_epu8(max1, c1);
                    }

                    max0 = _mm_max_epu8(max0, max1);
                    int m = _mm_movemask_epi8(_mm_cmpgt_epi8(max0, K16));

                    for( k = 0; m > 0 && k < 16; k++, m >>= 1 )
                        if(m & 1)
                        {
                            cornerpos[ncorners++] = j+k;
                            if(nonmax_suppression)
                                curr[j+k] = (uchar)cornerScore<patternSize>(ptr+k, pixel, threshold);
                        }
                }
            }
    #endif
            for( ; j < img.cols - 3; j++, ptr++ )
            {
                int v = ptr[0];
                const uchar* tab = &threshold_tab[0] - v + 255;
                int d = tab[ptr[pixel[0]]] | tab[ptr[pixel[8]]];

                if( d == 0 )
                    continue;

                d &= tab[ptr[pixel[2]]] | tab[ptr[pixel[10]]];
                d &= tab[ptr[pixel[4]]] | tab[ptr[pixel[12]]];
                d &= tab[ptr[pixel[6]]] | tab[ptr[pixel[14]]];

                if( d == 0 )
                    continue;

                d &= tab[ptr[pixel[1]]] | tab[ptr[pixel[9]]];
                d &= tab[ptr[pixel[3]]] | tab[ptr[pixel[11]]];
                d &= tab[ptr[pixel[5]]] | tab[ptr[pixel[13]]];
                d &= tab[ptr[pixel[7]]] | tab[ptr[pixel[15]]];

                if( d & 1 )
                {
                    int vt = v - threshold, count = 0;

                    for( k = 0; k < N; k++ )
                    {
                        int x = ptr[pixel[k]];
                        if(x < vt)
                        {
                            if( ++count > K )
                            {
                                cornerpos[ncorners++] = j;
                                if(nonmax_suppression)
                                    curr[j] = (uchar)cornerScore<patternSize>(ptr, pixel, threshold);
                                break;
                            }
                        }
                        else
                            count = 0;
                    }
                }

                if( d & 2 )
                {
                    int vt = v + threshold, count = 0;

                    for( k = 0; k < N; k++ )
                    {
                        int x = ptr[pixel[k]];
                        if(x > vt)
                        {
                            if( ++count > K )
                            {
                                cornerpos[ncorners++] = j;
                                if(nonmax_suppression)
                                    curr[j] = (uchar)cornerScore<patternSize>(ptr, pixel, threshold);
                                break;
                            }
                        }
                        else
                            count = 0;
                    }
                }
            }
        }

        cornerpos[-1] = ncorners;

        if( i == 3 )
            continue;

        const uchar* prev = buf[(i - 4 + 3)%3];
        const uchar* pprev = buf[(i - 5 + 3)%3];
        cornerpos = cpbuf[(i - 4 + 3)%3];
        ncorners = cornerpos[-1];

        for( k = 0; k < ncorners; k++ )
        {
            j = cornerpos[k];
            int score = prev[j];
            if( !nonmax_suppression ||
               (score > prev[j+1] && score > prev[j-1] &&
                score > pprev[j-1] && score > pprev[j] && score > pprev[j+1] &&
                score > curr[j-1] && score > curr[j] && score > curr[j+1]) )
            {
                keypoints.push_back(KeyPoint((float)j, (float)(i-1), 7.f, -1, (float)score));
            }
        }
    }
Пример #23
0
void PointsToKeyPoints(const Points2f& ps, Keypoints& kps) {
    kps.clear();
    for (const auto& p : ps) {
        kps.push_back(KeyPoint(p, 1.0f));
    }
}
Пример #24
0
void DisplayCorrespondence::onNewImage() {
	int wrongmatch_counter=0;
	int goodmatch_counter=0;

	Mat image = in_img.read();
	std::string path = in_path.read();
	std::vector<int> image_params = in_image_params.read();
	std::vector<std::vector<int> > MatchedSourceForTile =in_MatchedSourceForTile.read();
	std::vector<int> PositionOfPatchesInImages =in_PositionOfPatchesInImages.read();
	std::vector<std::vector<int> > MatchedPatchInMatcher =in_MatchedPatchInMatcher.read();
	std::vector<std::vector<double> > DistanceMap = in_DistanceMap.read();
	std::vector<std::string> all_file_paths = in_all_file_paths.read();
	int files_number = all_file_paths.size();
	std::vector<double> QueryMatchMap = in_match_map.read();
	double match_quality = in_match_quality.read();

	patches_cols = image_params[0];
	patches_rows = image_params[1];
	int patchsize = image_params[2];

	int bd_cols = image_params[3];
	int bd_rows = image_params[4];
	int bd_patch_size = image_params[5];

	int queue_size = image_params[6];
	int BestMatchingImage = image_params[7];

	int image_cols = image_params[8];
	int image_rows = image_params[9];
	
	double threshold = (double)image_params[10]/10000;

	std::vector<std::vector<int> > BDMatchMap;
	BDMatchMap.resize(bd_cols * bd_rows);
	//for (int q = 0; q < bd_cols * bd_rows; q++) {
	//	BDMatchMap[q] = -1;
	//}

	int query_col;
	int query_row;
	int fn;

	std::cout << "qs:" << queue_size << "  thre:"<<threshold<<" p:"<<image_params[10]<<std::endl;
	/*=======================================================================*/
	/*************************************************************************/
	/*		create corresspondence map for DB image							 */
	/*************************************************************************/

	if (mode == 3) {
		for (int k = 0; k < patches_rows * patches_cols; k++) {
			int flag = 0;
			int zzz;
			//check if there is match of current patch to the best image
			for (zzz = 0; zzz < queue_size; zzz++) {
				if (DistanceMap[k][zzz]>threshold || DistanceMap[k][zzz]<0){
					//std::cout<<"k:"<<k<<" zzz:"<<zzz<<" dmap"<<DistanceMap[k][zzz]<<"  th:"<<threshold<<std::endl;
					//break;
				}
				if (MatchedSourceForTile[k][zzz] == BestMatchingImage) {
					flag = 1;
					break;
				}
			}
			if (flag) {
				//where in the image is the patch (all patches are numbered linearly in 1D. Like in progressive scan in TV from left to right and to next line)
				fn = PositionOfPatchesInImages[MatchedPatchInMatcher[k][zzz]];
				BDMatchMap[fn].push_back(k);
			}
		}
	}
	
	if (mode==4){
	//!!!!!!!!!!!!!!!!!!!!!!!
	Mat matchedim = cv::imread(path, -1);
	//!!!!!!!!!!!!!!!!!!
		double nx, ny, mx, my;
		
		double angle_rad=M_PI*angle/180;
		
		//scalefactor=1.0;
		int basex=bd_patch_size*bd_cols;
		int basey=bd_patch_size*bd_rows;
		//int imgx=patchsize*patches_cols;
		//int imgy=patchsize*patches_rows;
		int imgx=image_cols;
		int imgy=image_rows;
				
		//circle(matchedim, Point(basex/2.0,basey/2.0), 20, Scalar(0,255,0),-1);
		//circle(image, Point(imgx/2.0,imgy/2.0), 20, Scalar(0,255,0),-1);
		//float px=-100, py=-100;
		
		//float px2=px*scalefactor;
		//float py2=px*scalefactor;
		
		//float qx=px2*cos(angle_rad)-py2*sin(angle_rad);
		//float qy=px2*sin(angle_rad)+py2*cos(angle_rad);
		
		
		
		//std::cout<<qx<<" "<<qy<<std::endl;
		
		//circle(matchedim, Point(basex/2.0+px,basey/2.0+py), 10, Scalar(255,0,0),-1);
		//circle(image, Point(basex/2.0+qx,basey/2.0+qy), 10, Scalar(255,0,0),-1);
				
		for (int k = 0; k < patches_rows * patches_cols; k++) {
					
					
			int flag = 0;
			int zzz;
			//check if there is match of current patch to the best image
			for (zzz = 0; zzz < queue_size; zzz++) {
				if (DistanceMap[k][zzz]>threshold || DistanceMap[k][zzz]<0.0){
					//std::cout<<"k:"<<k<<" zzz:"<<zzz<<" dmap"<<DistanceMap[k][zzz]<<"  th:"<<threshold<<std::endl;
					break;
				}
				if (MatchedSourceForTile[k][zzz] == BestMatchingImage) {
					flag = 1;
					break;
				}
			}
			if (flag) {
			
				fn = PositionOfPatchesInImages[MatchedPatchInMatcher[k][zzz]];
			
				
		
				//float p1x=base_keypoints[matches[i].queryIdx].pt.x-basex/2;
				//float p1y=base_keypoints[matches[i].queryIdx].pt.y-basey/2;
				//float p2x=keypoints[matches[i].trainIdx].pt.x-imgx/2;
				//float p2y=keypoints[matches[i].trainIdx].pt.y-imgy/2;
				
				//cout<<"loop i2: "<<i<<std::endl;
				//float bigx=p1x*(cos(angle_rad)-sin(angle_rad));
				//float bigy=p1y*(sin(angle_rad)+cos(angle_rad));
				
				//float bigx=p1x*cos(angle_rad)-p1y*sin(angle_rad);
				//float bigy=p1x*sin(angle_rad)+p1y*cos(angle_rad);
				
				//cout<<"loop i3: "<<i<<std::endl;
				
				//if (sqrt((bigx-p2x)*(bigx-p2x)+(bigy-p2y)*(bigy-p2y))<=threshold){
					
			
				nx = bd_patch_size * (fn % bd_cols) + bd_patch_size * 0.5;
				ny = bd_patch_size * (fn / bd_cols) + bd_patch_size * 0.5;
				
				//nx*=scalefactor;
				//ny*=scalefactor;
				
				//which tile is matched
				query_col = k % patches_cols;
				query_row = k / patches_cols;

				//location of the center
				mx = patchsize * (query_col) + 0.5 * patchsize;
				my = patchsize * (query_row) + 0.5 * patchsize;
				
				
				float p1x=nx-basex/2.0;
				float p1y=ny-basey/2.0;
				float p2x=mx-imgx/2.0;
				float p2y=my-imgy/2.0;
				
				p1x*=scalefactor;
				p1y*=scalefactor;
				
				//circle(image, Point(mx,my), 10, Scalar(0,0,255), -1);
				//circle(matchedim, Point(nx,ny), 10, Scalar(0,0,255),-1);
				
				
				
				
				float bigx=p1x*cos(angle_rad)-p1y*sin(angle_rad);
				float bigy=p1x*sin(angle_rad)+p1y*cos(angle_rad);	//<<" basex"<<basex<<" basey"<<basey<<" imgx"<<imgx<<" imgy"<<imgy
				//std::cout<<"scale:"<<scalefactor<<std::endl;
				
				if (sqrt((bigx-p2x)*(bigx-p2x)+(bigy-p2y)*(bigy-p2y))<=(sqrt(2)*bd_patch_size*scalefactor/2+3)){
					//where in the image is the patch (all patches are numbered linearly in 1D. Like in progressive scan in TV from left to right and to next line)
					
					//std::cout<<"p1x:"<<p1x<<" p1y:"<<p1y<<" p2x:"<<p2x<<" p2y:"<<p2y<<" bx:"<<bigx<<" by:"<<bigy<<" scale:"<<scalefactor<<std::endl;
				//std::cout<<sqrt((bigx-p2x)*(bigx-p2x)+(bigy-p2y)*(bigy-p2y))<<std::endl;
					
					BDMatchMap[fn].push_back(k);
					goodmatch_counter++;
				}
				else{
					wrongmatch_counter++;
				}
			}
	
		}
		wrongmatches.push_back(wrongmatch_counter);
		goodmatches.push_back(goodmatch_counter);
		similarity.push_back(match_quality);
	}
	/*=======================================================================*/
	/*************************************************************************/
	/*				simple correspondence drawing							 */
	/*************************************************************************/
	
	if (mode == 0) {
		float nx, ny, mx, my;
		Mat outimg;
		//int query_col;
		//int query_row;


		std::vector<cv::KeyPoint> im1kp;
		std::vector<cv::KeyPoint> im2kp;
		std::vector<cv::DMatch> immatches;

		int tempc = 0;

		int cant = 0, cant2 = 0;
		//read query image
		Mat matchedim = cv::imread(path, -1);
		double color;

		for (int k = 0; k < patches_rows * patches_cols; k++) {
			int flag = 0;
			int zzz;
			//check if there is match of current patch to the best image
			for (zzz = 0; zzz < queue_size; zzz++) {
				if (MatchedSourceForTile[k][zzz] == BestMatchingImage) {
					flag = 1;
					//cant++;
					break;
				}
			}
			if (flag) {

				//where in the image is the patch (all patches are numbered linearly in 1D. Like in progressive scan in TV from left to right and to next line)
				fn = PositionOfPatchesInImages[MatchedPatchInMatcher[k][zzz]];
				//BDMatchMap[fn] = k;

				//error?
				if (fn < 0) {
					return;
				}

				//location of the center tile in the image#include <time.h>
				nx = bd_patch_size * (fn % bd_cols) + bd_patch_size * 0.5;
				ny = bd_patch_size * (fn / bd_cols) + bd_patch_size * 0.5;

				//which tile is matched
				query_col = k % patches_cols;
				query_row = k / patches_cols;

				//location of the center
				mx = patchsize * (query_col) + 0.5 * patchsize;
				my = patchsize * (query_row) + 0.5 * patchsize;

				//Is it not a bad match?
				if (DistanceMap[k][0] < 0 || DistanceMap[k][0] > 0.3) {
					cant2++;
					continue;
				}

				//choose colour
				//color = (1 - 10 * DistanceMap[k][0] * DistanceMap[k][0]) * 255.0;
				int cb = 0, cg = 0, cr = 255;
				int qLineW = 2, bdLineW = 2;
				//cb=rand() % 255;
				//cg=rand() % 255;
				//cr=rand() % 255;

				//draw patches in query img
				rectangle(image, Point(mx - 0.5 * patchsize, my - 0.5
						* patchsize), Point(mx + 0.5 * patchsize, my + 0.5
						* patchsize), Scalar(cb, cg, cr), qLineW);

				//draw patches in BD img
				rectangle(matchedim, Point(nx - 0.5 * bd_patch_size, ny - 0.5
						* bd_patch_size), Point(nx + 0.5 * bd_patch_size, ny
						+ 0.5 * bd_patch_size), Scalar(cb, cg, cr), bdLineW);

				//each tile center as a KP
				im1kp.push_back(KeyPoint(Point2f(nx, ny), 5.0));
				im2kp.push_back(KeyPoint(Point2f(mx, my), 5.0));

				std::ostringstream q;
				q.precision(2);
				q << QueryMatchMap[k];

				//putText(image, q.str(), cvPoint(mx-0.25*patchsize,my-0.125*patchsize), FONT_HERSHEY_SIMPLEX, 0.5, cvScalar(0,0,0), 1.5, CV_AA);

				//and now set correspondence
				immatches.push_back(DMatch(tempc, tempc, 0.0));
				tempc++;
			}
		}
		drawMatches(image, im2kp, matchedim, im1kp, immatches, outimg,
				Scalar::all(-1));
		out_image.write(outimg);
	}

	/*=======================================================================*/
	/*************************************************************************/
	/*				corresponding tiles marked with the same color			 */
	/*************************************************************************/
	if (mode == 3 || mode==4) {
		std::cout << "mode:" << mode << " s" << BDMatchMap.size() << std::endl;
		//!!!!!!!!!!!!!!!!!!!
		//!!!!!!!!!!!!!!!!
		//int counter=0;
		Mat matchedim = cv::imread(path, -1);
		float nx, ny, mx, my;
		Mat outimg;
		std::vector<cv::KeyPoint> im1kp;
		std::vector<cv::KeyPoint> im2kp;
		std::vector<cv::DMatch> immatches;

		int k;
		for (int m = 0; m < BDMatchMap.size(); m++) {
			int cb = 0, cg = 0, cr = 255;
			int qLineW = -1, bdLineW = -1;
			cb = rand() % 255;
			cg = rand() % 255;
			cr = rand() % 255;
			if (BDMatchMap[m].size() > 0) {
				for (int n = 0; n < BDMatchMap[m].size(); n++) {
				
				
					k = BDMatchMap[m][n];
					fn = n;

					query_col = k % patches_cols;
					query_row = k / patches_cols;

					//std::cout<<query_col<<" "<<query_row<<" "<<k<<std::endl;

					//location of the center
					mx = patchsize * (query_col) + 0.5 * patchsize;
					my = patchsize * (query_row) + 0.5 * patchsize;

					//Is it not a bad match?
					if (DistanceMap[k][0] < 0.0 || DistanceMap[k][0] > threshold) {
						continue;
					}
					//counter++;
					//draw patches in query img
					rectangle(image, Point(mx - 0.5 * patchsize, my - 0.5
							* patchsize), Point(mx + 0.5 * patchsize, my + 0.5
							* patchsize), Scalar(cb, cg, cr), qLineW);
							
					std::ostringstream q;
					q.precision(2);
					q << QueryMatchMap[k];
					putText(image, q.str(), cvPoint(mx-0.25*patchsize,my-0.125*patchsize), FONT_HERSHEY_SIMPLEX, 0.3, cvScalar(0,0,0), 1.5, CV_AA);
							
				}

				nx = bd_patch_size * (m % bd_cols) + bd_patch_size * 0.5;
				ny = bd_patch_size * (m / bd_cols) + bd_patch_size * 0.5;

				//draw patches in BD img
				rectangle(matchedim, Point(nx - 0.5 * bd_patch_size, ny - 0.5
						* bd_patch_size), Point(nx + 0.5 * bd_patch_size, ny
						+ 0.5 * bd_patch_size), Scalar(cb, cg, cr), bdLineW);
			}
		}
		drawMatches(image, im2kp, matchedim, im1kp, immatches, outimg,
				Scalar::all(-1));

		out_image.write(outimg);
		//goodmatches_q.push_back(counter);
	}

	/*=======================================================================*/
	/*************************************************************************/
	/*			experimental mode to reconstruct image from matched patches	 */
	/*						  possible only when patches have the same size  */
	/*************************************************************************/
	//
	if ((mode == 1 && patchsize == bd_patch_size) || mode == 2) {

		int nx, ny, mx, my;
		//int fn;
		//int query_col;
		//int query_row;

		int ax, bx, ay, by;
		int fx;
		int r, g, b;
		Mat outimage(image_rows, image_cols, CV_8UC3,
				Scalar(0.0, 0.0, 0.0, 1.0));

		int counter = 0;
		int zzz = 0, flag = 0;

		//scan through all the files
		for (int l = 0; l < files_number; l++) {

			Mat matchedim = cv::imread(all_file_paths[l], -1);
			unsigned char *input = (unsigned char*) (matchedim.data);

			for (int k = 0; k < patches_rows * patches_cols; k++) {
				//matches only to the best image
				if (mode == 1) {
					flag = 0;
					//find if an image has some corresponging match on the list
					for (zzz = 0; zzz < queue_size; zzz++) {
						if (MatchedSourceForTile[k][zzz] == BestMatchingImage) {
							flag = 1;
							break;
						}
					}
				}
				//matches to all img in the DB
				if (flag || mode == 2) {

					query_col = k % patches_cols;
					query_row = k / patches_cols;
					mx = patchsize * (query_col);
					my = patchsize * (query_row);

					fn
							= PositionOfPatchesInImages[MatchedPatchInMatcher[k][zzz]];

					nx = bd_patch_size * (fn % bd_cols);
					ny = bd_patch_size * (fn / bd_cols);

					//if the tile is matched to the current image l
					if (MatchedSourceForTile[k][zzz] == l) {

						//then copy image pixel-by-pixel
						for (int ax = 0; ax < patchsize; ax++) {
							for (int ay = 0; ay < patchsize; ay++) {
								//outimage[mx+ax][mx+ay]=matchedim[nx+ax][nx+ay];
								//if ((ax+nx)>512||(ay+ny))
								b = matchedim.data[matchedim.step[0]
										* (ay + ny) + matchedim.step[1] * (ax
										+ nx)];
								g = matchedim.data[matchedim.step[0]
										* (ay + ny) + matchedim.step[1] * (ax
										+ nx) + 1];
								r = matchedim.data[matchedim.step[0]
										* (ay + ny) + matchedim.step[1] * (ax
										+ nx) + 2];

								outimage.data[outimage.step[0] * (my + ay)
										+ outimage.step[1] * (mx + ax) + 0] = b;
								outimage.data[outimage.step[0] * (my + ay)
										+ outimage.step[1] * (mx + ax) + 1] = g;
								outimage.data[outimage.step[0] * (my + ay)
										+ outimage.step[1] * (mx + ax) + 2] = r;

							}
						}
					}
				}
			}
		}

		std::cout << "done" << std::endl;
		out_image.write(outimage);
	}
	/*************************************************************************/

	std::cout << "raise" << std::endl;
	matched->raise();
}
Пример #25
0
int test_multitypestorage()
{
	// init some variables:
	Mat a(10,10,CV_32F, Scalar(0.3));
	Mat b(20,20,CV_32F, Scalar(1.));
	Mat c(10,10,CV_32FC3, Scalar(120.));

	double v(9.);
	double w(19.);

	vector<KeyPoint> kp, kp1;
	kp.push_back(KeyPoint(1.0,-1.0,20));
	kp.push_back(KeyPoint(2.0,21.0,10));

	kp1.push_back(KeyPoint(11.0,-1.0,20));
	kp1.push_back(KeyPoint(2.0,1.0,10));


	vector<vector<DMatch> > m;
	vector<DMatch> _m, _n; 
	_m.push_back(DMatch(1,2,10.)); 
	_m.push_back(DMatch(3,4,4.)); 
	_n.push_back(DMatch(6,2,1.)); 
	_n.push_back(DMatch(5,4,41.)); 
	m.push_back(_m);
	m.push_back(_n);
		

	
	// 0-test:
	//cerr << "test_compare(1,2) = " << test_compare(1,2) << " = 0 (false) " << endl;
	//cerr << "test_compare(1.,1.) = " << test_compare(1.,1.) << " = 1 (true) " << endl;
	//cerr << "test_compare(a,a) = " << test_compare(a,a) << " = 1 " << endl;
	//cerr << "test_compare(a,b) = " << test_compare(a,b) << " = 0 "<< endl;
	//cerr << "test_compare(c,c) = " << test_compare(c,c) << " = 1 "<< endl;
	//cerr << "test_compare(a,c) = " << test_compare(a,c) << " = 0 "<< endl;
	//cerr << "test_compare(v,v) = " << test_compare(v,v) << " = 1 "<< endl;
	//cerr << "test_compare(v,w) = " << test_compare(v,w) << " = 0 "<< endl;
	//cerr << "test_compare(kp,kp) = " << test_compare<KeyPoint>(kp,kp) << " = 1 "<< endl;
	//cerr << "test_compare(kp,kp1) = " << test_compare<KeyPoint>(kp,kp1) << " = 0 "<< endl;
	//cerr << "test_compare(m,m) = " << test_compare<vector<DMatch> >(m,m) << " = 1 "<< endl;
	//cerr << "test_compare(_m,_n) = " << test_compare<DMatch>(_m,_n) << " = 0 "<< endl;


	// init MTStorage:
	MultiTypeStorage storage;	

	// add elements:
	storage.setElement<Mat>("a", a);
	storage.setElement<Mat>("b", b);
	storage.setElement<Mat>("c", c);
	storage.setElement<double>("v", v);
	storage.setElement<double>("w", w);
	storage.setElement<vector<KeyPoint> >("kp", kp);
	storage.setElement<vector<vector<DMatch> > >("m", m);


	// get elements:
	Mat A;
	if (storage.getElement<Mat>("a") != NULL) 
		A = *(storage.getElement<Mat>("a"));
	else{
		cerr << "a is not found !" << endl;
		return -1;
	}

	Mat B; 
	if (storage.getElement<Mat>("b")!=NULL)
		B = *(storage.getElement<Mat>("b"));
	else{
		cerr << "b is not found !" << endl;
		return -1;
	}

	Mat C = *(storage.getElement<Mat>("c"));

	double V = *(storage.getElement<double>("v"));
	double W = *(storage.getElement<double>("w"));
	vector<KeyPoint> KP = *(storage.getElement<vector<KeyPoint> >("kp"));
	vector<vector<DMatch> > M = *(storage.getElement<vector<vector<DMatch> > >("m"));

	// compare:
	int s1 = test_compare(A,a) + test_compare(B,b) + test_compare(C,c) + test_compare(V,v) + test_compare(W,w) + test_compare(KP,kp) + test_compare(M,m);
	if (s1 == 7)
		cerr << "test OK" << endl;
	else
		cerr << "test failed" << endl;


}
Пример #26
0
void FAST_t(InputArray _img, std::vector<KeyPoint>& keypoints, int threshold, bool nonmax_suppression)
{
    Mat img = _img.getMat();
    const int K = patternSize/2, N = patternSize + K + 1;
    int i, j, k, pixel[25];
    makeOffsets(pixel, (int)img.step, patternSize);

#if CV_SIMD128
    const int quarterPatternSize = patternSize/4;
    v_uint8x16 delta = v_setall_u8(0x80), t = v_setall_u8((char)threshold), K16 = v_setall_u8((char)K);
    bool hasSimd = hasSIMD128();
#if CV_TRY_AVX2
    Ptr<opt_AVX2::FAST_t_patternSize16_AVX2> fast_t_impl_avx2;
    if(CV_CPU_HAS_SUPPORT_AVX2)
        fast_t_impl_avx2 = opt_AVX2::FAST_t_patternSize16_AVX2::getImpl(img.cols, threshold, nonmax_suppression, pixel);
#endif

#endif

    keypoints.clear();

    threshold = std::min(std::max(threshold, 0), 255);

    uchar threshold_tab[512];
    for( i = -255; i <= 255; i++ )
        threshold_tab[i+255] = (uchar)(i < -threshold ? 1 : i > threshold ? 2 : 0);

    AutoBuffer<uchar> _buf((img.cols+16)*3*(sizeof(int) + sizeof(uchar)) + 128);
    uchar* buf[3];
    buf[0] = _buf.data(); buf[1] = buf[0] + img.cols; buf[2] = buf[1] + img.cols;
    int* cpbuf[3];
    cpbuf[0] = (int*)alignPtr(buf[2] + img.cols, sizeof(int)) + 1;
    cpbuf[1] = cpbuf[0] + img.cols + 1;
    cpbuf[2] = cpbuf[1] + img.cols + 1;
    memset(buf[0], 0, img.cols*3);

    for(i = 3; i < img.rows-2; i++)
    {
        const uchar* ptr = img.ptr<uchar>(i) + 3;
        uchar* curr = buf[(i - 3)%3];
        int* cornerpos = cpbuf[(i - 3)%3];
        memset(curr, 0, img.cols);
        int ncorners = 0;

        if( i < img.rows - 3 )
        {
            j = 3;
#if CV_SIMD128
            if( hasSimd )
            {
                if( patternSize == 16 )
                {
#if CV_TRY_AVX2
                    if (fast_t_impl_avx2)
                        fast_t_impl_avx2->process(j, ptr, curr, cornerpos, ncorners);
#endif
                    //vz if (j <= (img.cols - 27)) //it doesn't make sense using vectors for less than 8 elements
                    {
                        for (; j < img.cols - 16 - 3; j += 16, ptr += 16)
                        {
                            v_uint8x16 v = v_load(ptr);
                            v_int8x16 v0 = v_reinterpret_as_s8((v + t) ^ delta);
                            v_int8x16 v1 = v_reinterpret_as_s8((v - t) ^ delta);

                            v_int8x16 x0 = v_reinterpret_as_s8(v_sub_wrap(v_load(ptr + pixel[0]), delta));
                            v_int8x16 x1 = v_reinterpret_as_s8(v_sub_wrap(v_load(ptr + pixel[quarterPatternSize]), delta));
                            v_int8x16 x2 = v_reinterpret_as_s8(v_sub_wrap(v_load(ptr + pixel[2*quarterPatternSize]), delta));
                            v_int8x16 x3 = v_reinterpret_as_s8(v_sub_wrap(v_load(ptr + pixel[3*quarterPatternSize]), delta));

                            v_int8x16 m0, m1;
                            m0 = (v0 < x0) & (v0 < x1);
                            m1 = (x0 < v1) & (x1 < v1);
                            m0 = m0 | ((v0 < x1) & (v0 < x2));
                            m1 = m1 | ((x1 < v1) & (x2 < v1));
                            m0 = m0 | ((v0 < x2) & (v0 < x3));
                            m1 = m1 | ((x2 < v1) & (x3 < v1));
                            m0 = m0 | ((v0 < x3) & (v0 < x0));
                            m1 = m1 | ((x3 < v1) & (x0 < v1));
                            m0 = m0 | m1;

                            int mask = v_signmask(m0);
                            if( mask == 0 )
                                continue;
                            if( (mask & 255) == 0 )
                            {
                                j -= 8;
                                ptr -= 8;
                                continue;
                            }

                            v_int8x16 c0 = v_setzero_s8();
                            v_int8x16 c1 = v_setzero_s8();
                            v_uint8x16 max0 = v_setzero_u8();
                            v_uint8x16 max1 = v_setzero_u8();
                            for( k = 0; k < N; k++ )
                            {
                                v_int8x16 x = v_reinterpret_as_s8(v_load((ptr + pixel[k])) ^ delta);
                                m0 = v0 < x;
                                m1 = x < v1;

                                c0 = v_sub_wrap(c0, m0) & m0;
                                c1 = v_sub_wrap(c1, m1) & m1;

                                max0 = v_max(max0, v_reinterpret_as_u8(c0));
                                max1 = v_max(max1, v_reinterpret_as_u8(c1));
                            }

                            max0 = v_max(max0, max1);
                            int m = v_signmask(K16 < max0);

                            for( k = 0; m > 0 && k < 16; k++, m >>= 1 )
                            {
                                if(m & 1)
                                {
                                    cornerpos[ncorners++] = j+k;
                                    if(nonmax_suppression)
                                        curr[j+k] = (uchar)cornerScore<patternSize>(ptr+k, pixel, threshold);
                                }
                            }
                        }
                    }
                }
            }
#endif
            for( ; j < img.cols - 3; j++, ptr++ )
            {
                int v = ptr[0];
                const uchar* tab = &threshold_tab[0] - v + 255;
                int d = tab[ptr[pixel[0]]] | tab[ptr[pixel[8]]];

                if( d == 0 )
                    continue;

                d &= tab[ptr[pixel[2]]] | tab[ptr[pixel[10]]];
                d &= tab[ptr[pixel[4]]] | tab[ptr[pixel[12]]];
                d &= tab[ptr[pixel[6]]] | tab[ptr[pixel[14]]];

                if( d == 0 )
                    continue;

                d &= tab[ptr[pixel[1]]] | tab[ptr[pixel[9]]];
                d &= tab[ptr[pixel[3]]] | tab[ptr[pixel[11]]];
                d &= tab[ptr[pixel[5]]] | tab[ptr[pixel[13]]];
                d &= tab[ptr[pixel[7]]] | tab[ptr[pixel[15]]];

                if( d & 1 )
                {
                    int vt = v - threshold, count = 0;

                    for( k = 0; k < N; k++ )
                    {
                        int x = ptr[pixel[k]];
                        if(x < vt)
                        {
                            if( ++count > K )
                            {
                                cornerpos[ncorners++] = j;
                                if(nonmax_suppression)
                                    curr[j] = (uchar)cornerScore<patternSize>(ptr, pixel, threshold);
                                break;
                            }
                        }
                        else
                            count = 0;
                    }
                }

                if( d & 2 )
                {
                    int vt = v + threshold, count = 0;

                    for( k = 0; k < N; k++ )
                    {
                        int x = ptr[pixel[k]];
                        if(x > vt)
                        {
                            if( ++count > K )
                            {
                                cornerpos[ncorners++] = j;
                                if(nonmax_suppression)
                                    curr[j] = (uchar)cornerScore<patternSize>(ptr, pixel, threshold);
                                break;
                            }
                        }
                        else
                            count = 0;
                    }
                }
            }
        }

        cornerpos[-1] = ncorners;

        if( i == 3 )
            continue;

        const uchar* prev = buf[(i - 4 + 3)%3];
        const uchar* pprev = buf[(i - 5 + 3)%3];
        cornerpos = cpbuf[(i - 4 + 3)%3];
        ncorners = cornerpos[-1];

        for( k = 0; k < ncorners; k++ )
        {
            j = cornerpos[k];
            int score = prev[j];
            if( !nonmax_suppression ||
               (score > prev[j+1] && score > prev[j-1] &&
                score > pprev[j-1] && score > pprev[j] && score > pprev[j+1] &&
                score > curr[j-1] && score > curr[j] && score > curr[j+1]) )
            {
                keypoints.push_back(KeyPoint((float)j, (float)(i-1), 7.f, -1, (float)score));
            }
        }
    }