In my testcase http://drifted.in/other/ol/tiles.html there is a tiny gap between tiles even though the GeoJSON coordinates are same.
7/68/84 - xMax: 1565430.3392804079 (meters)
7/68/85 - xMin: 1565430.3392804079
Is there any rounding involved? Or is my border X coord calculated incorrectly, hence rendered slightly shifted?
Related
In OpenCV or object detection models, they represent bounding box as 4 numbers e.g. x,y,width,height or x1,y1,x2,y2.
These numbers seem to be ill-defined but it's fine when the resolution is big.
But it causes me to think when the image has very low resolution e.g. 8x8, the one-pixel error can cause things to go very wrong.
So I want to know, what exactly does it mean when you say that a bounding box has x1=0, x2=100?
Specifically, I want to clear these confusions when understood well:
Does the bounding box border occupy the 0th pixel or is it surrounding 0th pixel (its border is at x=-1)?
Where is the exact end of the bounding box? If the image have shape=(8,8), would the end be at 7 or 8?
If you want to represent a bounding box that occupy the entire image, what should be its values?
So I think the right question should be, how do I think about bounding box intuitively so that these are not confusing for me?
OK. After many days working with bounding boxes, I have my own intuition on how to think about bounding box coordinates now.
I divide coordinates in 2 categories: continuous and discrete. The mental problems usually arise when you try to convert between them.
Suppose the image have width=100, height=100 then you can have a continuous point with x,y that can have any real value in the range [0,100].
It means that points like (0,0), (0.5,7.1,39.83,99.9999) are valid points.
Now you can convert a continuous point to a discrete point on the image by taking the floor of the number. E.g. (5.5, 8.9) gets mapped to pixel number (5,8) on the image. It's very important to understand that you should not use the ceiling or rounding operation to convert it to the discrete version. Suppose you have a continuous point (0.9,0.9) this point lies in the (0,0) pixel so it's closest to (0,0) pixel, not (1,1) pixel.
From this foundation, let's try to answer my question:
So I want to know, what exactly does it mean when you say that a bounding box has x1=0, x2=100?
It means that the continuous point 1 has x value = 0, and continuous point 2, has x value = 100. Continuous point has zero size. It's not a pixel.
Does the bounding box border occupy the 0th pixel or is it surrounding 0th pixel (its border is at x=-1)?
In continuous-space, the bounding box border occupy zero space. The border is infinitesimally slim. But when we want to draw it onto an image, the border will have the size of at least 1 pixel thick. So if we have a continuous point (0,0), it will occupy 0th pixel of the image. But theoretically, it represents a slim border at the left side and top side of the 0th pixel.
Where is the exact end of the bounding box? If the image have shape=(8,8), would the end be at 7 or 8?
The biggest x,y value you can have is 7.999... but when converted to discrete version you will be left with 7 which represent the last pixel.
If you want to represent a bounding box that occupy the entire image, what should be its values?
You should represent bounding box coordinates in continuous space instead of discrete space because of the precision that you have. It means the largest bounding box starts at (0,0) and ends at (100,100). But if you want to draw this box, you need to convert it to discrete version and draws the bounding box at (0,0) and end at (99,99).
In OpenCv the bounding rectangle can be defined in many ways. One way is its top-left corner and bottom-right corner. In case of constructor Rect(int x1, int y1, int x2, int y2) it defines those two points. The rectangle starts exactly on that pixel and coordinate. For subpixel rectangles there are also variants holding the floating point coordinates.
So I want to know, what exactly does it mean when you say that a bounding box has x1=0, x2=100?
That means the top-left corner x-coordinate starts at 0 and bottom-right x-coordinate
starts at 100.
Does the bounding box border occupy the 0th pixel or is it surrounding 0th pixel (its border is at x=-1)?
The border starts exactly on the 0-th pixel. Meaning that rectangle with width and height of 1px when drawn is just a signle dot (1px)
Where is the exact end of the bounding box? If the image have shape=(8,8), would the end be at 7 or 8?
The end would be at 7, see below.
If you want to represent a bounding box that occupy the entire image, what should be its values?
Lets have an image size of 100,100. The around the image rectangle defined by two points would be Rect(Point(0,0), Point(99,99)) by starting point and size Rect(0, 0, 100, 100)
The basic is to know that image of size X,Y has a minimum top-left coordinate at (0,0) and maximum at bottom-right (X-1,Y-1)
I am attempting to map a fisheye image to a 360 degree view using a sky sphere in Unity. The scene is inside the sphere. I am very close but I am seeing some slight distortion. I am calculating UV coordinates as follows:
Vector3 v = currentVertice; // unit vector from edge of sphere, -1, -1, -1 to 1, 1, 1
float r = Mathf.Atan2(Mathf.Sqrt(v.x * v.x + v.y * v.y), v.z) / (Mathf.PI * 2.0f);
float phi = Mathf.Atan2(v.y, v.x);
textureCoordinates.x = (r * Mathf.Cos(phi)) + 0.5f;
textureCoordinates.y = (r * Mathf.Sin(phi)) + 0.5f;
Here is the distortion and triangles:
The rest of the entire sphere looks great, it's just at this one spot that I get the distortion.
Here is the source fish eye image:
And the same sphere with a UV test texture over the top showing the same distortion area. Full UV test texture is on the right, and is a square although stretched into a rectangle on the right for purposes of my screenshot.
The distortion above is using sphere mapping rather than fish eye mapping. Here is the UV texture using fish eye mapping:
Math isn't my strong point, am I doing anything wrong here or is this kind of mapping simply not 100% possible?
The spot you are seeing is the case where r gets very close to 1. As you can see in the source image, this is the border area between the very distorted image data and the black.
This area is very distorted, however that's not the main problem. Looking at the result you can see that there are problems with UV orientation.
I've added a few lines to your source image to demonstrate what I mean. Where r is small (yellow lines) you can see that the UV coordinates can be interpolated between the corners of your quad (assuming quads instead of tris). However, where r is big (red corners), interpolating UV coordinates will make them travel through areas of your source image whose r is much smaller than 1 (red lines), causing distortions in UV space. Actually, those red lines should not be straight, but they should travel along the border of your source image data.
You can improve this by having a higher polycount in the area of your skysphere where r gets close to 1, but it will never be perfect as long as your UVs are interpolated in a linear way.
I also found another problem. If you look closely at the spot, you'll find that the complete source image is present there in small. This is because your UV coordinates wrap around at that point. As rendering passes around the viewer, uv coordinates travel from 0 towards 1. At the spot they are at 1, the neighboring vertex however is at 0.001 or something, causing the whole source image to be rendered inbetween. To fix that, you'll need to have two seperate vertices at the seam of your skysphere, one where the surface of the sphere starts, and one where it ends. In object space they are identical, but in uv space one is at 0, the other at 1.
I'm trying to calculate the size of a bounding box after rotating a square. I've attached an image that hopefully describes what I'm looking to do.
After rotating by x degrees, the bounds becomes bigger. Is there a way to calculate this new size, given the angle and the dimensions of the original square? Thank you.
This can be solved through 2 applications of Pythag.
Each side of your larger square is split into two by a corner of your small blue square. Lets call the larger of these 2 sections length a, the smaller length b (although if x > 45 degrees then b will be larger), with side length l for the blue square and L as length of the black square.
We can calculate the first as: Cos(x) = a/l.
And the 2nd as Sin(x) = b/l
Thus we have L = (Sin(x)+Cos(x))*l.
Edit: Area is of course side length squared in both cases.
This works only if you have the co-ordinates. If you can get the co-ordinates of the four vertices, it would be so easy.. Lets assume the point at the top left corner of the bound be A. And the top two vertices of the square be sq_a and sq_b. The value of the vertex A would be (sq_a.x,sq_b.y). Then by symmetry , all the small four triangles formed between the bound and the square will be of the same area. Calculate the area of the triangle formed between A,sq_a and sq_b (which should be easy .. 1/2 * breadth * height). Multiply by 4 and the you will get the total area. Sorry couldnt post detailed pics.
I am currently plotting certain data using Scatter Plot of Core Plot. The size of the circles depends on the frequency of occurrence of the particular value. On plotting, I find that some of the circles are overlapping and crossing the x and y axes.
Is there any method to check if a circle (i.e, plot point) crosses the axes and automatically resize the circle so that it does not cross the axes?
Edit - The axes are fixed. So I cannot change the axes.
Edit - I would like to know which methods to use to determine if a circle crosses/touches the x or y axis. Currently the circle overlaps if the size of circle is 12 and its y coordinate is 1.1. I am unable to understand how the size is being mapped to the circle on the plot. Thanks.
No. The easiest way around this problem is to figure out how big the largest circle will be and adjust the plot ranges on the the plot space to leave at least that much space between the extreme data points (smallest and largest) and the axes or other edges of the plot space. The plot space has methods to convert back and forth between data coordinates and pixels in the coordinate space of the plot area layer.
The point conversion methods are:
(data to plot area)
-(CGPoint)plotAreaViewPointForPlotPoint:(NSDecimal *)plotPoint
numberOfCoordinates:(NSUInteger)count;
-(CGPoint)plotAreaViewPointForDoublePrecisionPlotPoint:(double *)plotPoint
numberOfCoordinates:(NSUInteger)count;
(plot area to data)
-(void)plotPoint:(NSDecimal *)plotPoint numberOfCoordinates:(NSUInteger)count
forPlotAreaViewPoint:(CGPoint)point;
-(void)doublePrecisionPlotPoint:(double *)plotPoint
numberOfCoordinates:(NSUInteger)count
forPlotAreaViewPoint:(CGPoint)point;
Depending on your application, you might be able to expand the plot range by a simple factor using -expandRangeByFactor:. You can find the factor for the xRange by dividing the width of the plot area plus the circle diameter by the width of the plot area. Do a similar calculation for the yRange using the height of the plot area.
Perhaps you could check to see if half of the diameter is greater than both the x and y value of the plot. If it is greater, then reduce the diameter to equal twice the smaller of x and y.
I'm doing some drawing relative to a scaled image so I end up with fractional CGPoints. I am scaling the results from the CoreImage face detection routine.
Do I want to round these myself or leave it to iOS to do it when I use these points in CGPathAddLineToPoint calls? If it is better to round, should I round up or down?
I've read about pixel boundaries, etc. but I'm not sure how to apply that here. I am drawing to a CALayer
CGPoint leftEye = CGPointMake((leftEyePosition.x * xScale),
(leftEyePosition.y * yScale));
// result
features {
faceRect = "{{92, 144.469}, {166.667, 179.688}}";
hasLeftEyePosition = 1;
hasMouthPosition = 1;
hasRightEyePosition = 1;
leftEyePosition = "{142.667, 268.812}";
mouthPosition = "{176, 189.75}";
rightEyePosition = "{207.333, 269.531}";
}
Whether or not you round, and in what direction, depends on the effect you are trying to accomplish.
CoreGraphics itself has absolutely no problem with fractional coordinates. However, drawing anything using fractional coordinates is going to end up antialiasing the drawn objects. This typically causes them to look fuzzy. Rounding your coordinates appropriately is a good idea to avoid this.
Be warned, however. Depending on what you're drawing and how, you may want coordinates that are 0.5 pixels off instead of integral coordinates. For example, if you're drawing a line, the line is centered on the coordinate you give. So a 1-pixel line drawn on integral coordinates will actually end up being a fuzzy line 2 pixels wide (with each pixel accounting for half of the line). The simplest thing to remember is that strokes are centered on the coordinates, but fills are bounded by them. So when filling a rectangle, integral coordinates is best. When stroking a rectangle, inset your coordinates by 0.5 pixels (or, rather, by half of the stroke width you want to use).
Also, don't forget that when drawing an image that's meant to be displayed on a retina screen with scale=2, coordinates that are 0.5 units off are actually still on pixel boundaries. So if you know it's retina, you can avoid rounding to fully integral coordinates when the nearest half-unit coordinate is fine.