void cv::gpu::BruteForceMatcher_GPU_base::makeGpuCollection(GpuMat& trainCollection, GpuMat& maskCollection, const vector<GpuMat>& masks) { if (empty()) return; if (masks.empty()) { Mat trainCollectionCPU(1, static_cast<int>(trainDescCollection.size()), CV_8UC(sizeof(DevMem2Db))); DevMem2Db* trainCollectionCPU_ptr = trainCollectionCPU.ptr<DevMem2Db>(); for (size_t i = 0, size = trainDescCollection.size(); i < size; ++i, ++trainCollectionCPU_ptr) *trainCollectionCPU_ptr = trainDescCollection[i]; trainCollection.upload(trainCollectionCPU); maskCollection.release(); } else { CV_Assert(masks.size() == trainDescCollection.size()); Mat trainCollectionCPU(1, static_cast<int>(trainDescCollection.size()), CV_8UC(sizeof(DevMem2Db))); Mat maskCollectionCPU(1, static_cast<int>(trainDescCollection.size()), CV_8UC(sizeof(PtrStepb))); DevMem2Db* trainCollectionCPU_ptr = trainCollectionCPU.ptr<DevMem2Db>(); PtrStepb* maskCollectionCPU_ptr = maskCollectionCPU.ptr<PtrStepb>(); for (size_t i = 0, size = trainDescCollection.size(); i < size; ++i, ++trainCollectionCPU_ptr, ++maskCollectionCPU_ptr) { const GpuMat& train = trainDescCollection[i]; const GpuMat& mask = masks[i]; CV_Assert(mask.empty() || (mask.type() == CV_8UC1 && mask.cols == train.rows)); *trainCollectionCPU_ptr = train; *maskCollectionCPU_ptr = mask; } trainCollection.upload(trainCollectionCPU); maskCollection.upload(maskCollectionCPU); } }
void cv::gpu::ORB_GPU::mergeKeyPoints(GpuMat& keypoints) { using namespace cv::gpu::device::orb; int nAllkeypoints = 0; for (int level = 0; level < nLevels_; ++level) nAllkeypoints += keyPointsCount_[level]; if (nAllkeypoints == 0) { keypoints.release(); return; } 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]); 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)); offset += keyPointsCount_[level]; } }
void cv::gpu::ORB_GPU::computeDescriptors(GpuMat& descriptors) { using namespace cv::gpu::device::orb; int nAllkeypoints = 0; for (int level = 0; level < nLevels_; ++level) nAllkeypoints += keyPointsCount_[level]; if (nAllkeypoints == 0) { descriptors.release(); return; } ensureSizeIsEnough(nAllkeypoints, descriptorSize(), CV_8UC1, 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) { // preprocess the resized image ensureSizeIsEnough(imagePyr_[level].size(), imagePyr_[level].type(), buf_); 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), keyPointsCount_[level], pattern_.ptr<int>(0), pattern_.ptr<int>(1), descRange, descriptorSize(), WTA_K_, 0); offset += keyPointsCount_[level]; } }
//cuda version void LKTracker::normCrossCorrelation(const GpuMat& img1, const GpuMat& img2, const GpuMat& gPoints1, const GpuMat& gPoints2, const vector<Point2f>& points1, const vector<Point2f> points2) { GpuMat res; GpuMat rec0; GpuMat rec1; similarity.clear(); for (int i = 0; i < points1.size(); i++) { if (status[i] == 1) { Rect loc0(points1[i].x, points1[i].y, 10, 10); Rect loc1(points2[i].x, points2[i].y, 10, 10); rec0 = GpuMat(img1, loc0); rec1 = GpuMat(img2, loc1); gpu::matchTemplate(rec0, rec1, res, CV_TM_CCOEFF_NORMED); similarity.push_back(((float *)(res.data))[0]); } else { similarity.push_back(0.0); } } rec0.release(); rec1.release(); res.release(); }
void cv::gpu::GoodFeaturesToTrackDetector_GPU::operator ()(const GpuMat& image, GpuMat& corners, const GpuMat& mask) { using namespace cv::gpu::device::gfft; CV_Assert(qualityLevel > 0 && minDistance >= 0 && maxCorners >= 0); CV_Assert(mask.empty() || (mask.type() == CV_8UC1 && mask.size() == image.size())); ensureSizeIsEnough(image.size(), CV_32F, eig_); if (useHarrisDetector) cornerHarris(image, eig_, Dx_, Dy_, buf_, blockSize, 3, harrisK); else cornerMinEigenVal(image, eig_, Dx_, Dy_, buf_, blockSize, 3); double maxVal = 0; minMax(eig_, 0, &maxVal, GpuMat(), minMaxbuf_); ensureSizeIsEnough(1, std::max(1000, static_cast<int>(image.size().area() * 0.05)), CV_32FC2, tmpCorners_); int total = findCorners_gpu(eig_, static_cast<float>(maxVal * qualityLevel), mask, tmpCorners_.ptr<float2>(), tmpCorners_.cols); if (total == 0) { corners.release(); return; } sortCorners_gpu(eig_, tmpCorners_.ptr<float2>(), total); if (minDistance < 1) tmpCorners_.colRange(0, maxCorners > 0 ? std::min(maxCorners, total) : total).copyTo(corners); else { vector<Point2f> tmp(total); Mat tmpMat(1, total, CV_32FC2, (void*)&tmp[0]); tmpCorners_.colRange(0, total).download(tmpMat); vector<Point2f> tmp2; tmp2.reserve(total); const int cell_size = cvRound(minDistance); const int grid_width = (image.cols + cell_size - 1) / cell_size; const int grid_height = (image.rows + cell_size - 1) / cell_size; std::vector< std::vector<Point2f> > grid(grid_width * grid_height); for (int i = 0; i < total; ++i) { Point2f p = tmp[i]; bool good = true; int x_cell = static_cast<int>(p.x / cell_size); int y_cell = static_cast<int>(p.y / cell_size); int x1 = x_cell - 1; int y1 = y_cell - 1; int x2 = x_cell + 1; int y2 = y_cell + 1; // boundary check x1 = std::max(0, x1); y1 = std::max(0, y1); x2 = std::min(grid_width - 1, x2); y2 = std::min(grid_height - 1, y2); for (int yy = y1; yy <= y2; yy++) { for (int xx = x1; xx <= x2; xx++) { vector<Point2f>& m = grid[yy * grid_width + xx]; if (!m.empty()) { for(size_t j = 0; j < m.size(); j++) { float dx = p.x - m[j].x; float dy = p.y - m[j].y; if (dx * dx + dy * dy < minDistance * minDistance) { good = false; goto break_out; } } } } } break_out: if(good) { grid[y_cell * grid_width + x_cell].push_back(p); tmp2.push_back(p); if (maxCorners > 0 && tmp2.size() == static_cast<size_t>(maxCorners)) break; } } corners.upload(Mat(1, static_cast<int>(tmp2.size()), CV_32FC2, &tmp2[0])); } }
void cv::gpu::PyrLKOpticalFlow::sparse(const GpuMat& prevImg, const GpuMat& nextImg, const GpuMat& prevPts, GpuMat& nextPts, GpuMat& status, GpuMat* err) { using namespace cv::gpu::device::pyrlk; if (prevPts.empty()) { nextPts.release(); status.release(); if (err) err->release(); return; } dim3 block, patch; calcPatchSize(winSize, block, patch, isDeviceArch11_); CV_Assert(prevImg.type() == CV_8UC1 || prevImg.type() == CV_8UC3 || prevImg.type() == CV_8UC4); CV_Assert(prevImg.size() == nextImg.size() && prevImg.type() == nextImg.type()); CV_Assert(maxLevel >= 0); CV_Assert(winSize.width > 2 && winSize.height > 2); CV_Assert(patch.x > 0 && patch.x < 6 && patch.y > 0 && patch.y < 6); CV_Assert(prevPts.rows == 1 && prevPts.type() == CV_32FC2); if (useInitialFlow) CV_Assert(nextPts.size() == prevPts.size() && nextPts.type() == CV_32FC2); else ensureSizeIsEnough(1, prevPts.cols, prevPts.type(), nextPts); GpuMat temp1 = (useInitialFlow ? nextPts : prevPts).reshape(1); GpuMat temp2 = nextPts.reshape(1); multiply(temp1, Scalar::all(1.0 / (1 << maxLevel) / 2.0), temp2); ensureSizeIsEnough(1, prevPts.cols, CV_8UC1, status); status.setTo(Scalar::all(1)); if (err) ensureSizeIsEnough(1, prevPts.cols, CV_32FC1, *err); // build the image pyramids. prevPyr_.resize(maxLevel + 1); nextPyr_.resize(maxLevel + 1); int cn = prevImg.channels(); if (cn == 1 || cn == 4) { prevImg.convertTo(prevPyr_[0], CV_32F); nextImg.convertTo(nextPyr_[0], CV_32F); } else { cvtColor(prevImg, dx_calcBuf_, COLOR_BGR2BGRA); dx_calcBuf_.convertTo(prevPyr_[0], CV_32F); cvtColor(nextImg, dx_calcBuf_, COLOR_BGR2BGRA); dx_calcBuf_.convertTo(nextPyr_[0], CV_32F); } for (int level = 1; level <= maxLevel; ++level) { pyrDown(prevPyr_[level - 1], prevPyr_[level]); pyrDown(nextPyr_[level - 1], nextPyr_[level]); } loadConstants(make_int2(winSize.width, winSize.height), iters); for (int level = maxLevel; level >= 0; level--) { if (cn == 1) { lkSparse1_gpu(prevPyr_[level], nextPyr_[level], prevPts.ptr<float2>(), nextPts.ptr<float2>(), status.ptr(), level == 0 && err ? err->ptr<float>() : 0, prevPts.cols, level, block, patch); } else { lkSparse4_gpu(prevPyr_[level], nextPyr_[level], prevPts.ptr<float2>(), nextPts.ptr<float2>(), status.ptr(), level == 0 && err ? err->ptr<float>() : 0, prevPts.cols, level, block, patch); } } }