void GridFitter::visualizeDebug(std::multiset<candidate_t> const& grids, const cv::Mat& roi, const cv::Size2i roiSize, const cv::Mat& edgeRoiX, const cv::Mat& edgeRoiY, const Tag &tag, cv::Mat const& binarizedROI, std::string winName, const size_t numBest)
{
	cv::Mat binarizedROICpy;
	cv::cvtColor(binarizedROI, binarizedROICpy, CV_GRAY2BGR);

	cv::Mat edgeX;
	cv::cvtColor(edgeRoiX, edgeX, CV_GRAY2BGR);

	cv::Mat edgeY;
	cv::cvtColor(edgeRoiY, edgeY, CV_GRAY2BGR);

	cv::Mat roiCpy;
	cv::cvtColor(roi, roiCpy, CV_GRAY2BGR);

	const size_t to = std::min(grids.size(), numBest);
	size_t idx = 0;
	for (candidate_t const& candidate : grids) {
		std::vector<cv::Mat> images;

		PipelineGrid grid(candidate.config);

        images.push_back(tag.getRepresentations().orig);
		images.push_back(roiCpy);

		cv::Mat origCopy;
		roiCpy.copyTo(origCopy);
		pipeline::Ellipse const& ell = tag.getCandidatesConst().front().getEllipse();
		cv::ellipse(origCopy, ell.getCen(), ell.getAxis(), ell.getAngle(), 0, 360, cv::Scalar(0, 255, 0), 2);
		images.push_back(origCopy);

		images.push_back(edgeX);
		images.push_back(edgeY);
		images.push_back(binarizedROICpy);
		images.push_back(grid.getProjectedImage(roiSize));

		cv::Mat blendedBin;
		cv::addWeighted(binarizedROICpy, 0.6, grid.getProjectedImage(roiSize), 0.4, 0.0, blendedBin);
		images.push_back(blendedBin);

		cv::Mat blended;
        cv::addWeighted(tag.getRepresentations().orig, 0.8, grid.getProjectedImage(roiSize), 0.2, 0.0, blended);
		images.push_back(blended);

		cv::Mat cannyBlendedX;
		edgeX.copyTo(cannyBlendedX);
		grid.drawContours(cannyBlendedX, 0.9, cv::Vec3b(150, 200, 170));
		images.push_back(cannyBlendedX);

		cv::Mat cannyBlendedY;
		edgeY.copyTo(cannyBlendedY);
		grid.drawContours(cannyBlendedY, 0.9, cv::Vec3b(150, 200, 170));
		images.push_back(cannyBlendedY);

		cv::Mat origCopyOverlay;
		roiCpy.copyTo(origCopyOverlay);
		grid.drawContours(origCopyOverlay, 0.5);
		images.push_back(origCopyOverlay);

		const auto canvas = CvHelper::makeCanvas(images, images[0].rows + 10, 1);

		std::string title(winName + " " + std::to_string(idx) + " (error: " + std::to_string(candidate.error) + ")");
		cv::namedWindow(title);
		cv::imshow(title, canvas);

		++idx;
		if (idx == to) break;
	}

	if (!grids.empty()) {
		bool cont = true;
		while (cont) {
			const char c = cv::waitKey();
			if (c == 'd') {
				cv::destroyAllWindows();
				cont = false;
			} else if (c == 'c') {
				cont = false;
			}
		}
	}
}