use of org.opencv.core.RotatedRect in project kifu-recorder by leonardost.
the class Corner method mergeWith.
public Corner mergeWith(Corner otherCorner) {
Corner mergedCorner = new Corner();
mergedCorner.isStone = isStone && otherCorner.isStone;
mergedCorner.position = new Ponto((getX() + otherCorner.getX()) / 2, (getY() + otherCorner.getY()) / 2);
RotatedRect averageRectangle = new RotatedRect();
averageRectangle.center.x = mergedCorner.position.x;
averageRectangle.center.y = mergedCorner.position.y;
averageRectangle.size.height = Math.max(stonePosition.size.height, otherCorner.stonePosition.size.height);
averageRectangle.size.width = Math.max(stonePosition.size.width, otherCorner.stonePosition.size.width);
averageRectangle.angle = (stonePosition.angle + otherCorner.stonePosition.angle) / 2;
mergedCorner.stonePosition = averageRectangle;
return mergedCorner;
}
use of org.opencv.core.RotatedRect in project kifu-recorder by leonardost.
the class Corner method isTooCloseToCircle.
// Checks if a point lies too close to the stone position
// We increase the size of the ellipse a little to discard points
// that lie on the stone's edge and could be mistaken for a
// Harris corner point
public boolean isTooCloseToCircle(Ponto point) {
if (stonePosition == null)
return false;
RotatedRect ellipse = stonePosition.clone();
ellipse.size.width *= 1.2;
ellipse.size.height *= 1.2;
// https://stackoverflow.com/questions/7946187/point-and-ellipse-rotated-position-test-algorithm
double cos = Math.cos(Math.toRadians(ellipse.angle));
double sin = Math.sin(Math.toRadians(ellipse.angle));
double minorAxis = (ellipse.size.width / 2) * (ellipse.size.width / 2);
double majorAxis = (ellipse.size.height / 2) * (ellipse.size.height / 2);
double a = cos * (point.x - getX()) + sin * (point.y - getY());
double b = sin * (point.x - getX()) - cos * (point.y - getY());
return (a * a / minorAxis) + (b * b / majorAxis) <= 1;
}
use of org.opencv.core.RotatedRect in project kifu-recorder by leonardost.
the class EllipseCornerDetector method detectCandidateCornersIn.
public List<Corner> detectCandidateCornersIn(Mat image) {
List<EllipseDetectorInterface> ellipseDetectors = new ArrayList<>();
EllipseDetectorInterface firstEllipseDetector = new FirstEllipseDetector();
EllipseDetectorInterface secondEllipseDetector = new SecondEllipseDetector();
String prefix = "processing/corner" + cornerIndex + "_frame" + imageIndex;
firstEllipseDetector.setFilePrefix(prefix + "_first-filter");
secondEllipseDetector.setFilePrefix(prefix + "_second-filter");
ellipseDetectors.add(firstEllipseDetector);
ellipseDetectors.add(secondEllipseDetector);
List<Corner> candidateCorners = new ArrayList<>();
for (EllipseDetectorInterface ellipseDetector : ellipseDetectors) {
List<RotatedRect> ellipses = ellipseDetector.detectEllipsesIn(image);
for (RotatedRect ellipse : ellipses) {
Corner corner = new Corner((int) ellipse.center.x, (int) ellipse.center.y, true);
corner.stonePosition = ellipse;
candidateCorners.add(corner);
}
}
return mergeEllipsesWithCloseCenters(candidateCorners);
}
use of org.opencv.core.RotatedRect in project kifu-recorder by leonardost.
the class EllipseChecker method getEllipseFrom.
public RotatedRect getEllipseFrom(MatOfPoint contour) {
approximatedContour = approximateContour(contour);
if (!canContourBeAnEllipse(approximatedContour))
return null;
RotatedRect ellipse = fitEllipseInContour(contour);
if (!isEllipseAGoodFitAgainstContour(ellipse, contour))
return null;
return ellipse;
}
use of org.opencv.core.RotatedRect in project kifu-recorder by leonardost.
the class FirstEllipseDetector method detectEllipsesIn.
// https://stackoverflow.com/questions/35121045/find-cost-of-ellipse-in-opencv
public List<RotatedRect> detectEllipsesIn(Mat image) {
this.image = image.clone();
Mat imageWithEllipses = image.clone();
approximatedContours = new ArrayList<>();
Mat preprocessedImage = preprocessImage(image.clone());
List<MatOfPoint> contours = detectContoursIn(preprocessedImage);
outputImageWithContours(image, contours, filePrefix + "_all_contours.png");
List<RotatedRect> ellipses = new ArrayList<>();
// stones and the board in the scene
if (contours.size() > 5) {
System.out.println("More than 5 contours found, disregarding this image");
return ellipses;
}
EllipseChecker ellipseChecker = new EllipseChecker();
ellipseChecker.setImage(this.image);
for (int i = 0; i < contours.size(); i++) {
RotatedRect ellipse = ellipseChecker.getEllipseFrom(contours.get(i));
approximatedContours.add(ellipseChecker.getApproximatedContour());
if (ellipse == null)
continue;
// Let's increase the ellipse size to encompass the entire stone and some more
// The perspective should be taken into account here, but let's leave it like this for now
ellipse.size.width *= 1.2;
ellipse.size.height *= 1.1;
ellipses.add(ellipse);
Imgproc.ellipse(imageWithEllipses, ellipse, new Scalar(0, 255, 0));
}
return ellipses;
}
Aggregations