Is there a difference between WKB and the hex value returned in PostGIS - postgresql

I've been doing some experimenting with PostGIS, and here's what I've noticed:
Suppose I have a table defined as follows:
CREATE TABLE IF NOT EXISTS geomtest (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
geom geometry(POLYGON, 4326) NOT NULL
);
And I add the following polygon:
SRID=4326;POLYGON((0 0,0 10,10 10,10 0,0 0))
If I query the geom column on its own, I get a Hex representation of the geometry. If I instead call ST_AsBinary(geom), I get a binary representation.
However, when I convert both the hex and binary representations to an array of bytes, the results I get are slightly different. The first comment is the result I get by converting the hex into binary, and the next is straight from ST_AsBinary()
//[1 3 0 0 32 230 16 0 0 1 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 36 64 0 0 0 0 0 0 36 64 0 0 0 0 0 0 36 64 0 0 0 0 0 0 36 64 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
//[1 3 0 0 0 1 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 36 64 0 0 0 0 0 0 36 64 0 0 0 0 0 0 36 64 0 0 0 0 0 0 36 64 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
As you can see, the first 4 bytes are identical; representing whether it's in big or little endian, and the type of geometry (3, in this case a Polygon). The rest of the bytes are the same too. The only difference is there are a few extra bytes added after the first 4.
I wondered if this had to do with representing the projection (SRID=4326), but I haven't found any evidence to that.
If someone could shed some light on this, I'd greatly appreciate it.

I didn't examine the bytes, but I am sure that the difference is the SRID that's not included in the WKB format.
Try st_asewkb instead.

Related

How to correctly use the col2im function?

This function is confusing to use, and it always gives me an error:
To RESHAPE the number of elements must not change.
That's my code:
im=im2col(zeros(300,300),[3 3]);
im(:,9)=ones(9,1);
im=col2im(im,[3 3],[300 300]);
Basically, this code just gets the block at index 6, replaces it with ones, and reassembles it back into the original image. What's wrong with this code?
It seems you want to create distinct blocks from your input array, change single blocks, and rearrange them. (Your target size is the same as your input array size.) So, you must use the distinct parameter in both, im2col as well as col2im:
blk_size = [3, 3];
im = zeros(9, 9)
temp = im2col(im, blk_size, 'distinct');
temp(:, 3) = ones(prod(blk_size), 1);
im2 = col2im(temp, [3 3], size(im), 'distinct')
Output:
im =
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
im2 =
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0
1 1 1 0 0 0 0 0 0
When using im2col with the sliding parameter, which is also the default, if no parameter is set at all, there'll be a lot more columns in the result than can be rearranged to the input array size, cf. the Tips section on im2col.
Hope that helps!

Avoid restarting for-loop

I have a folder with pictures. For each picture, I want to take the maximum value and add it to a new matrix (I created a zeros-matrix, so the zeroes will be replaced with the new values).
This is my code:
function handles = original(hObject, eventdata, handles)
handles.weed=handles.selected;
pic=imread(handles.me);
handles.pic=pic;
axes(handles.axes1)
imshow(pic);
num=max(pic(:))
zeroMat = zeros(1,70);
handles.zeroMat = zeroMat;
for i =1:3
if zeroMat(1,i)~= 0;
i=i+1
else
zeroMat(1,i)=num
break
end
end
zeroMat(1,i)=num
Every time I select a new picture, the zeromat restarts itself to a new zeros-matrix. I know why it happens, but unfortunately I don't know how to overcome it.
This is the output:
pic1:
zeroMat =
Columns 1 through 20
255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 21 through 40
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 41 through 60
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 61 through 70
0 0 0 0 0 0 0 0 0 0
pic2:
Columns 1 through 20
203 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 21 through 40
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 41 through 60
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 61 through 70
0 0 0 0 0 0 0 0 0 0
I can't tell how this function is being invoked, so can't advice how to change up the logic. A rough fix could be to include the line
if ~isfield(handles,'zeroMat')
handles.zeroMat = zeros(1,70);
end % if
which should create handles.zeroMat the first time the function is run. You could then do something like
firstNonzero = find(handles.zeroMat > 0, 1, 'first'); % 'first' not needed, default
handles.zeroMat(firstNonzero) = max(pic(:));

How to Count Total Number of pixel of padded value used in image(Padded Image)?

