miky94
Posts: 103
Joined: Sun Jun 03, 2018 9:17 pm

best compromise quality/size for time-lapse camera

Sun Jun 09, 2019 2:56 pm

I'm working on a onboard motorbike time-lapse camera for holidays, I'm using the picamera python module and I did a test looking for the best compromise quality/size.
excluding the unusable image with quality 1, I didn't find significant quality differences (not even by zooming) between quality 10 and quality 100 images, but a size difference of 1/8.
however it seems strange to me and I'm afraid of getting worse results under different conditions.
now I'm using Camera Module v1 (3€) and I'm wondering if is worth to buy the v2 (20€) to get better quality images, since I'll use 1920x1080 resolution for video conversion.
also is there a way to auto-improve the camera settings or is it already done automatically by the module?
quality 1
Image
quality 10
Image
quality 100
Image
Attachments
images.jpg
images.jpg (41.94 KiB) Viewed 1445 times

User avatar
HermannSW
Posts: 1394
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: best compromise quality/size for time-lapse camera

Sun Jun 09, 2019 8:29 pm

If you are only interested in 1920x1080 resolution, then v2 seems not to bring new value over v1 camera. Considering the reduced FoV of v2 over v1 maybe v2 is even worse than v1 (1920x1080 is 2MP, with v1 you get 2MP/5MP=40% of full view, with v2 you get only 25%):
https://picamera.readthedocs.io/en/rele ... 2/fov.html
⇨https://stamm-wilbrandt.de/en/Raspberry_camera.html

https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://gitlab.freedesktop.org/HermannSW/gst-template
https://github.com/Hermann-SW/fork-raspiraw
https://twitter.com/HermannSW

miky94
Posts: 103
Joined: Sun Jun 03, 2018 9:17 pm

Re: best compromise quality/size for time-lapse camera

Sun Jun 09, 2019 10:18 pm

from what I read here https://www.raspberrypi.org/documentati ... re/camera/ the difference in resolution is greater than the difference in FoV, if I understood that means that at 1920x1080 v2 has better definition but worse FoV, right?
anyway seeing comparisons on the internet, in some v2 looks better in other v2 looks worse, so the difference is not so clear, surely not so clear to be worth that price difference.
regarding the quality parameter, I see no reason to use a value higher than 10, I can't figure out why the default is 85.

User avatar
HermannSW
Posts: 1394
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: best compromise quality/size for time-lapse camera

Mon Jun 10, 2019 6:58 am

I am sure there are scenes where 10 and 85 make a great difference, but if for your application there is none, go with 10.
in some v2 looks better in other v2 looks worse, so the difference is not so clear, surely not so clear to be worth that price difference.
From my main interests (global external shutter capturing and high framerate capturing), there are differences between v1 and v2 camera.

Only v1 camera has "global reset" feature, allowing to build your own external shutter and do global external shutter captures (without the nasty rolling shutter effect for fast moving objects). This is a 2MP multiple exposure capturing of an airgun pellet flying with 109m/s two times in same frame:
viewtopic.php?f=43&t=241418&p=1477441#p1477441
Image


v2 camera allows for up to 1007fps framerate capturing (v1 can to up to 665fps ) with raspiraw (raspivid is limited to 200fps by GPU), this is 1007fps framerate animation playing at 1fps, of a mouse trap bar closing in 10ms:
Image


In general you get double framerate for v2 over v1 when comparing same frame size:
viewtopic.php?f=43&t=212518&p=1310445#p1320034
Image


While maximal framerate for v1/v2 cameras is 665fps/1007fps because of needed frame data transfer from image sensor to Pi after each frame capture, you can do much higher "exposures per second" capturings with global external shutter capturing. The frame shown above was taken with strobe pulses of 8.33µs length at 3kHz PWM frequency, so it is a 3000eps frame. I did take 12000eps frame as well in same posting referenced above, up to 100,000eps captures seem to be possible.
⇨https://stamm-wilbrandt.de/en/Raspberry_camera.html

https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://gitlab.freedesktop.org/HermannSW/gst-template
https://github.com/Hermann-SW/fork-raspiraw
https://twitter.com/HermannSW

miky94
Posts: 103
Joined: Sun Jun 03, 2018 9:17 pm

Re: best compromise quality/size for time-lapse camera

Mon Jun 10, 2019 7:19 am

Ok @HermannSW but I guess on a Pi Zero you can't get such high frame rate right? how do you capture at multiple exposure? that probably would improve the quality
I did the quality/size test only on that scene, I'll try on other scenes to see if it is worth using a higher quality

User avatar
HermannSW
Posts: 1394
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: best compromise quality/size for time-lapse camera

Mon Jun 10, 2019 7:29 am

