How would I store OpenCV rotatedRect's in a database - database

I have a need to store data from an openCV rotatedRect into a database and also be able to search through them. In short, a rotated rectangle in openCV consists of:
a set of four points representing the four corners of the rectangle
the angle the rect is rotated at
the center point of the rect
the bounding box of the rotated rect
I'm not sure if this is more than one question, but I think they relate to each other nicely:
how would I represent this in PostgreSQL? One record will consist of (among other fields) several hundred rotated rect's in a sequential fashion. Does this look sensible?
// the rotated rect type
CREATE TYPE rotated_rect AS {
angle real,
points point ARRAY[4],
center point,
bounding_box box,
width real,
height real
};
// the item that will have several hundred rotated_rects
CREATE TABLE foo {
...,
rotated_rects rotated_rect[],
...
};
How would I then go about searching this data? I'd like to be able to compare one list of rotated rect's with those stored in the database for each record - quite possibly just the center-point of each rotated rect at this stage - and pick out the record/s which either match exactly, or are the closest in position. Would this require PostGIS for spatial data? Or would I have to read all the records into memory and search position manually?
EDIT: Added a stab at a type for postgresql.

Related

Any way to get an accurate ST_MinimumBoundingCircle calculation on a geography?

ST_MinimumBoundingCircle accepts the geometry type, i.e. planar geometry. Is there any way to get the minimum bounding circle of a geography collection using PostGIS? That is, the minimum bounding circle of a collection of features on the sphere. Simply converting a geography to a geometry and the resulting bounding circle back to geography does not create an accurate result. This guy (via https://observablehq.com/#fil/spherical-smallest-circle-problem) seems to have it worked out in JavaScript by
Going forward (to the stereographic plane), we compute the circumcenter of three projected points on each circle. Going backward, we use d3-geo-voronoi to retrieve the enclosing circle’s center.
Is there any built-in way to do this on PostGIS or achieve the same result using equivalent functions?

Geometry operations on latitude/longitude coordinates

My question is probably a duplicate, but all the answers I have seen so far do not satisfy me or still leaves me in doubt.
I have a web application that uses Google Maps API to draw and save shapes (circles and polygons) in a SQL Server DB with the geometry data type (where I save lat/long coordinates) and an SRID = 4326.
My objective is to later on, determine if a point is contained in the area of those circles/polygons thanks to SQL function geometry::ST_Intersects().
I have been told so far that my method wouldn't work because I am using geometry instead of geography. But to my surprise... after checking with a few tests, it works perfectly well with geometry and I am not able to understand why or how?
Could somebody explain to me why the geometry type works well with operations on lat/long whereas geography would be more suited?
I post as an answer because as comment is too long
geometry works well to the extent that your intersections are approximable to flat intersections.
the difference between geometry and geography consists in the fact that the former works by hypothesizing to work on plane surfaces the second on spherical surfaces. in the case in which the polygons in question are related to small areas in the order of a few thousand meters geometry works very well. the difference between measured distance by imagining that the points lie on a plane or that the points lie on the earth's sphere is so small as to be negligible. Unlike the question if the points are a few hundred kilometers in this case the distance measured in the plane or on the sphere is very different and proportionally is also the result of the intersection between these areas

Connect points to plane/Draw Polygon

I'm currently working on a project where I want to draw different mathematical objects onto a 3D cube. It works as it should for Points and Lines given as a vector equation. Now I have a plane given as a parametric equation. This plane can be somewhere in the 3D space and may be visible on the screen, which is this 3D cube. The cube acts as an AABB.
First thing I needed to know was whether the plane intersects with the cube. To do this I made lines who are identical to the edges of this cube and then doing 12 line/plane intersections, calculating whether the line is hit inside the line segment(edge) which is part of the AABB. Doing this I will get a set of Points defining the visible part of the plane in the cube which I have to draw.
I now have up to 6 points A, B, C, D, E and F defining the polygon ABCDEF I would like to draw. To do this I want to split the polygon into triangles for example: ABC, ACD, ADE, AED. I would draw this triangles like described here. The problem I am currently facing is, that I (believe I) need to order the points to get correct triangles and then a correctly drawn polygon. I found out about convex hulls and found QuickHull which works in three dimensional space. There is just one problem with this algorithm: At the beginning I need to create a three dimensional simplex to have a starting point for the algorithm. But as all my points are in the same plane they simply form a two dimensional plane. Thus I think this algorithm won't work.
My question is now: How do I order these 3D points resulting in a polygon that should be a 2D convex hull of these points? And if this is a limitation: I need to do this in C.
Thanks for your help!
One approach is to express the coordinates of the intersection points in the space of the plane, which is 2D, instead of the global 3D space. Depending on how exactly you computed these points, you may already have these (say (U, V)) coordinates. If not, compute two orthonormal vectors that belong to the plane and take the dot products with the (X, Y, Z) intersections. Then you can find the convex hull in 2D.
The 8 corners of the cube can be on either side of the plane, and have a + or - sign when the coordinates are plugged in the implicit equation of the plane (actually the W coordinate of the vertices). This forms a maximum of 2^8=256 configurations (of which not all are possible).
For efficiency, you can solve all these configurations once for all, and for every case list the intersections that form the polygon in the correct order. Then for a given case, compute the 8 sign bits, pack them in a byte and lookup the table of polygons.
Update: direct face construction.
Alternatively, you can proceed by tracking the intersection points from edge to edge.
Start from an edge of the cube known to traverse the plane. This edge belongs to two faces. Choose one arbitrarily. Then the plane cuts this face in a triangle and a pentagon, or two quadrilaterals. Go to the other the intersection with an edge of the face. Take the other face bordered by this new edge. This face is cut in a triangle and a pentagon...
Continuing this process, you will traverse a set of faces and corresponding segments that define the section polygon.
In the figure, you start from the intersection on edge HD, belonging to face DCGH. Then move to the edge GC, also in face CGFB. From there, move to edge FG, also in face EFGH. Move to edge EH, also in face ADHE. And you are back on edge HD.
Complete discussion must take into account the case of the plane through one or more vertices of the cube. (But you can cheat by slightly translating the plane, constructing the intersection polygon and removing the tiny edges that may have been artificially created this way.)

What is the best way to store the data for a Mahjong tile set?

I am planning a kids' version of Mahjong Solitaire (starting with just the Turtle board layout and working my way from there). I am trying to wrap my head around how to store the data for each layer of the Turtle layout tileset. See here for an example: http://icarus.cs.weber.edu/~dab/cs3230/labs/lab.5/tile_layers.pdf
Ordinarily I'd use a 2D array for each layer, and a 1D array of the layers, from 0 (bottom-most) to 4 (topmost), with the allowance for layers above that (5, 6, ...). However, there are the tiles that occupy more than one row and/or column at once. For example, in Layer 0 (bottom-most), the far left tile and the 2 far right tiles occupy two rows at once, and the single tile in Layer 4 (topmost) occupies two columns and two rows at the same time.
What is the best data model to store this sort of tileset? Should each tile have a flag for shifting it halfway into the next row and column?
I'm thinking, there is a Tile object, each instance of which represents 1 of the 144 tiles on the board. Then all tiles are arranged in layers as I described above (2D array for each layer, all layers stored in a 1D array).
Note: I am considering using Javascript & HTML5 for this project. It won't be something I release to the public, just a programming exercise.
Is this the best method? Am I missing something?
I would indeed use a finer grid as alikox suggested. I would use a 2 times finer grid, give each tile an unique id, so one regular tile now uses four squares of the grid, when you have to delete one tile, you only have to check for surrounding squares with the same id and delete them as well.
There would be more than one way to implement this, you can set x, y and z coordinates of each tile for example.
class Tile {
int x
int y
int z
}

Antipole Clustering

I made a photo mosaic script (PHP). This script has one picture and changes it to a photo buildup of little pictures. From a distance it looks like the real picture, when you move closer you see it are all little pictures. I take a square of a fixed number of pixels and determine the average color of that square. Then I compare this with my database which contains the average color of a couple thousand of pictures. I determine the color distance with all available images. But to run this script fully it takes a couple of minutes.
The bottleneck is matching the best picture with a part of the main picture. I have been searching online how to reduce this and came a cross “Antipole Clustering.” Of course I tried to find some information on how to use this method myself but I can’t seem to figure out what to do.
There are two steps. 1. Database acquisition and 2. Photomosaic creation.
Let’s start with step one, when this is all clear. Maybe I understand step 2 myself.
Step 1:
partition each image of the database into 9 equal rectangles arranged in a 3x3 grid
compute the RGB mean values for each rectangle
construct a vector x composed by 27 components (three RGB components for each rectangle)
x is the feature vector of the image in the data structure
Well, point 1 and 2 are easy but what should I do at point 3. How do I compose a vector X out of the 27 components (9 * R mean, G mean, B mean.)
And when I succeed to compose the vector, what is the next step I should do with this vector.
Peter
Here is how I think the feature vector is computed:
You have 3 x 3 = 9 rectangles.
Each pixel is essentially 3 numbers, 1 for each of the Red, Green, and Blue color channels.
For each rectangle you compute the mean for the red, green, and blue colors for all the pixels in that rectangle. This gives you 3 numbers for each rectangle.
In total, you have 9 (rectangles) x 3 (mean for R, G, B) = 27 numbers.
Simply concatenate these 27 numbers into a single 27 by 1 (often written as 27 x 1) vector. That is 27 numbers grouped together. This vector of 27 numbers is the feature vector X that represents the color statistic of your photo. In the code, if you are using C++, this will probably be an array of 27 number or perhaps even an instance of the (aptly named) vector class. You can think of this feature vector as some form of "summary" of what the color in the photo is like. Roughly, things look like this: [R1, G1, B1, R2, G2, B2, ..., R9, G9, B9] where R1 is the mean/average of red pixels in the first rectangle and so on.
I believe step 2 involves some form of comparing these feature vectors so that those with similar feature vectors (and hence similar color) will be placed together. Comparison will likely involve the use of the Euclidean distance (see here), or some other metric, to compare how similar the feature vectors (and hence the photos' color) are to each other.
Lastly, as Anony-Mousse suggested, converting your pixels from RGB to HSB/HSV color would be preferable. If you use OpenCV or have access to it, this is simply a one liner code. Otherwise wiki HSV etc. will give your the math formula to perform the conversion.
Hope this helps.
Instead of using RGB, you might want to use HSB space. It gives better results for a wide variety of use cases. Put more weight on Hue to get better color matches for photos, or to brightness when composing high-contrast images (logos etc.)
I have never heard of antipole clustering. But the obvious next step would be to put all the images you have into a large index. Say, an R-Tree. Maybe bulk-load it via STR. Then you can quickly find matches.
Maybe it means vector quantization (vq). In vq the image isn't subdivide in rectangles but in density areas. Then you can take a mean point of this cluster. First off you need to take all colors and pixels separate and transfer it to a vector with XY coordinate. Then you can use a density clustering like voronoi cells and get the mean point. This point can you compare with other pictures in the database. Read here about VQ: http://www.gamasutra.com/view/feature/3090/image_compression_with_vector_.php.
How to plot vector from adjacent pixel:
d(x) = I(x+1,y) - I(x,y)
d(y) = I(x,y+1) - I(x,y)
Here's another link: http://www.leptonica.com/color-quantization.html.
Update: When you have already computed the mean color of your thumbnail you can proceed and sort all the means color in a rgb map and using the formula I give to you to compute the vector x. Now that you have a vector of all your thumbnails you can use the antipole tree to search for a thumbnail. This is possbile because the antipole tree is something like a kd-tree and subdivide the 2d space. Read here about antipole tree: http://matt.eifelle.com/2012/01/17/qtmosaic-0-2-faster-mosaics/. Maybe you can ask the author and download the sourcecode?

Resources