std::map<int, chilitags::Quad> chilitags::Track::operator()( const cv::Mat &inputImage) { mEnsureGreyscale(mToImage).copyTo(mFromImage); mToImage = mEnsureGreyscale(inputImage); std::vector<uchar> status; std::vector<float> errors; std::map<int, chilitags::Quad> trackedTags; for (auto tag : mFromTags) { chilitags::Quad result; static const float GROWTH_RATIO = 20.f/10.f; cv::Rect roi = growRoi(mToImage, cv::Mat_<cv::Point2f>(tag.second), GROWTH_RATIO); cv::Point2f roiOffset = roi.tl(); for (int i : {0,1,2,3}) { tag.second(i,0) -= roiOffset.x; tag.second(i,1) -= roiOffset.y; } cv::calcOpticalFlowPyrLK( mFromImage(roi), mToImage(roi), tag.second, result, status, errors, //TODO play with parameters (with tests) cv::Size(21,21), 3, cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 30, 0.01) ); for (int i : {0,1,2,3}) { result(i,0) += roiOffset.x; result(i,1) += roiOffset.y; } if (cv::sum(cv::Mat(status))[0] == status.size()) { trackedTags[tag.first] = mRefine(mToImage, result, .5/10.); } } mFromTags = std::move(trackedTags); return mFromTags; }
std::map<int, Quad> find(const cv::Mat &inputImage){ auto greyscaleImage = mEnsureGreyscale(inputImage); std::map<int, Quad> tags; for (const auto & quad : mFindQuads(greyscaleImage)) { auto refinedQuad = mRefine(greyscaleImage, quad); auto tag = mDecode(mReadBits(greyscaleImage, refinedQuad), refinedQuad); if (tag.first != Decode::INVALID_TAG) tags[tag.first] = tag.second; else { tag = mDecode(mReadBits(greyscaleImage, quad), quad); if (tag.first != Decode::INVALID_TAG) tags[tag.first] = tag.second; } } return mFilter(tags); };