/*! @brief visualize the candidate part locations overlaid on an image * * @param im the image * @param candidates a vector of type Candidate, representing potential * part locations * @param N the number of candidates to render. If the candidates have been sorted, * this is equivalent to displaying only the 'N best' candidates * @param display_confidence display the detection confidence above each bounding box * for each part */ void Visualize::candidates(const Mat& im, const vectorCandidate& candidates, unsigned int N, Mat& canvas, bool display_confidence) const { // create a new canvas that we can modify cvtColor(im, canvas, CV_RGB2BGR); // generate a set of colors to display. Do this in HSV then convert it const unsigned int ncolors = candidates[0].parts().size(); vector<Scalar> colors; for (unsigned int n = 0; n < ncolors; ++n) { Mat color(Size(1,1), CV_32FC3); // Hue is in degrees, not radians (because consistency is over-rated) color.at<float>(0) = (360) / ncolors * n; color.at<float>(1) = 1.0; color.at<float>(2) = 0.7; cvtColor(color, color, CV_HSV2BGR); color = color * 255; colors.push_back(Scalar(color.at<float>(0), color.at<float>(1), color.at<float>(2))); } // draw each candidate to the canvas const int LINE_THICKNESS = 3; Scalar black(0,0,0); N = (candidates.size() < N) ? candidates.size() : N; for (unsigned int n = 0; n < N; ++n) { Candidate candidate = candidates[n]; for (unsigned int p = 0; p < candidate.parts().size(); ++p) { Rect box = candidate.parts()[p]; string confidence = boost::lexical_cast<string>(candidate.confidence()[p]); rectangle(canvas, box, colors[p], LINE_THICKNESS); if (display_confidence && p == 0) putText(canvas, confidence, Point(box.x, box.y-5), FONT_HERSHEY_SIMPLEX, 0.5f, black, 2); } rectangle(canvas, candidate.boundingBox(), Scalar(255, 0, 0), LINE_THICKNESS); } }