From: Eshbonzie on
Hi guys,

Im doing some sort of algorithm on the pixels of an image. This algorithm returns a 26 bit wide signature for each pixel, so I have 2^26 different combination. My target is to save the pixel value as well as a counter for the number of occurences for this signature in an array address corresponding to the signature value. Memory usage and efeciency of the algorithm is a critical issue.

For the x and y value of each pixel I need 20 bits and for the counter I need 18 bits. All together are 38 bits (around 5 bytes).

I dont have so much experience with matlab, but I know that if I define a new array with 2^26 addresses, each one will correspond to 8 bytes of data (what I need is only 5).

so
1) is there a way to manipulate memory so that each address points to only 5 bytes of data? (I know about uint32 and uint64 but still one is 4 bytes and the other is 8 bytes)

2) howa can I access each byte inside each address bitwise and define that the first 10 bits corresponds to x value of the pixel and so on

Any help or hints about functions to use especially for the bitwise manipulation of the data inside my array is greatly appreciated.

Thanks!!
From: Jan Simon on
Dear Eshbonzie,

> Im doing some sort of algorithm on the pixels of an image. This algorithm returns a 26 bit wide signature for each pixel, so I have 2^26 different combination. My target is to save the pixel value as well as a counter for the number of occurences for this signature in an array address corresponding to the signature value. Memory usage and efeciency of the algorithm is a critical issue.
>
> For the x and y value of each pixel I need 20 bits and for the counter I need 18 bits. All together are 38 bits (around 5 bytes).
>
> I dont have so much experience with matlab, but I know that if I define a new array with 2^26 addresses, each one will correspond to 8 bytes of data (what I need is only 5).
>
> so
> 1) is there a way to manipulate memory so that each address points to only 5 bytes of data? (I know about uint32 and uint64 but still one is 4 bytes and the other is 8 bytes)
> 2) howa can I access each byte inside each address bitwise and define that the first 10 bits corresponds to x value of the pixel and so on

Your demands are not getting clear to me.
You need 20 bits for the x and y values of each pixel. Does this mean, that your picture has 2^20 pixels? Why does the counter need 18bits, if you can get 2^26 different signatures?
You do not have to store 2^26 *addresses* with 8 byte elements when you allocate an array. Storing the first address is enough and you can access all elements with 32bit addressing.
5 Byte addressing can be implemented with dramatical drawbacks for the speed only.
The first 10 bits of a value can be access with BITSHIFT and/or BITAND.

Good luck, Jan
From: Eshbonzie on

>
> Your demands are not getting clear to me.
> You need 20 bits for the x and y values of each pixel. Does this mean, that your picture has 2^20 pixels? Why does the counter need 18bits, if you can get 2^26 different signatures?
> You do not have to store 2^26 *addresses* with 8 byte elements when you allocate an array. Storing the first address is enough and you can access all elements with 32bit addressing.
> 5 Byte addressing can be implemented with dramatical drawbacks for the speed only.
> The first 10 bits of a value can be access with BITSHIFT and/or BITAND.
>
> Good luck, Jan

The dimension of the picture is
x = 260 pixels (need 2^9 bits actually!)
y = 640 pixels (2^10)

the counter is for how many pixels appeared for each signature(after running the algorithm for each pixel). A min = 0 and max = 260x640 pixel = 166400 pixels = 2^18 would be the boundaries of this counter.

I dont want to store the addresses, I will use the sigantures as addresses to access the array and for each location(corresponding to the signature value) inside the array I want to store the x, y and counter value for that signature(thats where I need almost 5 bytes instead of the default 8 bytes).

defining a new array with the size of 2^26 memory locations will by default allocate 8 bytes for each address. is it possible somehow to reduce this 8 bytes memory allocation for each address to be only 5?

one more question, for example if I have the value of x = 15 = 1111(bin). Is it possible to store it as 000001111(with zeros on the left) if I will use 9 bits to represent the x. because whenever I store any binary number with zeros on the left, it is removed by matlab. It makes sense of course but in my case I believe I always need a 9 bits precision to be able to identefy the x and 10 bits percision to identify the y and 18 bits precision to be able to identify the counter.

quick example:

x = 63 = 000111111(bin using 9 bits)
y = 511 = 0111111111(bin using 10 bits)

if I store it in the array(value of x first then value of y) it will be just a sequence of 15 ones (111111111111111). If it is not always stored with the precision I define(9 bits for x and 10 for y adding zeros on the left if necesary) then I wont be able to define when the x, y or the counter value starts.

Hope I made it little bit clear :)

Thanks for your time
From: Jan Simon on
Dear Eshbonzie,

> defining a new array with the size of 2^26 memory locations will by default allocate 8 bytes for each address. is it possible somehow to reduce this 8 bytes memory allocation for each address to be only 5?

An array of type UINT64 or DOUBLE uses 8 bytes per element.
You can create a UINT32 and a UINT8 array an access your elements like:
Element = double(Uint32Array(x, y)) * 2^32 + double(Uint8Array(x, y));
Did you thought of using a sparse DOUBLE array? Most your 2^26 elements are not used for pictures of size 640*260.

I have the strong impression, that there must be a much simpler method then bit-hustling.
Jan
From: Jan Simon on
Dear Eshbonzie,

> one more question, for example if I have the value of x = 15 = 1111(bin). Is it possible to store it as 000001111(with zeros on the left) if I will use 9 bits to represent the x. because whenever I store any binary number with zeros on the left, it is removed by matlab.

Nope. Matlab stores numbers as DOUBLEs, if nothing else is specified. Just if displayed to screen the leading zeros are not shown.
I'd suggest using a linear index for the pixels with a simple UINT32 array and store the signatures either in a sorted list or a sparse array.

Jan