Пример #1
0
void OpticalMusic::rotate(Angle amount) {
	int width = image.cols;
	int height = image.rows;

	// compute rotation matrix (homogenous coordinates)
	Point center(width / 2.f, height / 2.f);
	Mat rotMat = getRotationMatrix2D(center, amount.degree(), 1.0);

	// calculate size of the new image
	Mat topLeft = (Mat_<double>(3, 1) << 0, 0, 1);	// homogenous coordinates
	topLeft = rotMat * topLeft;
	int dx = abs(round(topLeft.at<double>(Point(0, 0))));
	int dy = abs(round(topLeft.at<double>(Point(0, 1))));
	Size newSize(width + 2 * dx, height + 2 * dy);

	// pad old image
	Mat padded = Mat::zeros(newSize, CV_8U);
	Mat targetRegion = padded(Range(dy, dy + height), Range(dx, dx + width));
	image.copyTo(targetRegion);

	// rotate padded
	Mat* rotated = new Mat(newSize, CV_8UC1);
	warpAffine(padded, *rotated, rotMat, newSize);
	image = *rotated;
}
Пример #2
0
/**
 * Performs a range query in the R-Tree, where the range is defined by the center +- the tolerances given.
 * @param center The center of the query volume.
 * @param xTolerance The absolute values to add and subtract to obtain the range in x dimension.
 * @param yTolerance
 * @param angleTolerance
 * @return All points within the specified interval.
 */
vector<ContourIndex::ContourPointIdx> ContourIndex::symmetricRange(Contour::ContourPart center, float xTolerance, float yTolerance,
		Angle angleTolerance, Angle curvatureTolerance
		) {

	assert(angleTolerance<=Angle(180,Angle::DEGREE));		// +-180˚ covers everything, more would cause duplicate results (because the generated regions will overlap)
	assert(curvatureTolerance<=Angle(180,Angle::DEGREE));

	int NORMAL_DIM = 2; // index of the normal orientation angle in the region bounds arrays
	int CURVATURE_DIM = 3;	// index of the curvature orientation angle in the region bounds arrays

	double rLow[numDimensions], rHigh[numDimensions];
	Angle lowerNormalBound = center->getAngularFeature(indexAngularFeature).normalize() - angleTolerance;
	Angle upperNormalBound = center->getAngularFeature(indexAngularFeature).normalize() + angleTolerance;

	Angle lowerCurvatureBound = center->curvature.normalize() - curvatureTolerance;
	Angle upperCurvatureBound = center->curvature.normalize() + curvatureTolerance;

	// location is unproblematic, no modulo here
	rLow[0] = center->x - xTolerance;
	rLow[1] = center->y - yTolerance;
	rHigh[0] = center->x + xTolerance;
	rHigh[1] = center->y + yTolerance;

	// SPLIT RANGES FOR MODULO BEHAVIOR OF ANGLES
	vector<SpatialIndex::Region> regions;

	// central region
	rLow[NORMAL_DIM] = std::max(0.f, lowerNormalBound.degree());
	rHigh[NORMAL_DIM] = std::min(360.f, upperNormalBound.degree());
	rLow[CURVATURE_DIM] = std::max(0.f, lowerCurvatureBound.degree());
	rHigh[CURVATURE_DIM] = std::min(360.f, upperCurvatureBound.degree());
	regions.push_back(SpatialIndex::Region(rLow, rHigh, numDimensions));

	// normal orientation overshoot
	if(upperNormalBound.degree() > 360){
		// 0 to normalize(upperNormal) in normal dimension
		rLow[NORMAL_DIM] = 0;
		rHigh[NORMAL_DIM] = upperNormalBound.normalize().degree();
		rLow[CURVATURE_DIM] = std::max(0.f, lowerCurvatureBound.degree());		// clip the rest
		rHigh[CURVATURE_DIM] = std::min(360.f, upperCurvatureBound.degree());
		regions.push_back(SpatialIndex::Region(rLow, rHigh, numDimensions));
	}

	// normal orientation undershoot
	if(lowerNormalBound.degree() < 0){
		// normalize(lowerNormal) to 360 in normal dimension
		rLow[NORMAL_DIM] = lowerNormalBound.normalize().degree();
		rHigh[NORMAL_DIM] = 360;
		rLow[CURVATURE_DIM] = std::max(0.f, lowerCurvatureBound.degree());		// clip the rest
		rHigh[CURVATURE_DIM] = std::min(360.f, upperCurvatureBound.degree());
		regions.push_back(SpatialIndex::Region(rLow, rHigh, numDimensions));
	}

	// curvature orientation overshoot
	if(upperCurvatureBound.degree() > 360){
		// 0 to normalize(lowerCurvature) in curvature dimension
		rLow[CURVATURE_DIM] = 0;
		rHigh[CURVATURE_DIM] = upperCurvatureBound.normalize().degree();
		rLow[NORMAL_DIM] = std::max(0.f, lowerNormalBound.degree());			// clip the rest
		rHigh[NORMAL_DIM] = std::min(360.f, upperNormalBound.degree());
		regions.push_back(SpatialIndex::Region(rLow, rHigh, numDimensions));
	}

	// curvature orientation undershoot
	if(lowerCurvatureBound.degree() < 0){
		// normalize(lowerCurvature) to 360 in curvature dimension
		rLow[CURVATURE_DIM] = lowerCurvatureBound.normalize().degree();
		rHigh[CURVATURE_DIM] = 360;
		rLow[NORMAL_DIM] = std::max(0.f, lowerNormalBound.degree());			// clip the rest
		rHigh[NORMAL_DIM] = std::min(360.f, upperNormalBound.degree());
		regions.push_back(SpatialIndex::Region(rLow, rHigh, numDimensions));
	}

	// combined overshoot
	if(upperNormalBound.degree() > 360 && upperCurvatureBound.degree() > 360){
		// 0 to normalize(upperCurvature) in curvature dimension
		// 0 to normalize(upperNormal) in normal dimension
		rLow[NORMAL_DIM] = 0;
		rHigh[NORMAL_DIM] = upperNormalBound.normalize().degree();
		rLow[CURVATURE_DIM] = 0;
		rHigh[CURVATURE_DIM] = upperCurvatureBound.normalize().degree();
		regions.push_back(SpatialIndex::Region(rLow, rHigh, numDimensions));
	}

	// combined undershoot
	if(lowerNormalBound.degree() < 0 && lowerCurvatureBound.degree() < 0){
		// normalize(lowerNormal) to 360 in normal dimension
		// normalize(lowerCurvature) to 360 in curvature dimension
		rLow[NORMAL_DIM] = lowerNormalBound.normalize().degree();
		rHigh[NORMAL_DIM] = 360;
		rLow[CURVATURE_DIM] = lowerCurvatureBound.normalize().degree();
		rHigh[CURVATURE_DIM] = 360;
		regions.push_back(SpatialIndex::Region(rLow, rHigh, numDimensions));
	}

	// QUERY ALL REGIONS AND CONCAT RESULTS
	vector<ContourPointIdx> *result = new vector<ContourPointIdx>();
	for (std::vector<SpatialIndex::Region>::iterator r = regions.begin(); r != regions.end(); ++r) {

		CollectIndicesVisitor cv(this);
		tree->intersectsWithQuery(*r, cv);
		for (vector<ContourPointIdx>::iterator it = cv.result.begin(); it != cv.result.end(); ++it)
			result->push_back(*it);
	}

	return *result;
}