I just mentioned global external shutter and high framerate capturing in previous posting as general v1/v2 comparison features, not specific to your application scenario.
miky94 wrote:
Mon Jun 10, 2019 7:19 am
Ok @HermannSW but I guess on a Pi Zero you can't get such high frame rate right?
If you look eg. into 640x64 tool you see that it captures with 665fps for Non-PiZero and 500fps for PiZero, so yes, a bit slower, but not that much:
https://github.com/Hermann-SW/raspiraw/ ... /640x64#L8
For your application raspiraw high framerate capturing is unlikely to help, since you can capture only 8s of video at 500fps on PiZero and then the needed /dev/shm ramdisk is full.
how do you capture at multiple exposure?
Please find the details here:
https://github.com/Hermann-SW/Raspberry ... al_shutter
Global external shutter capturing requires dark scene and very bright (5000lm) leds, so it will not help for your current application.
⇨https://stamm-wilbrandt.de/en/Raspberry_camera.html

https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://gitlab.freedesktop.org/HermannSW/gst-template
https://github.com/Hermann-SW/fork-raspiraw
https://twitter.com/HermannSW

miky94
Posts: 103
Joined: Sun Jun 03, 2018 9:17 pm

Re: best compromise quality/size for time-lapse camera

Wed Jun 19, 2019 10:49 pm

and how can I detect darkness using picamera to trigger a shutdown?
how do I read the image and see if most of pixels are beyond a threshold close to black?

User avatar
HermannSW
Posts: 1394
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: best compromise quality/size for time-lapse camera

Thu Jun 20, 2019 12:34 am

miky94 wrote:
Wed Jun 19, 2019 10:49 pm
and how can I detect darkness using picamera to trigger a shutdown?
how do I read the image and see if most of pixels are beyond a threshold close to black?
I don't use picamera, but you can use picamera Array API.
For black detection you may use PiYUVArray and only look at the Y component:
https://picamera.readthedocs.io/en/rele ... piyuvarray
Or use PiRGBArray:
https://picamera.readthedocs.io/en/rele ... pirgbarray
⇨https://stamm-wilbrandt.de/en/Raspberry_camera.html

https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://gitlab.freedesktop.org/HermannSW/gst-template
https://github.com/Hermann-SW/fork-raspiraw
https://twitter.com/HermannSW

miky94
Posts: 103
Joined: Sun Jun 03, 2018 9:17 pm

Re: best compromise quality/size for time-lapse camera

Thu Jun 20, 2019 1:18 am

I said picamera just because I'm using it for time lapse, is there another easier solution?

User avatar
HermannSW
Posts: 1394
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: best compromise quality/size for time-lapse camera

Thu Jun 20, 2019 5:13 pm

If you need more than 200fps, the solution has to be based on raspiraw because GPU limits to 200fps.

In this posting you can see how to intercept raspiraw's frame capturing and control servo for robot camera tilt calibration:
viewtopic.php?t=189661#p1231151
I converted the difficult to access raw10 Bayer data from 640x480 to a 320x240 greyscale image on the fly for further processing.

Otherwise you can get support of GPU by utilizing raspividyuv (that gives easy to access pixel color data, .h264 from raspivid is not helpful).
This is the line in raspividyuv callback where you can add your own code to detect darkness:
https://github.com/6by9/userland/blob/m ... YUV.c#L865
You can access the width×height 8bit/px chromatic Y plane of YUV only and do your black detection based on that.
viewtopic.php?f=43&t=241110&p=1479262#p1479262
⇨https://stamm-wilbrandt.de/en/Raspberry_camera.html

https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://gitlab.freedesktop.org/HermannSW/gst-template
https://github.com/Hermann-SW/fork-raspiraw
https://twitter.com/HermannSW

miky94
Posts: 103
Joined: Sun Jun 03, 2018 9:17 pm

Re: best compromise quality/size for time-lapse camera

Tue Jun 25, 2019 9:50 pm

I think that PiYUVArray could do the work, but I don't understand how to read the array and count the pixels beyond a threshold that I could consider "darkness"

User avatar
HermannSW
Posts: 1394
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: best compromise quality/size for time-lapse camera

Wed Jun 26, 2019 12:40 am

> I think that PiYUVArray could do the work, but I don't understand how to read the array and count the pixels beyond a threshold that I could consider "darkness"
>
The example on picamera doc is wrong (misses 3rd argument ":1"), but it explains YUV:
https://picamera.readthedocs.io/en/late ... yuv-format

This code takes a frame and extracts the 2592*1944 bytes of Y plane (for v1 camera):

Code: Select all

$ cat PYA.py 
#!/usr/bin/env python

import picamera
import picamera.array
import numpy as np
from time import sleep

