// 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); }
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)); }
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)); }
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; }
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 ); }
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)); } }
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); }
//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)); } }
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); } }
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); } }
/** * 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)); } }
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)); }
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; }
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 ); }
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; }
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)); } } }
void PointsToKeyPoints(const Points2f& ps, Keypoints& kps) { kps.clear(); for (const auto& p : ps) { kps.push_back(KeyPoint(p, 1.0f)); } }
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(); }
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; }
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)); } } }