I was wondering about constructing an IndexColourModel. I don't understand the 'bits' parameter argument. Is this what is used to index into a colour map, i.e. the number of least-significant-bits to use from the pixel to index into the map? The docs simply state
bits - the number of bits each pixel occupies
I'm not satisfied with this and was wondering if someone could elucidate what exactly this parameter is and how it is used. Must this be correlated with the other 'size' parameter?
The bits parameter is the color depth.
From the IndexColourModel javadoc at the top of the class:
The values used to index into the colormap are taken from the least
significant n bits of pixel representations where n is based on the
pixel size specified in the constructor. For pixel sizes smaller than
8 bits, n is rounded up to a power of two (3 becomes 4 and 5,6,7
become 8). For pixel sizes between 8 and 16 bits, n is equal to the
pixel size. Pixel sizes larger than 16 bits are not supported by this
class. Higher order bits beyond n are ignored in pixel
representations. Index values greater than or equal to the map size,
but less than 2n, are undefined and return 0 for all color and alpha
components.
Related
My use case is this,
I wish to reduce an extremely long number like 97173329791011L to a smaller integer by shifting down and be able to get back the long number 97173329791011L from the smaller integer by shifting up .I have implemented a function called reduceLong to implement this as shown below
private int reduceLong(long reduceable) {
return (int) (reduceable >> 32);
}
However, I feel the function I have is in a way wrong as the result produced is incorrect. Here is the result from my console output when trying to reduce 97173329791011L to a smaller integer
Trying to reduce 97173329791011L
Result= 0
Your help would be greatly appreciated. Thanks alot.
The int datatype can hold all integral values in the range [-2^31, +2^31-1], inclusive. That's, in decimal, [-2147483648, 2147483647]. The total range covers 2^32 different numbers, and that makes sense because ints are 32 bits in memory. Just like you can't store an elephant in a matchbox, you can't store an infinite amount of data in 32 bits worth of data. You can store at most... 32 bits worth of data.
3706111600L is a long; it is (slightly) outside of the range of the int. In binary, it is:
11011100111001101100011001110000
How do you propose to store these 64 bits into a mere 32 bits? There is no general strategy here, and that is mathematically impossible to have: You can store exactly 2^64 different numbers in a long, and that's more unique values than 2^32, so whatever 'compression' algorithm you suggest, it cannot work except for at most 2^32 unique long values, which is only a very small number of them.
Separate from that, running your snippet: first, you do 11011100111001101100011001110000 >> 32, which gets rid of all of the bits. (there are exactly 32 bits there), hence why you get 0.
Perhaps you want this 'compression' algorithm: The 2^32 longs we decree as representable in this scheme are:
all the longs from 0 to 2^31-1, by mapping them to the same integer value, and then also another batch of 2^31 longs that immediately follow that, by mapping them bitwise, although, given that in java all numbers are signed, these then map to negative ints. All other long values (so all values above 2^32-1 and all negative longs) cannot be mapped (or if you try, they'd unmap to the wrong value).
If you want that, all you need to do:
int longToInt = (int) theLong;
long backToLong = 0xFFFFFFFFL & theLong;
Normally if you cast an int to a long it 'sign extends', filling the top 32 bits with 1s to represent the fact that your int is negative. The bitwise & operation clears the top 32 bits all back down to 0 and you're back to your original... IF the original long had 32 zero-bits at the top (which 3706111600L does).
Your test number is too small. Converted into Hexadecimal, 3706111600L is 0x00000000DCE6C670.
If you shift this number 32 bits to the right, you will lose the last 8 nibbles; your resulting number is 0x00000000L. Casted to int this value is still 0.
I have read the but I still did not understand this paragraph:
All points used in defining a path are stored in eight bytes as a pair
of 32-bit components, vertical component first. The two components are
signed, fixed point numbers with 8 bits before the binary point and 24
bits after the binary point. Three guard bits are reserved in the
points to eliminate most concerns over arithmetic overflow. Hence, the
range for each component is 0xF0000000 to 0x0FFFFFFF representing a
range of -16 to 16. The lower bound is included, but not the upper
bound. This limited range is used because the points are expressed
relative to the image size. The vertical component is given with
respect to the image height, and the horizontal component is given
with respect to the image width. [ 0,0 ] represents the top-left
corner of the image; [ 1,1 ] ([ 0x01000000,0x01000000 ]) represents
the bottom-right. In Windows, the byte order of the path point
components are reversed; you should swap the bytes when accessing each
32-bit value.
I have done a test of that: link
and get the point of that:
x1:7e0e42 y1:0
x2:7e0e42 y2:0
x3:7e0e42 y3:0
x1:1000000 y1:0
x2:1000000 y2:0
x3:1000000 y3:0
the fisrt is at the top left of red rect;
the second is at the top
right of red rect;
the canvas width is 790px
the top left is at 389px
How can I get the number of 389 from 7e0e42?
I just can not understand the meaning of that paragraph.
Thanks a lot
A little late, but:
Your first x value is 0x007e0e42 in the fixed point representation mentioned in the text. That means 0 + 0x7e0e42 / 0xffffff, or 0.49240505695343 (approximately) in floating point.
Remember, the coordinates are given "relative to the image size". If you multiply this with the the image width of 790, you get 388.999994993209839, which should round nicely to 389, which is what you expected.
Mystery solved. :-)
I am reading the implementation details of Java 8 HashMap, can anyone let me know why Java HashMap initial array size is 16 specifically? What is so special about 16? And why is it the power of two always? Thanks
The reason why powers of 2 appear everywhere is because when expressing numbers in binary (as they are in circuits), certain math operations on powers of 2 are simpler and faster to perform (just think about how easy math with powers of 10 are with the decimal system we use). For example, multication is not a very efficient process in computers - circuits use a method similar to the one you use when multiplying two numbers each with multiple digits. Multiplying or dividing by a power of 2 requires the computer to just move bits to the left for multiplying or the right for dividing.
And as for why 16 for HashMap? 10 is a commonly used default for dynamically growing structures (arbitrarily chosen), and 16 is not far off - but is a power of 2.
You can do modulus very efficiently for a power of 2. n % d = n & (d-1) when d is a power of 2, and modulus is used to determine which index an item maps to in the internal array - which means it occurs very often in a Java HashMap. Modulus requires division, which is also much less efficient than using the bitwise and operator. You can convince yourself of this by reading a book on Digital Logic.
The reason why bitwise and works this way for powers of two is because every power of 2 is expressed as a single bit set to 1. Let's say that bit is t. When you subtract 1 from a power of 2, you set every bit below t to 1, and every bit above t (as well as t) to 0. Bitwise and therefore saves the values of all bits below position t from the number n (as expressed above), and sets the rest to 0.
But how does that help us? Remember that when dividing by a power of 10, you can count the number of zeroes following the 1, and take that number of digits starting from the least significant of the dividend in order to find the remainder. Example: 637989 % 1000 = 989. A similar property applies to binary numbers with only one bit set to 1, and the rest set to 0. Example: 100101 % 001000 = 000101
There's one more thing about choosing the hash & (n - 1) versus modulo and that is negative hashes. hashcode is of type int, which of course can be negative. modulo on a negative number (in Java) is negative also, while & is not.
Another reason is that you want all of the slots in the array to be equally likely to be used. Since hash() is evenly distributed over 32 bits, if the array size didn't divide into the hash space, then there would be a remainder causing lower indexes to have a slightly higher chance of being used. Ideally, not just the hash, but (hash() % array_size) is random and evenly distributed.
But this only really matters for data with a small hash range (like a byte or character).
Okay so I have implemented a stereo correspondence algorithm which takes a stereo image pair, matches a point on the left image with a point on the right image, and finds the disparity between the points. I need to write this to a disparity map.
The disparity maps I have found are grayscale images, with lighter grays meaning less depth and darker grays meaning more depth. How do I translate my set of disparities into a grayscale image like this? My disparities are very small, ie only a distance of two between pixels, how does this translate into a grayscale pixel value?
There must be a standard way of compiling disparity maps but all my searching has yielded nothing thus far.
A simple solution when creating a disparity map the largest distance becomes black ie rgb(0,0,0) and the smallest distance - which is 0 - becomes white ie rgb(255,255,255). If you divide 255 by the largest distance then you find the increment value. Finally just go through all the disparities and set each rgb value to 255 minus the disparity times the increment value. Viola, you have your disparity map.
So in your example it sounds like your largest distance is only 2 pixals (which unfortunately means your map isn't going to have a lot of detail). Anyways 255 / 2 = 127.5. This means that 127.5 is the increment value. So everywhere that the disparity is 0, the rgb value is 255 - (0 * 127.5) or rgb(255,255,255), anywhere the disparity is 1 the rgb value is 255 - (1 * 127.5), we'll round to 128 so rgb(128,128,128) and anywhere the disparity is 2 the rgb value is 255 - (2 * 127.5) or rgb(0,0,0).
Here are some more resources:
How MathWorks does it
Jay Rambhia has a good blog explaining how to program one
Hope that helps!
I've heard that the data in gray-scale images with 8-bits color depth is stored in the first 7 bits of a byte of each pixel and the last bit keep intact! So we can store some information using the last bit of all pixels, is it true?
If so, how the data could be interpreted in individual pixels? I mean there is no Red, Blue and Green! so what do those bits mean?
And How can I calculate the average value of all pixels of an image?
I prefer to use pure java classes not JAI or other third parties.
Update 1
BufferedImage image = ...; // loading image
image.getRGB(i, j);
getRGB method always return an int which is bigger than one byte!!!
What should I do?
My understanding is that 8-bits colour depth means there is 8-bits per pixel (i.e. one byte) and that Red, Gren and Blue are all this value. e.g. greyscale=192 means Red=192, Green=192, Blue=192. There is no 7 bits plus another 1 bit.
AFAIK, you can just use a normal average. However I would use long for the sum and make sure each byte is unsigned i.e. `b & 0xff
EDIT: If the grey scale is say 128 (or 0x80), I would expect the RGB to be 128,128,128 or 0x808080.