I'm trying to translate/reuse some processing code which uses shifts. (for translating 2 byte RGB to 1byte grayscale) - I am stuck.
I didn't yet understand the difference between the shift operations.
Maybe someone could enlight me and help with the translation.
Processing code:
//loc is defined and (I think) doesn't matter too much for the translation
int msb = packedbuf[2*loc] & 0xff;
int lsb = packedbuf[2*loc+1] & 0xff;
int r = (lsb >>> 3);
int g = ((lsb & 0x7) << 3);
g |= (msb >>> 5);
int b = (msb & 0x1f);
r = (r << 3)|(r >>> 2);
g = (g << 2)|(g >>> 4);
b = (b << 3)|(b >>> 2);
My arduino code, which is wrong as I just removed everything what didn't seemed to be c++ bit shift related:
//l is defined and is used instead of loc from the processing code, variables are defined earlier in the code
msb = 2*l;
lsb = 2*l+1;
r = (lsb >> 3);
g = (lsb << 3);
g |= (msb >> 5);
b = (msb);
r = (r << 3)|(r >> 2);
g = (g << 2)|(g >> 4);
b = (b << 3)|(b >> 2);
I am going back to wikipedia and google trying to understand the java shift operations ...
Maybe there some explanation on what has to be achived by the code helps:
I have two bytes as RGB value: RRRRRGGG GGGBBBBB. At least that's what I expect to get from the camera. (If I would fully understand what the processing code does, I would be sure )
I want to seperate them into three integers.
int 1= RRRRR
int 2= GGGGG
int 3= BBBBB
I thought it would maybe possible like this:
//buf contains the the byte stream
for (unsigned int l= 0; l < TWI_BUFFER_LENGTH/2; ++l){
r = (buf[l*2] >> 16) & 0xff ; //bitwise shifting
g = (buf[l*2] >> 8) & 0xff ;
b = buf[l*2] & 0xff ;
//here calculate grayscale and write to grayscale img buffer
}
robvoi:
Maybe there some explanation on what has to be achived by the code helps:
I have two bytes as RGB value: RRRRRGGG GGGBBBBB. At least that's what I expect to get from the camera. (If I would fully understand what the processing code does, I would be sure )
I want to seperate them into three integers.
int 1= RRRRR
int 2= GGGGG
int 3= BBBBB
Yes, that is what the Processing code seems to do. The >>> operator is the Java unsigned bit shift operator - when you do an unsigned bit shift, the bits shifted into the most significant position are zero. The code seems to extract three 5-bit values from the 16 bits. The code to extract the g (green) channel is a bit more complicated that the other channels because it has to take three bits from one byte and two bits from the other.
This worked. And thanks a lot for the explanation.
As you now finaly also wrote the convertion function for me I now get a grayscale picture from the cam.
I have to tune it as it is too dark, even with the most correct translation function you provided (have to figure out the bit shift part, but also without the calculaiton for the whole picture only takes 0.2 seconds).
I learned a lot from the information you provided. In retrospect all you explained (beside the bit shifting part) is clear and I should have been able to do it myself. But that how it is when you learn something.
have to tune it as it is too dark, even with the most correct translation function you provided
the reason is that the values of R, G, and B are not 0..255 which is assumed in the gray formulas.
int r = (lsb >> 3) & 0x1F;
int g = ((lsb & 0x07) << 3) | ((msb >> 5) & 0x07) ;
int b = (msb & 0x1f);
r = r << 3; // as r is only 5 bit we must shift it to the left 3 positions
g = g << 2; // g has 6 bits
b = b << 3; // ....
and now gray = (r + g + b )/3; or the more sophisticated formulas.
// and for some fun you could add some noise which will have a smoothing effect.
r = r << 3 + random(8); // fills up the 3 zero bits with some noise
g = g << 2 + random(4);
b = b << 3 + random(8);
if this work is done you should post a link to the HarcoCam group so others may use it to.
the work is only really done if you make a separate command for downloading grayscale pictures that exists besides the rgb pictures.
we now patched the dl command maybe create a dg (download gray) command?
I am already in contact with them. They got the link to the discussions right when I created them. So far there is little response. But their website states that they are on vacation until the 13th.
Updating the library and the Hub sketch was the plan anyway. I will try another thing (see 3) and than start cleaning up the code and do the library/sketch updating. Maybe the hacrocam guys want to kick in once they are back. Otehrwise I'll provide them the updated code. Gettingthe serial transmition times of the cam down will extend the pissiblities for robotics use (where I want to use it for). This together with the low price tag ... I hope more people will buy the cam and a comunity starts to build up.
Once the grayscale bought down the transmition time for the picture to half of the rgb time, I will now try to go to 4 bit grayscale. Should reduce it again by 50%. First step is to dig into the bit shifting and masking thing to combine the two times four bit to one byte.
With the alpha correction code you provided....
r = r << 3; // as r is only 5 bit we must shift it to the left 3 positions
g = g << 2; // g has 6 bits
b = b << 3; // ....
.... I get an image with many black arreas (I think in the most bright areas of the picture). Using the bit shift here and take only green as gray, I get a nearly complete black picture.
Shifting one bit less ...
r = r << 2;
g = g << 1;
b = b << 2;
... gives a brighter image without the black areas.
BTW. I am surprised how well only taking the green chanel works. Almost no visible difference to the calculated values.
here is an overview of the pics, including the one with the theoretically correct bit shift- which gives the black areas..
The 4 bit version is simulated only. It still works with 8 bit which I shifted right and left to reduce color depth.
I will now have to combine the two bytes to one and do the decoding on the other side.
Attached you also find the data sheet for the cam. Got it from a nice guy from hacroca (who is actually on vacation).
It shows that the RRRRRGGG GGGBBBBB coding is correct.
Good point. I'll keep it in mind for new code. For editors we have dev friendly fonts. The browser hasn't. Otherwise using one for the code outline in the forum would have been nice.