compress ==> OSError: Out of memory !

Hello,

I try to compress image continuously (every 10s) and i have some problem with the level of compression (between 0 and 100)
Here is a test code :

import sensor, image, pyb

red_led=pyb.LED(1)
red_led.off()

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.VGA)
sensor.skip_frames(time=500)

quality = 95

while(True):
   red_led.toggle()
   img=sensor.snapshot().compress(quality)

When i run, there is OSError: Out of memory !

Do you know what happens ?
How i can test it before running compress ?
How can i avoid it (OMV_RAW_BUF_SIZE, JPEG_QUALITY_THRESH, JPEG_QUALTIY_LOW, JPEG_QUALITY_HIGH) ?

Thanks,

Hi, this happens because the in place compress uses the frame buffer stack which is smaller than the image size at VGA resolution. So, sometimes you get a huge JPG which doesn’t fit in the frame buffer stack. On the H7 this won’t be a problem but it is on the M7. Um, the fixes are to either lower the quality or surround the compress method with python’s try: expect: logic. This will allow you to ignore failures when the jpg image comes out too big.

Thanks for your reply.
I tested your solution below :

import sensor, image, pyb

red_led=pyb.LED(1)
blue_led=pyb.LED(3)
red_led.off()
blue_led.off()

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.VGA)
sensor.skip_frames(time=500)

quality = 94

while(True):
   img=sensor.snapshot()
   try:
      img.compress(quality)
      blue_led.off()
      red_led.toggle()
   except:
      red_led.off()
      blue_led.toggle()

At start the compression works on static subject (ceiling): the red led is flashing.
If i put my hand in front of the camera, the compression dont works : the blue led is flashing.
But if i take off my hand, the compression still doesnt work…

Do i have to reinit something before re-use the compression ?

I tried to use

import gc
print('Used: ' + str(gc.mem_alloc()) + ' Free: ' + str(gc.mem_free()))

without having an out of memory ?


Thanks,

Okay, there’s definitely some type of memory corruption going on here. It’s kinda hard to track given the way things are written. However, I’m guessing the jpeg buffer is overflowing and corrupting the frame buffer stack pointers causing the frame buffer fast ram stack to break.

Um, please create a bug about this on the OpenMV GitHub. The fix is most likely just to make jpeg.c stop writing out JPEG data earlier than at the last bytes of the data buffer.

Done !

Hello,

I tested the last git version (3.3.0 displayed on openmv ide) with :

import sensor, image, pyb, time, gc

red_led=pyb.LED(1)
blue_led=pyb.LED(3)
red_led.off()
blue_led.off()

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.VGA)
sensor.skip_frames(time=500)

quality = 93
trialnb=0

while(True):
   print("---------START----------")
   img=sensor.snapshot()
   try:
      img.compress(quality)
      print(" OK %s " % trialnb)
      blue_led.off()
      red_led.toggle()
      trialnb=trialnb+1
   except:
      red_led.off()
      blue_led.toggle()
      print('Used: ' + str(gc.mem_alloc()) + ' Free: ' + str(gc.mem_free()) + ' Alloc: ' + str(gc.mem_alloc()) )

There are two modes :

  • the compression does not works ==> except :
    quality = 95
    terminal works
    image is displayed
    deconnexion is possible
  • the compression works :
    quality = 92
    terminal works
    image is not displayed
    deconnexion is not possible anymore

The change between two modes seems to work with led color test but not with image and connexion.

I hope it helps !

Hi, yes the FB stops working when the VGA image is compressed at high quality (when there’s no exception), I think this normal because the memory is full and the compression for the IDE preview fails, but the camera doesn’t disconnect. That’s what I saw in my testing. Is there any other problem ? Also note all the dev firmware version is 3.3.0 so you could still be on an old firmware, you have to make sure to upload the firmware you just compiled (openmv/firmware/OPENMV3/firmware.bin)

If you are always compressing the image at high quality and it can’t fit in our JPEG frame buffer to be sent to the PC then it will never be sent. This is normal behavior. The H7 has a lot more RAM making this not a problem but we’re pretty tight on the M7.

You are right the connexion is not lost but it is not possible to disconnect without unplugging the usb cable.
It is like the camera is too busy to answer.

Limited the quality at 90 maximum will solve the problem…

It’s probably the try/except catches the IDE interrupt. Try this:

try:
    ....
except MemoryError:
    ....
except:
    raise

Hello,

Sorry for late answer, i was lost in stm32F7 low power mode.
I downloaded the last 2.1.0 openmv ide and the camera version is 3.3.0.

Here is the code where i included your solution/question :

import sensor, image, pyb, time, gc

red_led=pyb.LED(1)
green_led=pyb.LED(2)
blue_led=pyb.LED(3)

sensor.reset()
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.VGA)
sensor.skip_frames(time=500)

quality = 94
trialnb=0

while(True):
   img=sensor.snapshot()
   try:
      img.compress(quality)
      green_led.off()
      blue_led.off()
      red_led.toggle()
   except MemoryError:      
      red_led.off()
      blue_led.off()      
      green_led.toggle()
   except:
      green_led.off()   
      red_led.off()
      blue_led.toggle()
      raise

I never go in MemoryError, is it what your expected ?
Thanks,