with picamera.PiCamera() as camera:
    with picamera.array.PiYUVArray(camera) as output:
        camera.resolution = (2592, 1944)
        camera.start_preview()
        sleep(2)

        camera.capture(output, 'yuv')
        print('Captured %dx%d image' % (
                output.array.shape[1], output.array.shape[0]))
        y_data = np.empty((1944, 2592), dtype=np.uint8)
        print('%d' % (y_data.size))
        y_data = output.array[:1944, :2592, :1]
        print((y_data.size))
$

This is generated output:

Code: Select all

$ ./PYA.py 
/usr/lib/python2.7/dist-packages/picamera/encoders.py:544: PiCameraResolutionRounded: frame size rounded up from 2592x1944 to 2592x1952
  width, height, fwidth, fheight)))
Captured 2592x1944 image
5038848
5038848
$

Per the doc y_data contains 1 byte of luminance for each pixel, from left to right per row, from top row to bottom row. Just check if each value is less than eg. 20 to consider it as dark.
⇨https://stamm-wilbrandt.de/en/Raspberry_camera.html

https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://gitlab.freedesktop.org/HermannSW/gst-template
https://github.com/Hermann-SW/fork-raspiraw
https://twitter.com/HermannSW

miky94
Posts: 103
Joined: Sun Jun 03, 2018 9:17 pm

Re: best compromise quality/size for time-lapse camera

Wed Jun 26, 2019 6:39 am

I don't understand in your code how do you loop each pixel and which is the luminance byte, so its value would be between 0-255 right?

User avatar
HermannSW
Posts: 1394
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: best compromise quality/size for time-lapse camera

Wed Jun 26, 2019 8:01 am

miky94 wrote:
Wed Jun 26, 2019 6:39 am
I don't understand in your code how do you loop each pixel and which is the luminance byte, so its value would be between 0-255 right?
Hi,

I had to learn myself, and my concerns on picamera have been confirmed.
This is the diff to iterate (and only count for now) the pixels of the frame:

Code: Select all

[email protected]:~ $ diff PYA.py.old PYA.py
20a21,27
> 
>         c=0
>         for y in y_data:
>             for x in y_data[y]:
>                 c+=1
> 
>         print(c)
[email protected]:~ $ 

But the runtime is soooo bad (on Pi3A+):

Code: Select all

$ time ./PYA.py     
/usr/lib/python2.7/dist-packages/picamera/encoders.py:544: PiCameraResolutionRounded: frame size rounded up from 2592x1944 to 2592x1952
  width, height, fwidth, fheight)))
Captured 2592x1944 image
5038848
5038848
5038848

real	1m5.213s
user	0m42.283s
sys	0m20.117s
$

I did caterpillar robot camera tilt calibration code in C/C++ and the performance was orders of magnitude better. You can look in my code how I determined the black bar on front of robot with grey2b+w conversion first and then checking for all 0s:
https://www.raspberrypi.org/forums/view ... 1#p1231151
Image


P.S:
I would do

Code: Select all

raspividyuv -md 2 -w 2592 -h 1944 -t 0 -o - | ./yourCcode
and in yourCcode.c I would read input in chunks of 2592*1952*3/2=7589376 bytes (rows have to be a multiple of 16, columns a multiple of 32). And only use the first 2592*1944 bytes of the chunks for the Y plane:
https://www.raspberrypi.org/forums/view ... 2#p1479262

Code: Select all

unsigned char p;
for(p=buffer+2592*1944-1; (p>=buffer) && (*p<20); --p) {}
p==(buffer-1) if and only if image is "dark".
⇨https://stamm-wilbrandt.de/en/Raspberry_camera.html

https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://gitlab.freedesktop.org/HermannSW/gst-template
https://github.com/Hermann-SW/fork-raspiraw
https://twitter.com/HermannSW

miky94
Posts: 103
Joined: Sun Jun 03, 2018 9:17 pm

Re: best compromise quality/size for time-lapse camera

Wed Jun 26, 2019 8:22 am

Thank you, I guess in my use case I could use a 400x300 image to elaborate 120.000 pixels instead of 5M decreasing in theory the runtime from 65s to 1.5s, also other improvements can be done, I have to test a bit.
so my question is:

Code: Select all

	for y in y_data:
		for x in y_data[y]:
			#how to detect darkness here?

User avatar
HermannSW
Posts: 1394
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: best compromise quality/size for time-lapse camera

Wed Jun 26, 2019 10:01 am

numpy arrays are weird, I had to use flatten to get a 1-dimensional array of 400*300=120000 bytes:

Code: Select all

$ cat PYA.py
#!/usr/bin/env python

import picamera
import picamera.array
import numpy as np
from time import sleep

