0
votes

each representing a channel and I want to merge them into a single one, like RGB image. The images are RAW, so no file header. I have managed to mix them with

cat imgPl0.raw imgPl1.raw imgPl2.raw >> img.rgb

but this is mixing the planes one after the other, but is there a way to do an interlaced mix ?


Maybe using imagemagick there is another way ?


Well, what I need at the output is a rgb image (not a png, sadly imagemagick is creating a png as output) containing the data interlaced. To be more explicit, cat-ing the images is going to make a rgb image plane-interlaced (that is rrrrrr...ggggggg...bbbbbbb). What I want is an operation that is creating a rgb image line-interlaced (that is rrr...ggg...bbb...rrr...ggg...bbb...rrr...ggg...bbb...). Sorry for not being explicit from the beginning.

About the data, it seems it is 12 bpp or 14 bpp little endian

2
bash doesn't know anything about image files, nor does cat; you need a program that does. - chepner
Sorry, I thought that there is a way to do it in bash, but it may be also imagemagick. I edited the question - sop
While correcting your question, you should also indicate if the data are 8 or 16 bit per sample. - Mark Setchell

2 Answers

2
votes

ImageMagick offers a few techniques, but you'll need to be responsible for defining all the information missing from the headers. Stuff like image size, quantum depth, and colorspace.

One approach.

 convert -size 70x46 -depth 8 \
         r:imgPl0.raw g:imgPl1.raw b:imgPl2.raw \
         -set colorspace RGB -combine -colorspace sRGB \
         output.rgb

Another option is to create a blank canvas, and copy the data from the raw files over to the correct canvas channels.

convert -size 70x46 xc: -depth 8 \
        r:imgPl0.raw -compose CopyRed -composite \
        g:imgPl1.raw -compose CopyGreen -composite \
        b:imgPl2.raw -compose CopyBlue -composite \
        -colorspace sRGB output.rgb

Other examples can be found here.

Also note: I'm assuming that these .raw data files only contain single channel samples, are unsigned character color sizes, and have a 70x46 image size. YMMV

Update

Well, what I need at the output is a rgb image (not a png, sadly imagemagick is creating a png as output)

Sorry about that. Just switch output.png to output.rgb. ImageMagick will do the rest.

About the data, it seems it is 12 bpp or 14 bpp little endian

Adjust -depth from 8 to 12, or 14 bits-per-part. There's also a -endian LSB option, but I don't think that's needed.

What I want is an operation that is creating a rgb image line-interlaced

Easy. Set the -interlace Line options.


So... My previous answer is still helpful, but just needs some additional options.

 convert -size 70x46 -depth 12 \
         r:imgPl0.raw g:imgPl1.raw b:imgPl2.raw \
         -set colorspace RGB -combine -colorspace sRGB \
         -interlace Line output.rgb

or

convert -size 70x46 xc: -depth 12 \
        r:imgPl0.raw -compose CopyRed -composite \
        g:imgPl1.raw -compose CopyGreen -composite \
        b:imgPl2.raw -compose CopyBlue -composite \
        -colorspace sRGB -interlace Line output.rgb

Hope that get's you close.

0
votes

If your data is 8 bits per sample, you can do it like this which whilst not very efficient, doesn't require any code writing or compiling or anything:

#!/bin/bash

# Bytes per row
bpr=100
row=0


# Loop through all rows of file
while :; do
   # Read a row from each channel and output on stdout redirected to result.rgb
   for ((chan=0;chan<3;chan++)); do
      dd if=imgPl${chan}.raw bs=$bpr count=1 skip=$row > row.tmp 2> /dev/null
      [ ! -s row.tmp ] && exit
      cat row.tmp
   done
   ((row+=1))
done > result.rgb