bool MarkerDetector::findMarkers(const BGRAVideoFrame& frame, std::vector<Marker>& detectedMarkers)
{
  cv::Mat bgraMat(frame.height, frame.width, CV_8UC3, frame.data, frame.stride);
  
  // Convert the image to grayscale
  prepareImage(bgraMat, m_grayscaleImage);
  
  // Make it binary
  performThreshold(m_grayscaleImage, m_thresholdImg);
  
  // Detect contours
  findContours(m_thresholdImg, m_contours, m_grayscaleImage.cols / 20);
  
  // Find closed contours that can be approximated with 4 points
  findMarkerCandidates(m_contours, detectedMarkers);
  
  // Find is them are markers
  detectMarkers(m_grayscaleImage, detectedMarkers);

  // Calcualte their poses
  estimatePosition(detectedMarkers);

  //sort by id
  std::sort(detectedMarkers.begin(), detectedMarkers.end());
  return false;
}
// The workflow of the marker detection routine is the following:
// 1.   convert the input image to grayscale;
// 2.   perform a binary threshold operation;
// 3.   detect contours;
// 4.   search for possible markers;
// 5.   detect and decode markers;
// 6.   estimate marker 3D pose.
void MarkerDetector::processFrame(const cv::Mat& frame)
{
	// ...
	std::vector<Marker> markers;
	//cv::Mat bgraMat( frame.rows, frame.cols, CV_8UC4 );
	//cv::cvtColor( frame, bgraMat, CV_BGR2BGRA );
	// Convert the image to grayscale.
	// See: http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html#cvtcolor
	// The conversion to grayscale is necessary because markers usually contain only black and white blocks.
	// So it is much easier to operate with them using grayscale images.
	//cv::cvtColor( bgraMat, grayscaleImage, CV_BGRA2GRAY );
	cv::cvtColor(frame, grayscaleImage, CV_BGR2GRAY);

	// Make it binary.
	// See: http://docs.opencv.org/modules/imgproc/doc/miscellaneous_transformations.html#adaptivethreshold
	// The binarization operation will transform each pixel of our image to black (0 intensity) or white (255 intensity).
	// This step is required to find contours.
	cv::threshold(grayscaleImage, thresholdImg, 127.0, 255.0, cv::THRESH_BINARY_INV);

#ifdef _DEBUG
	cv::imshow("THR", thresholdImg);
#endif

	// Detect contours.
	MarkerDetector::findContours(thresholdImg, contours, grayscaleImage.cols / 5);

#ifdef _DEBUG
	cv::Mat contoursImage(thresholdImg.size(), CV_8UC1);
	contoursImage = cv::Scalar(0);
	// See: http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#drawcontours
	cv::drawContours(contoursImage, contours, -1, cv::Scalar(255), 2, CV_AA);
	cv::imshow("CNT", contoursImage);
#endif

	// Find closed contours that can be approximated with 4 points.
	findMarkerCandidates(contours, markers);

	// Find if there are markers.
	detectMarkers(grayscaleImage, markers);

	// Calcualte their poses.
	estimatePosition(markers);
	// Sort by id.
	// See: http://www.cplusplus.com/reference/algorithm/sort/
	std::sort(markers.begin(), markers.end());
	// ...
	transformations.clear();
	ids.clear();
	for (size_t i = 0; i < markers.size(); i++) {
		transformations.push_back(markers[i].transformation);
		ids.push_back(markers[i].id);
	}
}