Saving the BAYER raw for sensor calibration

I want to save the Bayer unmodified image
Ideally i would like to save as a PGM file in which each pixel is each of the RGGB

import sensor, image, pyb

RED_LED_PIN = 1
BLUE_LED_PIN = 3

sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.BAYER) # or sensor.Bayer
sensor.set_framesize(sensor.VGA) # or sensor.QQVGA (or others)
sensor.skip_frames(time = 2000) # Let new settings take affect.

pyb.LED(RED_LED_PIN).on()
sensor.skip_frames(time = 2000) # Give the user time to get ready.

pyb.LED(RED_LED_PIN).off()
pyb.LED(BLUE_LED_PIN).on()

sensor.snapshot().save("bayer.pgm") # or "example.bmp" (or others)

pyb.LED(BLUE_LED_PIN).off()

but when I do try to run the program I get this: OSError: Image is not PGM!

if I edit the modify the sensor.BAYER to sensor.GRAYSCALE I am able to save as pgm, but it is not the BAYER information as it has been filtered to grayscale.

Thanks before hand

Hi, we don’t support saving bayer formats using the file system methods. Instead you have to write it out as a RAW binary file:

with open("file.bin", "wb") as f:
    f.write(img)
    f.close()

All images are treated as byte streams when passed to other micropython methods. So, the file object will just pull the image data as RAW bytes and save to the SD card.

Dear Kwagyeman

Thanks a lot for the tip it worked, and now I am able to capture the images and do post processing for the calibration of the sensor that I need.

Kind regards

Actually we do now, you can save as “.raw” or leave the extension and the code will figure it out.

Hi thanks,

I tried the raw option, but seem it didn’t work. But I can work with the Raw

Anyway I am trying to adjust the exposure time and the gain. Which are the ranges of both parameters in the camera?
Also when I am setting the Exposure value to 3000000 microseconds I watch the camera LED blue light and is turn on less than 3 seconds, I have been playing a bit with the value but seems to be is like half of the microseconds. Is there a way i can print/save the exposure time of the camera?

And also regarding the next code, is there any other auto setting that I should put to false, or 0?

import pyb, machine, sensor, image, pyb, os, time
RED_LED_PIN = 1
BLUE_LED_PIN = 3

Exp=int('3000000')
estr=str(Exp)
gain=0.1
gstr=str(gain)

sensor.set_auto_gain(False, gain_db = 1.0)
sensor.set_auto_whitebal(False)

sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.BAYER) # or sensor.Bayer
sensor.set_framesize(sensor.VGA) # or sensor.VGA (or others)
sensor.skip_frames(time = 1000) # Let new settings take affect.
sensor.set_gainceiling(2)
sensor.set_contrast(0)
sensor.set_brightness(0)
sensor.set_saturation(0)
sensor.set_auto_exposure(False, exposure_us = Exp)

sensor.skip_frames(time = 1000) # Give the user time to get ready.


newName='OpenMV_r254g000b000_fullsize_gain'+gstr+'msec'+estr# Image file name based on RTC

def get_filename_datetime():
    # Use current date to get a text file name.
    return newName + ".bin"

# Get full path for writing.
name = get_filename_datetime()

path =  name

with open(path, "wb") as f:
    pyb.LED(BLUE_LED_PIN).on()

    img = sensor.snapshot()
    f.write(img)
    f.close()

    pyb.LED(BLUE_LED_PIN).off()

Hi, you can get the exposure with the get_exposure() method…

https://github.com/openmv/openmv/blob/master/src/omv/ov7725.c#L443
https://github.com/openmv/openmv/blob/master/src/omv/ov7725.c#L405

Anyway, the exposure is limited by the chip’s internal register scales. Exposure is 16-bits. So, you may be going above the max. That said, you can slow the sensor PLL down to effectively double the time scales:

Do:

reg = sensor.__read_reg(0xD)
sensor.__write_reg(0xD, (reg & 0x3F) | (0 << 6))

To turn the PLL off…

reg = sensor.__read_reg(0xD)
sensor.__write_reg(0xD, (reg & 0x3F) | (1 << 6))

And the above to cut the FPS by a bit and extend the exposure.

My C code queries the PLL registers so it will try to scale the exposure time you pass to actually be correct.

