Home > Back-end >  How to convert raw YUV image to jpg
How to convert raw YUV image to jpg

Time:02-04

I have a raw image that was taken with v4l2-ctl after the camera had been setup like:

# media-ctl -d /dev/media0 -l "'rzg2l_csi2 10830400.csi2':1 -> 'CRU output':0 [1]"
# media-ctl -d /dev/media0 -V "'rzg2l_csi2 10830400.csi2':1 [fmt:UYVY8_2X8/1280x960 field:none]"
# media-ctl -d /dev/media0 -V "'ov5645 0-003c':0 [fmt:UYVY8_2X8/1280x960 field:none]"

and then the picture got snapped with:

# v4l2-ctl --device /dev/video0 --stream-mmap --stream-to=frame.raw --stream-count=1

now I've tried multiple methods to convert this into a jpeg but nothing seems to yield the expected output

the raw file can be downloaded here: enter image description here


If you wanted to do that with ImageMagick, you could do something like this:

#!/bin/bash

python3 <<EOF
import numpy as np
h, w = 960, 1280

# Load raw file into Numpy array
raw = np.fromfile('frame.raw', np.uint8)
raw[0::2].tofile('Y')     # Starting at the 1st byte, write every 2nd byte to file "Y"
raw[1::4].tofile('U')     # Starting at the 2nd byte, write every 4th byte to file "U"
raw[3::4].tofile('V')     # Starting at the 3rd byte, write every 4th byte to file "V"
EOF

# Load the Y channel, then the U and V channels forcibly resizing them, then combine and go to sRGB
magick -depth 8 -size 1280x960 gray:Y \
  \( -size 640x960 gray:U gray:V -resize 1280x960\! \) \
  -set colorspace YUV -combine -colorspace sRGB result.jpg

If yo don't like/have Python, that part can be replaced with some basic C as follows:

#include <stdint.h>
#include <stdio.h>

// Split YUYV file called "frame.raw" into separate channels with filenames "Y", "U" and "V"
// Compile with: clang -O3 splitter.c -o splitter

int main(){

   FILE    *in, *Y, *U, *V;
   uint8_t buffer[4];
   size_t  bytesRead;

   // Open input file and 1 output file per channel
   in = fopen("frame.raw", "rb");   
   Y  = fopen("Y", "wb");   
   U  = fopen("U", "wb");   
   V  = fopen("V", "wb");   

   // read up to sizeof(buffer) bytes
   while ((bytesRead = fread(buffer, 1, sizeof(buffer), in)) > 0)
   {
      fputc(buffer[0], Y);
      fputc(buffer[1], U);
      fputc(buffer[2], Y);
      fputc(buffer[3], V);
   }
}
  •  Tags:  
  • Related