Difference between revisions of "Working with raw image data"
From ElphelWiki
(→Capturing and downloading) |
|||
(11 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | ==<font color='darkblue'> | + | ==<font color='darkblue'>Capturing and downloading</font>== |
+ | ===raw.php (demo)=== | ||
+ | * capture (for ports 0 and 1): | ||
+ | <font size='2em'>http://192.168.0.9/raw.php?cmd=run&ports=0x3</font> | ||
+ | * download | ||
+ | <font size='2em'>http://192.168.0.9/raw.php?cmd=run&ports=0x1</font> | ||
+ | <font size='2em'>http://192.168.0.9/raw.php?cmd=run&ports=0x2</font> | ||
+ | * description: | ||
+ | <font size='2em'>'''<font color='darkblue'>help:</font>''' | ||
+ | 1. without parameters will print help | ||
+ | '''<font color='darkblue'>capture request:</font>''' | ||
+ | 2. decodes requested ports | ||
+ | 3. reads current frame_number | ||
+ | 4. sets buffers sizes | ||
+ | 5. triggers copying pixel data from video memory to system memory for the frame_number+1 (waiting is implemented in the videomem driver). | ||
+ | Image numbers might not match - this depends on fps. | ||
+ | 6. prints debug info and links to download raw images | ||
+ | '''<font color='darkblue'>download request:</font>''' | ||
+ | 7. decodes raw info from sysfs and calculates the number of bytes needed to be read | ||
+ | There is '''fullwidth''','''width''' and '''height''' - the raw image size is '''fullwidth x height x bytes_per_pixel/8''', | ||
+ | '''fullwidth''' is the '''width''' upped to the whole number of 128-bit bursts. | ||
+ | And so the '''width''' is the number of valid pixels. | ||
+ | 8. sets http response headers | ||
+ | 9. outputs pixel data</font> | ||
+ | |||
+ | ===raw.py (demo)=== | ||
+ | * run: | ||
+ | <font size='2em'>'''root@elphel393:~# raw.py'''</font> | ||
+ | * description: | ||
+ | <font size='2em'>1. scans all available ports, determines the trigger master | ||
+ | 2. reads current frame_number to be used later | ||
+ | 3. formats system memory buffers and mmaps to user memory (all available ports) | ||
+ | 4. selects position in video memory (0 or 1) | ||
+ | 5. triggers copying pixel data from video memory to system memory for the frame_number+1 (waiting is implemented in the videomem driver). | ||
+ | Image numbers might not match - this depends on fps. | ||
+ | 6. prints the first 16 bytes of the image | ||
+ | 7. prints raw image info for each port</font> | ||
+ | |||
+ | ===Command line=== | ||
* Available options (channels can be 0..3): | * Available options (channels can be 0..3): | ||
<font size='2em'># set receiving buffer size in 4kB pages (thus 4096 equals to 16MB) | <font size='2em'># set receiving buffer size in 4kB pages (thus 4096 equals to 16MB) | ||
Line 19: | Line 57: | ||
'''echo 0 > /sys/devices/soc0/elphel393-videomem\@0/membridge_start2''' | '''echo 0 > /sys/devices/soc0/elphel393-videomem\@0/membridge_start2''' | ||
'''cat /dev/image_raw2 > /tmp/test.raw'''</font> | '''cat /dev/image_raw2 > /tmp/test.raw'''</font> | ||
− | |||
− | |||
==<font color='darkblue'>Displaying</font>== | ==<font color='darkblue'>Displaying</font>== | ||
===ImageMagick=== | ===ImageMagick=== | ||
− | * Camera settings: 2592x1936 JPEG, actual pixels | + | * Camera settings: 2592x1936 JPEG, actual valid pixels - 2596x1940, pixels read - 2608x1940: |
<font size='2em'>convert -size 2608x1940 -depth 8 -endian MSB -normalize gray:test.raw -compress lzw result.tiff</font> | <font size='2em'>convert -size 2608x1940 -depth 8 -endian MSB -normalize gray:test.raw -compress lzw result.tiff</font> | ||
* Camera settings: 2592x1936 JP4, actual pixels available: 2592x1936 | * Camera settings: 2592x1936 JP4, actual pixels available: 2592x1936 | ||
Line 33: | Line 69: | ||
===bayer2rgb program=== | ===bayer2rgb program=== | ||
* Available [https://github.com/jdthomas/bayer2rgb here]. | * Available [https://github.com/jdthomas/bayer2rgb here]. | ||
− | * Camera settings: 2592x1936 JPEG | + | * Camera settings: 2592x1936 JPEG: |
<font size='2em'>bayer2rgb -w 2608 -v 1940 -b 8 -f GRBG -m AHD -t -i test.raw -o test.tiff</font> | <font size='2em'>bayer2rgb -w 2608 -v 1940 -b 8 -f GRBG -m AHD -t -i test.raw -o test.tiff</font> | ||
The result is a colored tiff image. Pixel values are linear. | The result is a colored tiff image. Pixel values are linear. | ||
+ | ===Python=== | ||
+ | * Camera settings: 2592x1936 JPEG: | ||
+ | ** a) | ||
+ | <font size='2em'>#!/usr/bin/env python | ||
+ | import cv2 | ||
+ | import numpy as np | ||
+ | |||
+ | width = 2608 | ||
+ | height = 1940 | ||
+ | |||
+ | with open("test.raw", "rb") as rawimg: | ||
+ | img = np.fromfile(rawimg, np.dtype('u1'), width * height).reshape(height, width) | ||
+ | img.tofile("test2.raw") | ||
+ | colimg = cv2.cvtColor(img, cv2.COLOR_BAYER_GB2BGR) | ||
+ | cv2.imwrite("test.jpeg", colimg) | ||
+ | #cv2.imshow("color", colimg) | ||
+ | #cv2.waitKey(0)</font> | ||
− | + | ** b) for PC: | |
− | |||
− | |||
− | * | ||
<font size='2em'>''#!/usr/bin/python3'' | <font size='2em'>''#!/usr/bin/python3'' | ||
from PIL import Image | from PIL import Image | ||
Line 48: | Line 98: | ||
img = Image.frombytes('L', imgSize, rawData) | img = Image.frombytes('L', imgSize, rawData) | ||
img.save("result.jpeg")# can give any format you like .png</font> | img.save("result.jpeg")# can give any format you like .png</font> | ||
+ | |||
+ | The result will be a grayscale image. | ||
+ | |||
+ | ==<font color='darkblue'>Processing</font>== | ||
+ | Open the file and process as pixel array RGGB, GRBG, GBRG or BGGR - 8 or 16 bits | ||
+ | |||
+ | [[Category:393]] | ||
+ | [[Category:raw image data]] | ||
+ | [[Category:bayer pixel array]] |
Latest revision as of 17:27, 18 January 2018
Contents
Capturing and downloading
raw.php (demo)
- capture (for ports 0 and 1):
http://192.168.0.9/raw.php?cmd=run&ports=0x3
- download
http://192.168.0.9/raw.php?cmd=run&ports=0x1 http://192.168.0.9/raw.php?cmd=run&ports=0x2
- description:
help: 1. without parameters will print help capture request: 2. decodes requested ports 3. reads current frame_number 4. sets buffers sizes 5. triggers copying pixel data from video memory to system memory for the frame_number+1 (waiting is implemented in the videomem driver). Image numbers might not match - this depends on fps. 6. prints debug info and links to download raw images download request: 7. decodes raw info from sysfs and calculates the number of bytes needed to be read There is fullwidth,width and height - the raw image size is fullwidth x height x bytes_per_pixel/8, fullwidth is the width upped to the whole number of 128-bit bursts. And so the width is the number of valid pixels. 8. sets http response headers 9. outputs pixel data
raw.py (demo)
- run:
root@elphel393:~# raw.py
- description:
1. scans all available ports, determines the trigger master 2. reads current frame_number to be used later 3. formats system memory buffers and mmaps to user memory (all available ports) 4. selects position in video memory (0 or 1) 5. triggers copying pixel data from video memory to system memory for the frame_number+1 (waiting is implemented in the videomem driver). Image numbers might not match - this depends on fps. 6. prints the first 16 bytes of the image 7. prints raw image info for each port
Command line
- Available options (channels can be 0..3):
# set receiving buffer size in 4kB pages (thus 4096 equals to 16MB) echo {size} > /sys/devices/soc0/elphel393-mem\@0/buffer_pages_raw_chn2 # start from the N-th frame position in buffer. Currently, 0 or 1 echo 1 > /sys/devices/soc0/elphel393-videomem\@0/video_frame_number # initiate transfer, wait for X-th frame (X - absolute frame number), 0 = no waiting echo X > /sys/devices/soc0/elphel393-videomem\@0/membridge_start2 # copy to file cat /dev/image_raw2 > /tmp/test.raw # see in hex hexdump /tmp/test.raw # copy to PC scp /tmp/test.raw user@address:/path/
- Minimal:
echo 4096 > /sys/devices/soc0/elphel393-mem\@0/buffer_pages_raw_chn2 echo 0 > /sys/devices/soc0/elphel393-videomem\@0/membridge_start2 cat /dev/image_raw2 > /tmp/test.raw
Displaying
ImageMagick
- Camera settings: 2592x1936 JPEG, actual valid pixels - 2596x1940, pixels read - 2608x1940:
convert -size 2608x1940 -depth 8 -endian MSB -normalize gray:test.raw -compress lzw result.tiff
- Camera settings: 2592x1936 JP4, actual pixels available: 2592x1936
convert -size 2592x1936 -depth 8 -endian MSB -normalize gray:test.raw -compress lzw result.tiff
The result is a grayscale tiff
bayer2rgb program
- Available here.
- Camera settings: 2592x1936 JPEG:
bayer2rgb -w 2608 -v 1940 -b 8 -f GRBG -m AHD -t -i test.raw -o test.tiff
The result is a colored tiff image. Pixel values are linear.
Python
- Camera settings: 2592x1936 JPEG:
- a)
#!/usr/bin/env python import cv2 import numpy as np width = 2608 height = 1940 with open("test.raw", "rb") as rawimg: img = np.fromfile(rawimg, np.dtype('u1'), width * height).reshape(height, width) img.tofile("test2.raw") colimg = cv2.cvtColor(img, cv2.COLOR_BAYER_GB2BGR) cv2.imwrite("test.jpeg", colimg) #cv2.imshow("color", colimg) #cv2.waitKey(0)
- b) for PC:
#!/usr/bin/python3 from PIL import Image rawData = open("test.raw", 'rb').read() imgSize = (2608,1940)# the image size img = Image.frombytes('L', imgSize, rawData) img.save("result.jpeg")# can give any format you like .png
The result will be a grayscale image.
Processing
Open the file and process as pixel array RGGB, GRBG, GBRG or BGGR - 8 or 16 bits