diff --git a/modules/java/android_test/src/org/opencv/test/core/RotatedRectTest.java b/modules/java/android_test/src/org/opencv/test/core/RotatedRectTest.java new file mode 100644 index 000000000..f42f97e0a --- /dev/null +++ b/modules/java/android_test/src/org/opencv/test/core/RotatedRectTest.java @@ -0,0 +1,156 @@ +package org.opencv.test.core; + +import org.opencv.Point; +import org.opencv.Rect; +import org.opencv.RotatedRect; +import org.opencv.Size; +import org.opencv.test.OpenCVTestCase; +import org.opencv.test.OpenCVTestRunner; + +public class RotatedRectTest extends OpenCVTestCase { + + public void testBoundingRect() { + Point center = new Point(matSize/2, matSize/2); + double length1 = matSize/4; + Size size = new Size(length1, length1); + double angle = 45; + + RotatedRect rr = new RotatedRect(center, size, angle); + + Rect r = rr.boundingRect(); + + OpenCVTestRunner.Log("testBoundingRect: r="+r.toString()); + OpenCVTestRunner.Log("testBoundingRect: center.x + length1*Math.sqrt(2)/2="+ (center.x + length1*Math.sqrt(2)/2)); + OpenCVTestRunner.Log("testBoundingRect: length1*Math.sqrt(2)="+ (length1*Math.sqrt(2))); + + assertTrue( + (r.x == Math.floor(center.x - length1*Math.sqrt(2)/2)) + && + (r.y == Math.floor(center.y - length1*Math.sqrt(2)/2))); + + assertTrue( + (r.br().x >= Math.ceil(center.x + length1*Math.sqrt(2)/2)) + && + (r.br().y >= Math.ceil(center.y + length1*Math.sqrt(2)/2))); + + assertTrue( + (r.br().x - Math.ceil(center.x + length1*Math.sqrt(2)/2)) <= 1 + && + (r.br().y - Math.ceil(center.y + length1*Math.sqrt(2)/2)) <= 1); + } + + + public void testClone() { + Point center = new Point(matSize/2, matSize/2); + Size size = new Size(matSize/4, matSize/2); + double angle = 40; + + RotatedRect rr1 = new RotatedRect(center, size, angle); + RotatedRect rr1c = rr1.clone(); + + assertTrue(rr1c != null); + assertTrue(rr1.center.equals(rr1c.center)); + assertTrue(rr1.size.equals(rr1c.size)); + assertTrue(rr1.angle == rr1c.angle); + } + + public void testEqualsObject() { + Point center = new Point(matSize/2, matSize/2); + Size size = new Size(matSize/4, matSize/2); + double angle = 40; + Point center2 = new Point(matSize/3, matSize/1.5); + Size size2 = new Size(matSize/2, matSize/4); + double angle2 = 0; + + RotatedRect rr1 = new RotatedRect(center, size, angle); + RotatedRect rr2 = new RotatedRect(center2, size2, angle2); + RotatedRect rr1c = rr1.clone(); + RotatedRect rr3 = rr2.clone(); + RotatedRect rr11=rr1; + rr3.angle=10; + + assertTrue(rr1.equals(rr11)); + assertTrue(!rr1.equals(rr2)); + assertTrue(rr1.equals(rr1c)); + assertTrue(!rr2.equals(rr3)); + + rr1c.center.x+=1; + assertTrue(!rr1.equals(rr1c)); + + rr1c.center.x-=1; + assertTrue(rr1.equals(rr1c)); + + rr1c.size.width+=1; + assertTrue(!rr1.equals(rr1c)); + + assertTrue(! rr1.equals(size)); + } + + public void testPoints() { + Point center = new Point(matSize/2, matSize/2); + Size size = new Size(matSize/4, matSize/2); + double angle = 40; + RotatedRect rr = new RotatedRect(center, size, angle); + Point p[] = new Point[4]; + + rr.points(p); + + boolean is_p0_irrational = (100*p[0].x!=(int)(100*p[0].x)) && (100*p[0].y!=(int)(100*p[0].y)); + boolean is_p1_irrational = (100*p[1].x!=(int)(100*p[1].x)) && (100*p[1].y!=(int)(100*p[1].y)); + boolean is_p2_irrational = (100*p[2].x!=(int)(100*p[2].x)) && (100*p[2].y!=(int)(100*p[2].y)); + boolean is_p3_irrational = (100*p[3].x!=(int)(100*p[3].x)) && (100*p[3].y!=(int)(100*p[3].y)); + + assertTrue(is_p0_irrational && is_p1_irrational && is_p2_irrational && is_p3_irrational); + + assertTrue("Symmetric points 0 and 2", + Math.abs((p[0].x + p[2].x)/2 - center.x) + Math.abs((p[0].y + p[2].y)/2 - center.y) < 0.001); + + assertTrue("Symmetric points 1 and 3", + Math.abs((p[1].x + p[3].x)/2 - center.x) + Math.abs((p[1].y + p[3].y)/2 - center.y) < 0.001); + + assertTrue("Orthogonal vectors 01 and 12", + Math.abs( (p[1].x - p[0].x) * (p[2].x - p[1].x) + (p[1].y - p[0].y) * (p[2].y - p[1].y) ) < 0.001); + + assertTrue("Orthogonal vectors 12 and 23", + Math.abs( (p[2].x - p[1].x) * (p[3].x - p[2].x) + (p[2].y - p[1].y) * (p[3].y - p[2].y) ) < 0.001); + + assertTrue("Orthogonal vectors 23 and 30", + Math.abs( (p[3].x - p[2].x) * (p[0].x - p[3].x) + (p[3].y - p[2].y) * (p[0].y - p[3].y) ) < 0.001); + + assertTrue("Orthogonal vectors 30 and 01", + Math.abs( (p[0].x - p[3].x) * (p[1].x - p[0].x) + (p[0].y - p[3].y) * (p[1].y - p[0].y) ) < 0.001); + + assertTrue("Length of the vector 01", + Math.abs( + (p[1].x - p[0].x) * (p[1].x - p[0].x) + (p[1].y - p[0].y)*(p[1].y - p[0].y) + - + size.height * size.height + ) < 0.001); + + assertTrue("Length of the vector 21", + Math.abs( + (p[1].x - p[2].x) * (p[1].x - p[2].x) + (p[1].y - p[2].y)*(p[1].y - p[2].y) + - + size.width * size.width + ) < 0.001); + + assertTrue("Angle of the vector 21 with the axes", + Math.abs( + (p[2].x - p[1].x) / size.width + - + Math.cos(angle * Math.PI / 180) + ) < 0.001); + + } + + public void testRotatedRect() { + RotatedRect rr = new RotatedRect(); + assertTrue(rr != null); + } + + public void testRotatedRectPointSizeDouble() { + RotatedRect rr = new RotatedRect(new Point(matSize/2, matSize/2), new Size(matSize/4, matSize/2), 45); + assertTrue(rr != null); + } + +} diff --git a/modules/java/gen_java.py b/modules/java/gen_java.py index 41f517ce1..d63b8bc58 100644 --- a/modules/java/gen_java.py +++ b/modules/java/gen_java.py @@ -46,9 +46,15 @@ type_dict = { "Rect" : { "j_type" : "Rect", "jn_args" : (("int", ".x"), ("int", ".y"), ("int", ".width"), ("int", ".height")), "jni_var" : "cv::Rect %(n)s(%(n)s_x, %(n)s_y, %(n)s_width, %(n)s_height)", "suffix" : "IIII"}, - "Size" : { "j_type" : "Size", "jn_args" : (("int", ".width"), ("int", ".height")), - "jni_var" : "cv::Size %(n)s(%(n)s_width, %(n)s_height)", - "suffix" : "II"}, + "Size" : { "j_type" : "Size", "jn_args" : (("double", ".width"), ("double", ".height")), + "jni_var" : "cv::Size %(n)s((int)%(n)s_width, (int)%(n)s_height)", + "suffix" : "DD"}, + "Size2f" : { "j_type" : "Size", "jn_args" : (("double", ".width"), ("double", ".height")), + "jni_var" : "cv::Size2f %(n)s((float)%(n)s_width, (float)%(n)s_height)", + "suffix" : "DD"}, + "RotatedRect": { "j_type" : "RotatedRect", "jn_args" : (("double", ".center.x"), ("double", ".center.y"), ("double", ".size.width"), ("double", ".size.height"), ("double", ".angle")), + "jni_var" : "cv::RotatedRect %(n)s(cv::Point2f(%(n)s_center_x, %(n)s_center_y), cv::Size2f(%(n)s_size_width, %(n)s_size_height), %(n)s_angle)", + "suffix" : "DDDDD"}, "Scalar" : { "j_type" : "Scalar", "jn_args" : (("double", ".v0"), ("double", ".v1"), ("double", ".v2"), ("double", ".v3")), "jni_var" : "cv::Scalar %(n)s(%(n)s_v0, %(n)s_v1, %(n)s_v2, %(n)s_v3)", "suffix" : "DDDD"}, diff --git a/modules/java/src/java/Point.java b/modules/java/src/java/Point.java index b1e5cd658..404b1f3dc 100644 --- a/modules/java/src/java/Point.java +++ b/modules/java/src/java/Point.java @@ -45,4 +45,11 @@ public class Point { public boolean inside(Rect r) { return r.contains(this); } + + + @Override + public String toString() { + if (this == null) return "null"; + return "{" + x + ", " + y + "}"; + } } diff --git a/modules/java/src/java/Rect.java b/modules/java/src/java/Rect.java index 3dce4a958..314a20914 100644 --- a/modules/java/src/java/Rect.java +++ b/modules/java/src/java/Rect.java @@ -3,7 +3,7 @@ package org.opencv; //javadoc:Rect_ public class Rect { - int x, y, width, height; + public int x, y, width, height; public Rect(int x, int y, int width, int height) { this.x = x; @@ -24,7 +24,7 @@ public class Rect { } public Rect(Point p, Size s) { - this((int)p.x, (int)p.y, s.width, s.height); + this((int)p.x, (int)p.y, (int)s.width, (int)s.height); } public Rect clone() { @@ -74,4 +74,10 @@ public class Rect { Rect it = (Rect) obj; return x == it.x && y == it.y && width == it.width && height == it.height; } + + @Override + public String toString() { + if (this == null) return "null"; + return "{" + x + ", " + y + ", " + width + "x" + height+"}"; + } } diff --git a/modules/java/src/java/RotatedRect.java b/modules/java/src/java/RotatedRect.java new file mode 100644 index 000000000..bbdd8cb0e --- /dev/null +++ b/modules/java/src/java/RotatedRect.java @@ -0,0 +1,87 @@ +package org.opencv; + +//javadoc:RotatedRect_ +public class RotatedRect { + + public Point center; + public Size size; + public double angle; + + public RotatedRect() { + this.angle=0; + } + + public RotatedRect(Point c, Size s, double a) { + this.center = c.clone(); + this.size = s.clone(); + this.angle = a; + } + + public void points(Point pt[]) + { + double _angle = angle*Math.PI/180.0; + double b = (double)Math.cos(_angle)*0.5f; + double a = (double)Math.sin(_angle)*0.5f; + + pt[0] = new Point( + center.x - a*size.height - b*size.width, + center.y + b*size.height - a*size.width); + + pt[1] = new Point( + center.x + a*size.height - b*size.width, + center.y - b*size.height - a*size.width); + + pt[2] = new Point( + 2*center.x - pt[0].x, + 2*center.y - pt[0].y); + + pt[3] = new Point( + 2*center.x - pt[1].x, + 2*center.y - pt[1].y); + } + + public Rect boundingRect() + { + Point pt[] = new Point[4]; + points(pt); + Rect r=new Rect((int)Math.floor(Math.min(Math.min(Math.min(pt[0].x, pt[1].x), pt[2].x), pt[3].x)), + (int)Math.floor(Math.min(Math.min(Math.min(pt[0].y, pt[1].y), pt[2].y), pt[3].y)), + (int)Math.ceil(Math.max(Math.max(Math.max(pt[0].x, pt[1].x), pt[2].x), pt[3].x)), + (int)Math.ceil(Math.max(Math.max(Math.max(pt[0].y, pt[1].y), pt[2].y), pt[3].y))); + r.width -= r.x - 1; + r.height -= r.y - 1; + return r; + } + + + public RotatedRect clone() { + return new RotatedRect(center, size, angle); + } + + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + long temp; + temp = Double.doubleToLongBits(center.x); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(center.y); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(size.width); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(size.height); + result = prime * result + (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(angle); + result = prime * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof RotatedRect)) return false; + RotatedRect it = (RotatedRect) obj; + return center.equals(it.center) && size.equals(it.size) && angle == it.angle; + } +} diff --git a/modules/java/src/java/Size.java b/modules/java/src/java/Size.java index c3af14367..161d1e9ff 100644 --- a/modules/java/src/java/Size.java +++ b/modules/java/src/java/Size.java @@ -3,9 +3,9 @@ package org.opencv; //javadoc:Size_ public class Size { - public int width, height; + public double width, height; - public Size(int width, int height) { + public Size(double width, double height) { this.width = width; this.height = height; } @@ -15,8 +15,8 @@ public class Size { } public Size(Point p) { - width = (int) p.x; - height = (int) p.y; + width = (double) p.x; + height = (double) p.y; } public double area() {