I have one binary image so it has only 2 value like 0 and 1. After, I convert this into a padded image of different values, like the image will have curve shape. I took a 3 X 3 matrix of value and if i get curve shape then I padded the image with 1, or any number. I use 15 different types shape values like junction point, end point etc.
After, I give the values 1 to 15 - or the appropriate number according its shape. As such, I am getting an image like:
Figure
0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0
I would like to count how many 1s there are in the image, followed by 2s, 3s, etc. up to 15. For example,
as shown in the figure, if the pad number was 5, the total number of pixels would be 3. If the pad number was 1, the total number of pixels would be 6.
Use histc:
>> im = [ 0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 5 0 0 0 0 0 0 0 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 ]; %// data
>> values = 1:15; %// possible values
>> count = histc(im(:), values)
count =
6 %// number of 1's
0 %// number of 2's, etc
0
0
3
0
0
0
0
0
0
0
0
0
0
Or compute it manually with bsxfun:
>> count = sum(bsxfun(#eq, im(:), values(:).'), 1)
>> count =
6 0 0 0 3 0 0 0 0 0 0 0 0 0 0
I can also suggest using accumarray:
im = [0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 5 0 0 0 0 0 0 0 1 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0 5 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 ]; %// data - borrowed from Luis Mendo
counts = accumarray(im(:) + 1, 1);
counts(1) = []
counts =
6
0
0
0
3
Note we have to offset by 1 as accumarray starts indexing the output array at 1. Because you want to disregard the 0s, I simply take the counts result and remove the first entry. This result agrees with what you are seeking. The first element is how many 1s we have encountered, which is 6. The last element is how many 5s you have encountered, which is 3. Because 5 is the largest number encountered in your image, we can say that all symbols after 5 (6, 7, 8, ..., 15) have a count of 0.

matlab running a video, .txt and .mat

I want to run a video in matlab but I got some problems while doing so. I tried to run the video while using 'load' and then 'implay'. But I got this problem. My movie file is a textfile which constains mostly of zeros, arranged diagonally.
When I load this file in matlab I get different values. Here a snippet:
0 0 0 0 0 0 0 0 0 0 0
0 0 -5 0 0 -5.00097609500000 0 0 0 0 0
0 0 -10 0 0 -10.0019423800000 0 0 0 0 0
0 0 -15 0 0 -15.0028988550000 0 0 0 0 0
0 0 -20 0 0 -20.0038455200000 0 0 0 0 0
0 0 -25 0 0 -25.0047823750000 0 0 0 0 0
0 0 -30 0 0 -30.0057094200000 0 0 0 0 0
0 0 -35 0 0 -35.0066266550000 0 0 0 0 0
0 0 -40 0 0 -40.0075340800000 0 0 0 0 0
0 0 -45 0 0 -45.0084316950000 0 0 0 0 0
I dont know why I get a mat.file with different values and why my movie does not run. I wanted to upload the original textfile but this not possible.
When I try to run I receive following message: There is not enough memory to open 'filename' in the Editor.
I hope you guys can help me!

Easy Way To Accomplish Data Compression in MATLAB?

I am working on an assignment where I have to take a large matrix containing data, and somehow compress the data so that it will be in a form of more manageable size. However, the data needs to be re-utilized as input to something else. (A toolbox, for example). Here's what I've done so far. For this example matrix, I use the find function to give me a matrix of all the indices where the values are non-zero. But I have no idea as to how to use it as input so that the original figure information is retained. I was curious if other folks had any other better (simple) solutions to this.
number_1 = [0 0 0 0 0 0 0 0 0 0 ...
0 0 1 1 1 1 0 0 0 0 ...
0 1 1 0 1 1 0 0 0 0 ...
0 1 1 0 1 1 0 0 0 0 ...
0 0 0 0 1 1 0 0 0 0 ...
0 0 0 0 1 1 0 0 0 0 ...
0 0 0 0 1 1 0 0 0 0 ...
0 0 0 0 1 1 0 0 0 0 ...
0 0 0 0 1 1 0 0 0 0 ...
0 0 0 0 1 1 0 0 0 0 ...
0 0 0 0 1 1 0 0 0 0 ...
0 1 1 1 1 1 1 1 1 0 ...
0 0 0 0 0 0 0 0 0 0];
number = number_1;
compressed_number = find(number);
compressed_number = compressed_number';
disp(compressed_number)
When you have only ones and zeros, and the fill factor is not terribly small, your best bet is to store the numbers as binary numbers; if you need the original size, save it separately. I have expanded the code, showing the intermediate steps a little more clearly, and also showing the amount of storage needed for the different arrays. Note - I reshaped your data into a 13x10 array because it displays better.
number_1 = [0 0 0 0 0 0 0 0 0 0 ...
0 0 1 1 1 1 0 0 0 0 ...
0 1 1 0 1 1 0 0 0 0 ...
0 1 1 0 1 1 0 0 0 0 ...
0 0 0 0 1 1 0 0 0 0 ...
0 0 0 0 1 1 0 0 0 0 ...
0 0 0 0 1 1 0 0 0 0 ...
0 0 0 0 1 1 0 0 0 0 ...
0 0 0 0 1 1 0 0 0 0 ...
0 0 0 0 1 1 0 0 0 0 ...
0 0 0 0 1 1 0 0 0 0 ...
0 1 1 1 1 1 1 1 1 0 ...
0 0 0 0 0 0 0 0 0 0];
n1matrix = reshape(number_1, 10, [])'; % make it nicer to display;
% transpose because data is stored column-major (row index changes fastest).
disp('the original data in 13 rows of 10:');
disp(n1matrix);
% create a matrix with 8 rows and enough columns
n1 = numel(number_1);
nc = ceil(n1/8); % "enough columns"
npad = zeros(8, nc);
npad(1:n1) = number_1; % fill the first n1 elements: the rest is zero
binVec = 2.^(7-(0:7)); % 128, 64, 32, 16, 8, 4, 2, 1 ... powers of two
compressed1 = uint8(binVec * npad); % 128 * bit 1 + 64 * bit 2 + 32 * bit 3...
% showing what we did...
disp('Organizing into groups of 8, and calculated their decimal representation:')
for ii = 1:nc
fprintf(1,'%d ', npad(:, ii));
fprintf(1, '= %d\n', compressed1(ii));
end
% now the inverse operation: using dec2bin to turn decimals into binary
% this function returns strings, so some further processing is needed
% original code used de2bi (no typo) but that requires a communications toolbox
% like this the code is more portable
decompressed = dec2bin(compressed1);
disp('the string representation of the numbers recovered:');
disp(decompressed); % this looks a lot like the data in groups of 8, but it's a string
% now we turn them back into the original array
% remember it is a string right now, and the values are stored
% in column-major order so we need to transpose
recovered = ('1'==decompressed'); % all '1' characters become logical 1
display(recovered);
% alternative solution #1: use logical array
compressed2 = (n1matrix==1);
display(compressed2);
recovered = double(compressed2); % looks just the same...
% other suggestions 1: use find
compressed3 = find(n1matrix); % fewer elements, but each element is 8 bytes
compressed3b = uint8(compressed); % if you know you have fewer than 256 elements
% or use `sparse`
compressed4 = sparse(n1matrix);
% or use logical sparse:
compressed5 = sparse((n1matrix==1));
whos number_1 comp*
the original data in 13 rows of 10:
0 0 0 0 0 0 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 1 1 0 1 1 0 0 0 0
0 1 1 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 1 1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0
Organizing into groups of 8, and their decimal representation:
0 0 0 0 0 0 0 0 = 0
0 0 0 0 1 1 1 1 = 15
0 0 0 0 0 1 1 0 = 6
1 1 0 0 0 0 0 1 = 193
1 0 1 1 0 0 0 0 = 176
0 0 0 0 1 1 0 0 = 12
0 0 0 0 0 0 1 1 = 3
0 0 0 0 0 0 0 0 = 0
1 1 0 0 0 0 0 0 = 192
0 0 1 1 0 0 0 0 = 48
0 0 0 0 1 1 0 0 = 12
0 0 0 0 0 0 1 1 = 3
0 0 0 0 0 0 0 0 = 0
1 1 0 0 0 0 0 1 = 193
1 1 1 1 1 1 1 0 = 254
0 0 0 0 0 0 0 0 = 0
0 0 0 0 0 0 0 0 = 0
the string representation of the numbers recovered:
00000000
00001111
00000110
11000001
10110000
00001100
00000011
00000000
11000000
00110000
00001100
00000011
00000000
11000001
11111110
00000000
00000000
compressed2 =
0 0 0 0 0 0 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 1 1 0 1 1 0 0 0 0
0 1 1 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 1 1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0
recovered =
0 0 0 0 0 0 0 0 0 0
0 0 1 1 1 1 0 0 0 0
0 1 1 0 1 1 0 0 0 0
0 1 1 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0
0 1 1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0
Name Size Bytes Class Attributes
compressed1 1x17 17 uint8
compressed2 13x10 130 logical
compressed3 34x1 272 double
compressed3b 34x1 34 uint8
compressed4 13x10 632 double sparse
compressed5 13x10 394 logical sparse
number_1 1x130 1040 double
As you can see, the original array takes 1040 bytes; the compressed array takes 17. You get almost 64x compression (not quite because 132 is not a multiple of 8); only a very sparse dataset would be better compressed by some other means. The only thing that gets close (and that is super fast) is
compressed3b = uint8(find(number_1));
At 34 bytes, it is definitely a contender for small arrays (< 256 elements).
Note - when you save data in Matlab (using save(fileName, 'variableName')), some compression happens automatically. This leads to an interesting and surprising result. When you take each of the above variables and save them to file using Matlab's save, the file sizes in bytes become:
number_1 195
compressed1 202
compressed2 213
compressed3 219
compressed3b 222
compressed4 256
compressed5 252
On the other hand, if you create a binary file yourself using
fid = fopen('myFile.bin', 'wb');
fwrite(fid, compressed1)
fclose(fid)
It will by default write uint8, so the file sizes are 130, 17, 130, 34, 34 -- sparse arrays cannot be written in this way. It still shows the "complicated" compression having the best compression.
First of all, you can use the find function to get all non-zero indices of your array, instead of doing it manually. More info here: http://www.mathworks.com/help/matlab/ref/find.html
Anyways, you will need not only matrix but also the original size. So when you pass matrix into whatever, you must also pass in length(number_1). This is because matrix will not tell you how many 0s there were after the last 1. You can figure it out by subtracting the last value of matrix from the original length (there might be an off-by-one error there).