Help with generating image from captured data

Hi,
I have a data generated from a camera feed and I would like to generate an image out of it. I'm wondering if anyone here could help me in this regard. Kindly find the file attached containing the data. The glitch is - we will have to ignore the second nibble from the 8 bit. The image format is ycbcr. So by ignoring the second nibble it will give us a grey scale image.
For instance, if the data is like this - F1 40 F1 88 F1 88 F1 88 D1 88 92 88 51 90 52 88 F1 90 after processing it should be like this - F1 F1 F1 F1 D1 92 51 52 F1
This processed data will then give a greyscale image.
I tried a lot to remove the second nibble and feed this modified data to generate an image but I couldn't succeed.
Any help in this regard will be greatly appreciated.

Capture.txt (73 KB)
Thanks.

how does the data arrive in to node-red? As a buffer?

I suspect you mean drop even bytes (a nibble is 4 bits)


Assuming it is a buffer, then you could use a function node to loop though the src buffer and write even bytes to a new buffer ...

var src = msg.payload;
var dst = Buffer.alloc(src.length/2); //as we are removing even bytes, only need half the size
for (let i = 0; i < src.length; i++) {
  dst[i] = src[i*2]; //copy even no bytes to dst buffer
}
msg.payload = dst;
return msg;

Hi Steve,

Sorry for replying late.

We have a team at some other place which is working on a camera module interface - ov7670. The capture.txt sent to me is from this team. So the data doesn't arrive in node-red. I have to feed it manually as of now.

Exactly. For instance, if F1 40 is an 8 bit YcbCr image data consisting 4 bits nibbles each then yes, drop the 4 bit even nibble (i.e., 40 in this case) and F1 gives us only the Y component of the image which is luminous component. 40 is CbCr which needs to be dropped. This applies to each and every 8 bit image data from the entire capture.txt

I'm not sure if the contents of the capture.txt file which is feeded to the inject node could be treated as buffer. If you had a look at the attached file you may understand what I mean to say. And I also tried your loop with the captured data but it gives error if I try to pass it as a string to the inject node and doesn't give the desired result if i try to pass it as a buffer.

YcbCr

F140 is a 16 bit value (2 bytes / 4 nibbles)

40 is decimal 64 (1 byte / 8 bits / 2 nibbles).

a 4 bit nibble holds 4 bits and has a max value of 15.

So the file has spaces (and also ends on a single number 6 so is incomplete) however, to convert that to a buffer, you need to remove the spaces & use Buffer.from(filedata,"hex") e.g...

var data = msg.payload.replace(/\s/g, ''); //remove all spaces
var src = Buffer.from(data, "hex"); //convert string to buffer

now you have 2 more problems...

  1. You probably need to convert the YCbCr to RBG.

    This is not too difficult given the real format of the 16 bit data however you have another issue...

  2. Your data has no dimensions

    An image has a header that specifies the various things like the data format and the image size - even a plain BITMAP has a multi byte header.


Recommendations...

  • Ask the developer to transmit an ACTUAL image.
  • If not possible due to language or processing constraints, ask for meta data to also be transmitted (e.g. pixel format, image size etc - everything you would need to construct an image)

The developer told me that the "F1" (Y component of the image is 4 bit) and "40" (CbCr component - another 4 bit) resulting a 8 bit image data. When we get rid of CbCr component, that is "40" - a 4 bit image data, all we are left with is only Y component i.e., F1 - 4 bit only.

I will ask the developer to ponder over your recommendations.

Hi Steve,

The developer says that the data arrived here is the pixel data (raw) from the camera module. So all the meta data needed for image generation is not available. But the image size is 174 X 144 as indicated by the developer.

I agree with you on the above.

As you have only pixel data you will have to draw each pixel to an image.

Your problem is quite similar to this Unable to display image from base64 - #18 by Steve-Mcl you can use the flow in there as a basis for a solution.

Thanks for the reply.

Although I'm not sure how am I going to do this but I will definitely give it a try to your solution.

As I said previously, if you have your devs send an actual image (instead of pixel data) this would be a non issue.

@blob, I will give it a go but I must have more information.

If you dont provide an answer for EVERY question, I cannot reconstitute an image (all questions must be answered)...

  1. Provide a FULL pixel data capture file (the one you posted before incorrectly ends like this)...
    image
    and only contained 24918 bytes and since you said the image is 174x144 there should be at least 25056 bytes

  2. Given F1 40 what BITS of those 2 bytes makes the Y component?

  3. Given F1 40 what BITS of those 2 bytes makes the Cb component?

  4. Given F1 40 what BITS of those 2 bytes makes the Cr component?

  5. You said "image size is 174 X 144" but which is width, which is height?

Bonus Question...

  1. Can your developer provide a fomula for converting F1 40 value to an RBG(a) value (this would save a lot of trouble)

I have forwarded your concern to the developer.

Will get back to you as I hear from him.