diff --git a/include/ball_tracking/img_proc.hpp b/include/ball_tracking/img_proc.hpp index 5f42941593d6f6cc43c1038f0c0487dca23c5799..a0de07abbb7bbd5d0f84a0531bc1036619a152bf 100644 --- a/include/ball_tracking/img_proc.hpp +++ b/include/ball_tracking/img_proc.hpp @@ -22,6 +22,19 @@ namespace ball_tracking { */ cv::Mat map_channel_quad(cv::InputArray src, cv::InputArray mean, cv::InputArray S); + /** + * @brief Applies a pixel-wise logistic regression with quadratic features to the source + * image and returns a single-channel image with the log-probabilities + * + * @param[in] src The source image + * @param[in] bkg A background image (Without the ball) + * @param[in] weights Vector of weights of logistic regression + * + * @returns a new image where every pixel corresponds to the log-probability of the + * pixel being a ball according to the trained classifier + */ + cv::Mat quadf_log_reg(cv::InputArray src, cv::InputArray bkg, cv::InputArray weights); + /** * @brief Produces a single channel image highlighting the possible position of the ball diff --git a/src/img_proc.cpp b/src/img_proc.cpp index 5d73ed6ca1ac595cf4091882b753a7077421a047..b7a6d32cf7654e4d3c3b2cb1d807795a878e9a76 100644 --- a/src/img_proc.cpp +++ b/src/img_proc.cpp @@ -34,4 +34,31 @@ namespace ball_tracking { return ans; } + cv::Mat quadf_log_reg(cv::InputArray _src, cv::InputArray _bkg, cv::InputArray _weights) { + Mat src = _src.getMat(), bkg = _bkg.getMat(), tmp_weight = _weights.getMat(); + const unsigned int channels = src.channels(); + CV_Assert(channels == 3); + CV_Assert(src.rows == bkg.rows && src.cols == bkg.cols); + double w[28]; + copy(tmp_weight.begin<double>(), tmp_weight.end<double>(), w); + + Mat ans(src.rows, src.cols, CV_64FC1); + MatIterator_<Vec3b> it=src.begin<Vec3b>(), end=src.end<Vec3b>(); + MatIterator_<Vec3b> it_bkg=bkg.begin<Vec3b>(); + MatIterator_<double> it_ans = ans.begin<double>(); + for (; it != end; it++, it_ans++, it_bkg++) { + double sum = 0.0; + double lfeat[7] = {(*it)[0]/255.0, (*it)[1]/255.0, (*it)[2]/255.0, + (*it_bkg)[0]/255.0, (*it_bkg)[1]/255.0, (*it_bkg)[2]/255.0, 1.0}; + double* wptr = w; + for (unsigned int i=0; i<7; i++) { + for (unsigned int j=i; j<channels; j++, wptr++) { + sum += (*wptr) * lfeat[i] * lfeat[j]; + } + } + *it_ans = sum; + } + return ans; + } + };