Exemplo n.º 1
0
void MarkerDetector::findContours(cv::Mat& thresholdImg,
                                  ContoursVector& contours,
                                  int minContourPointsAllowed)
{
    ContoursVector allContours;
    cv::findContours(thresholdImg, allContours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
    
    contours.clear();
    for (size_t i=0; i<allContours.size(); i++)
    {
        int contourSize = allContours[i].size();
        if (contourSize > minContourPointsAllowed)
        {
            contours.push_back(allContours[i]);
        }
    }
    
#ifdef SHOW_DEBUG_IMAGES
    {
        cv::Mat contoursImage(thresholdImg.size(), CV_8UC1);
        contoursImage = cv::Scalar(0);
        cv::drawContours(contoursImage, contours, -1, cv::Scalar(255), 2, CV_AA);
        cv::imshow("Contours", contoursImage);
        cv::waitKey();
    }
#endif
}
	bool MultiContourObjectDetector::findBaseShape(cv::Mat& baseImage)
	{
		vector<vector<vector<Point>>> approxContours = findApproxContours(baseImage, true, true);

		if (approxContours.size() == 0)
		{
			cerr << "ERROR: No valid contours found in base image" << endl;
			return false;
		}

		_baseShape = approxContours[0];
		_aspectedContours = _baseShape.size();
		_minContourPoints = numeric_limits<int>::max();

		for (int i = 0; i < _baseShape.size(); i++)
		{
			vector<Point> tempKeypoints;

			Utility::findCentroidsKeypoints(_baseShape[i], tempKeypoints, Utility::CentroidDetectionMode::THREE_LOOP);
			_baseKeypoints.push_back(tempKeypoints);

			if (_baseShape[i].size() < _minContourPoints)
				_minContourPoints = _baseShape[i].size();
		}

#ifdef DEBUG_MODE
		Mat contoursImage(baseImage.size(), CV_8UC1);
		contoursImage = cv::Scalar(0);
		drawContours(contoursImage, _baseShape, -1, cv::Scalar(255), 1, CV_AA);
		imshow("TO FIND CONTOUR", contoursImage);
#endif

		return true;
	}
// 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);
	}
}
// Each marker usually looks like a square figure with black and white areas inside it.
// So the best way to locate a marker is to find closed contours and approximate them with polygons of 4 vertices.
// This function will detect contours on the input binary image.
// The return value is a list of polygons where each polygon represents a single contour.
// This function skips contours that have their perimeter in pixel value set to be less than a specific input threshold.
// This because we are not interested in small contours.
void MarkerDetector::findContours(const cv::Mat& thresholdImg,
	std::vector< std::vector<cv::Point> >& contours,
	int minContourPointsAllowed)
{
	std::vector< std::vector<cv::Point> > allContours;
	// See: http://docs.opencv.org/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html#findcontours
	cv::findContours(thresholdImg, allContours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
	contours.clear();
	for (size_t i = 0; i < allContours.size(); i++) {
		int contourSize = allContours[i].size();
		if (contourSize > minContourPointsAllowed) { contours.push_back(allContours[i]); }
	}

#ifdef _DEBUG
	cv::Mat contoursImage(thresholdImg.size(), CV_8UC1);
	contoursImage = cv::Scalar(0);
	cv::drawContours(contoursImage, contours, -1, cv::Scalar(255), 2, CV_AA);
	cv::imshow("Contours Image", contoursImage);
#endif
}