The image below how all my records look in postgreSQL. I can't figure out why the geom field is so long, I can't make heads or tails of the number either. Is it the binary representation? Any help is appreciated
Geometry Types are stored in WKB (Well-Known Binary) form within PostGIS.
WKB form is a string of bytes that encode the information about this geometry. It holds information such as what kind of geometry is described (point, line, polygon, etc) as well as the actual information needed to represent the geometry itself.
The first byte in the stream identifies how the binary values are represented, either: NDR (Network Data Representation or XDR (eXtended Data Representation). The difference between the two encodings is byte order. NDR is little endian, which means that an unsigned integer – a 32 bit data type that encodes a nonnegative integer - stores the least significant byte first, while a double – a 64 bit double precision data type that encodes a double precision number using the IEEE 54 double precision format - stores the sign bit as the last byte. XDR is big endian, so the byte order is reversed.
The next component in the stream indicates the geometry type. Values from 1 through 7 indicate Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, and GeometryCollection.
If a geometry consists of multiple geometries, additional bytes indicate how many geometries there are.
The next byte component indicates the number of points in the first shape, followed by the X,Y coordinates of each of the points. For each additional shape, a byte indicates the number of points, followed by bytes defining each point’s coordinate values.
Alternatively, WKT (Well-Known Text) is a representation of geometry that would offer a better description for a human observer. WKT can be displayed by using the method ST_AsText in postGIS. There is a listing of examples of WKT representations for various geometry types in the postGIS documentation here.
If you would like more information about the WKB, see this helpful explanation of the representation.
Related
I have an image with the format R8G8B8A8 (Unorm).
I want to write uint data on it (to be able to use atomic function).
So, when I want to "write" it, I am using in the glsl :
layout(set = 0, binding = 2, r32ui) restrict writeonly uniform uimage3D dst;
However, when I am performing something like
imageStore(dst, coords, uvec4(0xffffffff));
RenderDoc (and my app as well) tells me that all my values are 0 (instead of 1.0 (255 unorm)).
If I replace the r32ui by rgba8 everything works fine but I can not use atomic values. So I wonder if it is possible to do such thing. (However, if I use a r32f instead of rgba8, it works fine as well).
Do you have any solution?
Vulkan specification guarantees that atomic operations must be supported for storage images (VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT) with only R32_UINT and R32_SINT formats. Implementations may add such support for other formats as well but it's not obligatory. So it's nothing strange that atomic operations don't work with rgba8 format.
Next. You can create an image view with a different format than the format of the image. In such case the image view's format must be compatible with the image's format. In case of the R8G8B8A8 format, both SINT and UINT R32 formats are compatible (have the same number of bits). But to be able to create an image view with a different format, image itself must be created with a VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT flag.
One last thing - there is a note in the specification about format compatibility/mutable images:
Values intended to be used with one view format may not be exactly
preserved when written or read through a different format. For
example, an integer value that happens to have the bit pattern of a
floating point denorm or NaN may be flushed or canonicalized when
written or read through a view with a floating point format.
Similarly, a value written through a signed normalized format that has
a bit pattern exactly equal to -2^b may be changed to -2^b + 1 as
described in Conversion from Normalized Fixed-Point to Floating-Point.
Maybe this is the problem? Though it seems that there should be no conversion between rgba8 (unorm) and r32 (uint). Did validation layers report any warnings or errors? What layout is Your image in when You try to store data in it? Don't forget that:
Load and store operations on storage images can only be done on images
in the VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR or VK_IMAGE_LAYOUT_GENERAL
layout.
I have a bit array representing an image mask, stored in a uint8_t[] container array, in row first order. Hence, for each byte, I have 8 pixels.
Now, I need to render this with OpenGL ( >= 3.0 ). A positive bit is drawn as a white pixel and a negative bit is drawn as a black pixel.
How could I do this? Please
The first idea that comes to mind is to develop a specific shader for this. Can anyone give some hints on that?
You definitely must write a shader for this. First and foremost you want to prevent the OpenGL implementation to reinterpret the integer bits of your B/W bitmap as numbers in a certain range and map them to [0…1] floats. Which means you have to load your bits into an integer image format. Since your image format is octet groups of binary pixels (byte is a rather unspecific term and can refer to any number of bits, though 8 bits is the usual), a single channel format 8 bits format seems the right choice. The OpenGL-3 moniker for that is GL_R8UI. Keep in mind that the "width" of the texture will be 1/8th of the actual width of your B/W image. Also for unnormalized access you must use a usampler (for unsigned) or an isampler (for signed) (thanks #derhass for noticing that this was not properly written here).
To access individual bits you use the usual bit manipulation operators. Since you don't want your bits to become filtered, texel fetch access must be used. So to access the binary pixel at integer location x,y the following would be used.
uniform usampler2D tex;
uint shift = x % 8;
uint mask = 1 << shift;
uint octet = texelFetch(tex, ivec2(x/8,y)).r;
value = (octet & mask) >> shift;
The best solution would be to use a shader, you could also hack something like this:
std::bitset<8> bits = myuint;
Then get the values of the single bits with bits.at(position) and finally do a simple point drawing.
I'm attempting to convert 12-bit RGGB color values into 8-bit RGGB color values, but with my current method it gives strange results.
Logically, I thought that simply dividing the 12-bit RGGB into 8-bit RGGB would work and be pretty simple:
// raw_color_array contains R,G1,G2,B in a bayer pattern with each element
// ranging from 0 to 4096
for(int i = 0; i < array_size; i++)
{
raw_color_array[i] /= 16; // 4096 becomes 256 and so on
}
However, in practice this actually does not work. Given, for example, a small image with water and a piece of ice in it you can see what actually happens in the conversion (right most image).
Why does this happen? and how can I get the same (or close to) image on the left, but as 8-bit values instead? Thanks!
EDIT: going off of #MSalters answer, I get a better quality image but the colors are still drasticaly skewed. What resources can I look into for converting 12-bit data to 8-bit data without a steep loss in quality?
It appears that your raw 12 bits data isn't on a linear scale. That is quite common for images. For a non-linear scale, you can't use a linear transformation like dividing by 16.
A non-linear transform like sqrt(x*16) would also give you an 8 bits value. So would std::pow(x, 12.0/8.0)
A known problem with low-gradient images is that you get banding. If your images has an area where the original value varies from say 100 to 200, the 12-to-8 bit reduction will shrink that to less than 100 different values. You get rounding , and with naive (local) rounding you get bands. Linear or non-linear, there will then be some inputs x that all map to y, and some that map to y+1. This can be mitigated by doing the transformation in floating point, and then adding a random value between -1.0 and +1.0 before rounding. This effectively breaks up the band structure.
After you clarified that this 12bit data is only for one color, here is my simple answer:
Since you want to convert its value to its 8 bit equivalent, it obviously means you lost some of the data (4bits). This is the reason why you are not getting the same output.
After clarification:
If you want to retain the actual colour values!
Apply de-mosaicking in the 12 Bit image and then scale the resultant data to 8 - Bit. So that the colour loss due to de-mosaicking will be less compared to the previous approach.
You say that your 12-bits represent 2^12 bits of one colour. That is incorrect. There are reds, greens and blues in your image. Look at the histogram. I made this with ImageMagick at the command line:
convert cells.jpg histogram:png:h.png
If you want 8-bits per pixel, rather than trying to blindly/statically apportion 3 bits to Green, 2 bits to Red and 3 bits to Blue, you would probably be better off going with an 8-bit palette so you can have 250+ colours of all variations rather than restricting yourself to just 8 blue shades, 4 reds an 8 green. So, like this:
convert cells.jpg -colors 254 PNG8:result.png
Here is the result of that beside the original:
The process above is called "quantisation" and if you want to implement it in C/C++, there is a writeup here.
I've been using SDL for input on ios but whenever I get the finger's coordinates from the event structure they are normalized. Now I'm wondering how I change these normalized coordinates to device space so I can use?
Examples of how they look normalized:
2.8026e-45
"Normalized", in this instance, simply means "between 0 and 1". That is a really, really unusually small number to be getting out of the structure, regardless of the units, and suggests that the data is either uninitialized, or being interpreted using the wrong typecasting (if you reinterpreted the bits of the integer 2 as a float32, you would get that value).
I have an array of point data, the values of points are represented as x co-ordinate and y co-ordinate.
These points could be in the range of 500 upto 2000 points or more.
The data represents a motion path which could range from the simple to very complex and can also have cusps in it.
Can I represent this data as one spline or a collection of splines or some other format with very tight compression.
I have tried representing them as a collection of beziers but at best I am getting a saving of 40 %.
For instance if I have an array of 500 points , that gives me 500 x and 500 y values so I have 1000 data pieces.
I around 100 quadratic beziers from this. each bezier is represented as controlx, controly, anchorx, anchory.
which gives me 100 x 4 = 400 pcs of data.
So input = 1000pcs , output = 400pcs.
I would like to further tighen this, any suggestions?
By its nature, spline is an approximation. You can reduce the number of splines you use to reach a higher compression ratio.
You can also achieve lossless compression by using some kind of encoding scheme. I am just making this up as I am typing, using the range example in previous answer (1000 for x and 400 for y),
Each point only needs 19 bits (10 for x, 9 for y). You can use 3 bytes to represent a coordinate.
Use 2 byte to represent displacement up to +/- 63.
Use 1 byte to represent short displacement up to +/- 7 for x, +/- 3 for y.
To decode the sequence properly, you would need some prefix to identify the type of encoding. Let's say we use 110 for full point, 10 for displacement and 0 for short displacement.
The bit layout will look like this,
Coordinates: 110xxxxxxxxxxxyyyyyyyyyy
Dislacement: 10xxxxxxxyyyyyyy
Short Displacement: 0xxxxyyy
Unless your sequence is totally random, you can easily achieve high compression ratio with this scheme.
Let's see how it works using a short example.
3 points: A(500, 400), B(550, 380), C(545, 381)
Let's say you were using 2 byte for each coordinate. It will take 16 bytes to encode this without compression.
To encode the sequence using the compression scheme,
A is first point so full coordinate will be used. 3 bytes.
B's displacement from A is (50, -20) and can be encoded as displacement. 2 bytes.
C's displacement from B is (-5, 1) and it fits the range of short displacement 1 byte.
So you save 10 bytes out of 16 bytes. Real compression ratio is totally depending on the data pattern. It works best on points forming a moving path. If the points are random, only 25% saving can be achieved.
If for example you use 32-bit integers for point coords and there is range limit, like x: 0..1000, y:0..400, you can pack (x, y) into a single 32-bit variable.
That way you achieve another 50% compression.
You could do a frequency analysis of the numbers you are trying to encode and use varying bit lengths to represent them, of course here I am vaguely describing Huffman coding
Firstly, only keep enough decimal points in your data that you actually need. Removing these would reduce your accuracy, but its a calculated loss. To do that, try converting your number to a string, locating the dot's position, and cutting of those many characters from the end. That could process faster than math, IMO. Lastly you can convert it back to a number.
150.234636746 -> "150.234636746" -> "150.23" -> 150.23
Secondly, try storing your data relative to the last number ("relative values"). Basically subtract the last number from this one. Then later to "decompress" it you can keep an accumulator variable and add them up.
A A A A R R
150, 200, 250 -> 150, 50, 50