Update the object tracker according to frame returns true if KLT succeeded, false otherwise
| 170 | // Update the object tracker according to frame |
| 171 | // returns true if KLT succeeded, false otherwise |
| 172 | bool CVTracker::trackFrame(cv::Mat &frame, size_t frameId) |
| 173 | { |
| 174 | const int W = frame.cols, H = frame.rows; |
| 175 | const auto& prev = trackedDataById[frameId - 1]; |
| 176 | |
| 177 | // Reconstruct last-known box in pixel coords |
| 178 | cv::Rect2d lastBox( |
| 179 | prev.x1 * W, prev.y1 * H, |
| 180 | (prev.x2 - prev.x1) * W, |
| 181 | (prev.y2 - prev.y1) * H |
| 182 | ); |
| 183 | |
| 184 | // Convert to grayscale |
| 185 | cv::Mat gray; |
| 186 | cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY); |
| 187 | |
| 188 | const bool prevGrayMatches = |
| 189 | !prevGray.empty() && |
| 190 | prevGray.size() == gray.size() && |
| 191 | prevGray.type() == gray.type(); |
| 192 | const bool fullPrevGrayMatches = |
| 193 | !fullPrevGray.empty() && |
| 194 | fullPrevGray.size() == gray.size() && |
| 195 | fullPrevGray.type() == gray.type(); |
| 196 | |
| 197 | if (!prevGray.empty() && !prevGrayMatches) { |
| 198 | prevPts.clear(); |
| 199 | lostCount = 0; |
| 200 | } |
| 201 | |
| 202 | cv::Rect2d cand; |
| 203 | bool didKLT = false; |
| 204 | |
| 205 | // Try KLT-based drift |
| 206 | if (prevGrayMatches && !prevPts.empty()) { |
| 207 | std::vector<cv::Point2f> currPts; |
| 208 | std::vector<uchar> status; |
| 209 | std::vector<float> err; |
| 210 | cv::calcOpticalFlowPyrLK( |
| 211 | prevGray, gray, |
| 212 | prevPts, currPts, |
| 213 | status, err, |
| 214 | cv::Size(21,21), 3, |
| 215 | cv::TermCriteria{cv::TermCriteria::COUNT|cv::TermCriteria::EPS,30,0.01}, |
| 216 | cv::OPTFLOW_LK_GET_MIN_EIGENVALS, 1e-4 |
| 217 | ); |
| 218 | |
| 219 | // collect per-point displacements |
| 220 | std::vector<double> dx, dy; |
| 221 | for (size_t i = 0; i < status.size(); ++i) { |
| 222 | if (status[i] && err[i] < 12.0) { |
| 223 | dx.push_back(currPts[i].x - prevPts[i].x); |
| 224 | dy.push_back(currPts[i].y - prevPts[i].y); |
| 225 | } |
| 226 | } |
| 227 | |
| 228 | if ((int)dx.size() >= minKltPts) { |
| 229 | auto median = [&](auto &v){ |
no test coverage detected