with picamera.PiCamera() as camera:
    with picamera.array.PiYUVArray(camera) as output:
        camera.resolution = (400, 300)
        camera.start_preview()
        sleep(2)

        camera.capture(output, 'yuv')
        print('Captured %dx%d image' % (
                output.array.shape[1], output.array.shape[0]))
        y_data = np.empty((300, 400), dtype=np.uint8)
        print('%d' % (y_data.size))
        y_data = output.array[:300, :400, :1].flatten()

        dark = True
        for i in y_data:
            if y_data[i] > 20:
                dark = False

        print(dark)
$

I did close window shutter completely to get dark reported, without dark was false:

Code: Select all

$ time ./PYA.py
/usr/lib/python2.7/dist-packages/picamera/encoders.py:544: PiCameraResolutionRounded: frame size rounded up from 400x300 to 416x304
  width, height, fwidth, fheight)))
Captured 400x300 image
120000
False

real	0m4.846s
user	0m2.049s
sys	0m0.080s
$ time ./PYA.py
/usr/lib/python2.7/dist-packages/picamera/encoders.py:544: PiCameraResolutionRounded: frame size rounded up from 400x300 to 416x304
  width, height, fwidth, fheight)))
Captured 400x300 image
120000
True

real	0m4.800s
user	0m1.999s
sys	0m0.070s
$

Time is not that bad anymore with 400×300.
⇨https://stamm-wilbrandt.de/en/Raspberry_camera.html

https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://gitlab.freedesktop.org/HermannSW/gst-template
https://github.com/Hermann-SW/fork-raspiraw
https://twitter.com/HermannSW

miky94
Posts: 103
Joined: Sun Jun 03, 2018 9:17 pm

Re: best compromise quality/size for time-lapse camera

Wed Jun 26, 2019 11:19 am

ok thank you, so y_data values are between 0 and 255?

User avatar
HermannSW
Posts: 1394
Joined: Fri Jul 22, 2016 9:09 pm
Location: Eberbach, Germany
Contact: Website Twitter YouTube

Re: best compromise quality/size for time-lapse camera

Wed Jun 26, 2019 11:32 am

miky94 wrote:
Wed Jun 26, 2019 11:19 am
ok thank you, so y_data values are between 0 and 255?

Yes, 0..255 range. From picamera doc on yuv you can see each pixel taking a byte in Y-plane:
https://picamera.readthedocs.io/en/late ... yuv-format
Image
⇨https://stamm-wilbrandt.de/en/Raspberry_camera.html

https://github.com/Hermann-SW/Raspberry_v1_camera_global_external_shutter
https://gitlab.freedesktop.org/HermannSW/gst-template
https://github.com/Hermann-SW/fork-raspiraw
https://twitter.com/HermannSW

miky94
Posts: 103
Joined: Sun Jun 03, 2018 9:17 pm

Re: best compromise quality/size for time-lapse camera

Sat Jun 29, 2019 1:40 am

I get an error the second time I run camera.capture(output,'yuv')

Code: Select all

from time import time
from time import sleep
from picamera import PiCamera
from picamera.array import PiYUVArray
import numpy
camera=PiCamera()
output=PiYUVArray(camera)
w=64
h=48
camera.resolution=(w,h)
camera.start_preview()
sleep(2)
t=0
while True:
	t=t+1
	print(t)
	camera.capture(output,'yuv')
	sleep(5)

Code: Select all

[email protected]:~/Desktop $ clear ; python camera.py
1
Traceback (most recent call last):
  File "camera.py", line 17, in <module>
    camera.capture(output,'yuv')
  File "/usr/lib/python2.7/dist-packages/picamera/camera.py", line 1421, in capture
    if not encoder.wait(self.CAPTURE_TIMEOUT):
  File "/usr/lib/python2.7/dist-packages/picamera/encoders.py", line 395, in wait
    self.stop()
  File "/usr/lib/python2.7/dist-packages/picamera/encoders.py", line 419, in stop
    self._close_output()
  File "/usr/lib/python2.7/dist-packages/picamera/encoders.py", line 349, in _close_output
    mo.close_stream(output, opened)
  File "/usr/lib/python2.7/dist-packages/picamera/mmalobj.py", line 371, in close_stream
    stream.flush()
  File "/usr/lib/python2.7/dist-packages/picamera/array.py", line 296, in flush
    self.array = bytes_to_yuv(self.getvalue(), self.size or self.camera.resolution)
  File "/usr/lib/python2.7/dist-packages/picamera/array.py", line 93, in bytes_to_yuv
    'Incorrect buffer length for resolution %dx%d' % (width, height))
picamera.exc.PiCameraValueError: Incorrect buffer length for resolution 64x48

miky94
Posts: 103
Joined: Sun Jun 03, 2018 9:17 pm

Re: best compromise quality/size for time-lapse camera

Fri Jul 05, 2019 9:19 pm

I solved using:

Code: Select all

output.truncate(0)
I don't know if there are differences with output.seek(0)

is it possible to loop PiYUVArray on a stored image?

Return to “Camera board”