Hi thanks for the reply.

I need to work in the order of milliseconds, i was just testing in seconds with the LED so i could take the time with a chrono watch.

Now I am using the filename for storing the information of the gain and exposure using sensor.get_gain_db(), sensor.get_exposure_us(), while the sensor.get_exposure_us() works when I input 3000 the output is 2990 and when i input 10000 is 9988 (assuming is because 16 bit approx conversion)
example of the file name

OpenMV_r210g000b000_fullsize_gain17.78586msec9988.bin

Does not matter how I change the gain that I always have the same gain = 17.78586, does not matter if I change to 10, or 100 or 0.1. Do you know what could be wrong in my code?

import pyb, machine, sensor, image, pyb, os, time
RED_LED_PIN = 1
BLUE_LED_PIN = 3

Exp=int('10000')
estr=str(Exp)
gain=0.1
gstr=str(gain)

sensor.set_auto_gain(False, gain_db = gain)
sensor.set_auto_whitebal(False)

sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.BAYER) # or sensor.Bayer
sensor.set_framesize(sensor.VGA) # or sensor.VGA (or others)
sensor.skip_frames(time = 1000) # Let new settings take affect.
sensor.set_gainceiling(128)
sensor.set_contrast(0)
sensor.set_brightness(0)
sensor.set_saturation(0)
sensor.set_auto_exposure(False, exposure_us = Exp)
gainr=sensor.get_gain_db()
gainrs=str(gainr)
timexp=sensor.get_exposure_us()
timexp=str(timexp)

sensor.skip_frames(time = 1000) # Give the user time to get ready.


newName='OpenMV_r210g000b000_fullsize_gain'+gainrs+'msec'+timexp # Image file name based on RTC

def get_filename_datetime():
    # Use current date to get a text file name.
    return newName + ".bin"

# Get full path for writing.
name = get_filename_datetime()

path =  name
with open(path, "wb") as f:
    pyb.LED(BLUE_LED_PIN).on()
    img = sensor.snapshot()
    f.write(img)
    f.close()

    pyb.LED(BLUE_LED_PIN).off()

#pyb.LED(BLUE_LED_PIN).off()

But thanks a lot for your help I manage to sorted out, and looking forward to the Open MV H7. I searched in kickstarter but I didn’t find it any link is welcomed.

Seems that was the line order, I put the line regarding the sensor gain later and now seems to work. So now I can control both Exposure and Gain without any problem. I hope all the autos are off with my code.


import pyb, machine, sensor, image, pyb, os, time
RED_LED_PIN = 1
BLUE_LED_PIN = 3

Exp=int('15000')
estr=str(Exp)
gain=10
gstr=str(gain)


sensor.set_auto_whitebal(False)

sensor.reset() # Initialize the camera sensor.
sensor.set_pixformat(sensor.BAYER) # or sensor.Bayer
sensor.set_framesize(sensor.VGA) # or sensor.VGA (or others)
sensor.skip_frames(time = 1000) # Let new settings take affect.
sensor.set_gainceiling(128)
sensor.set_contrast(0)
sensor.set_brightness(0)
sensor.set_saturation(0)
sensor.set_auto_exposure(False, exposure_us = Exp)
sensor.set_auto_gain(False, gain_db = gain)
gainr=sensor.get_gain_db()
gainrs=str(gainr)
timexp=sensor.get_exposure_us()
timexp=str(timexp)

sensor.skip_frames(time = 1000) # Give the user time to get ready.


newName='OpenMV_r210g000b000_fullsize_gain'+gainrs+'msec'+timexp # Image file name based on RTC

def get_filename_datetime():
    # Use current date to get a text file name.
    return newName + ".bin"

# Get full path for writing.
name = get_filename_datetime()

path =  name
with open(path, "wb") as f:
    pyb.LED(BLUE_LED_PIN).on()
    img = sensor.snapshot()
    f.write(img)
    f.close()

    pyb.LED(BLUE_LED_PIN).off()

#pyb.LED(BLUE_LED_PIN).off()

Hi, our Kickstarter website has not launched yet. ETA is next month. I’m working on media assets and the video right now.

Note the issue with saving BAYER using “.raw” or no extension has been fixed, and will be available in the next release.