waveform80/picamera

Frame freezes whilst try display/save high resolution frame

Opened this issue · 1 comments

image
With reference to - https://picamera.readthedocs.io/en/release-1.13/api_array.html#picamera.array.PiArrayOutput.truncate

Here we are trying to save one high-resolution image from the capture() function (every 15 frames) while running the low-resolution stream on the capture_continuous (), we find that the program freezes when trying to switch to the high-resolution image. How does one fix this?

Our readings show that we can change the resolution directly however it freezes in the same manner, refer to the above link (15.1):
image
From the image we see that one image is saved for the low resolution after which the resolution is changed to save another image.

context - we are trying to run a low-resolution preview in real-time and when the user presses a button a high-resolution image is saved.
We need fast fps for the preview hence the low res during the preview and then save a high res image.
We need the low resolution capture_continuous function in order for the preview to work.

import picamera.array
from picamera import PiCamera
from picamera.array import PiRGBArray
from picamera.exc import PiCameraValueError
import time
import cv2
import numpy as np
from datetime import datetime

camera = PiCamera()
camera.resolution = (320,240)
camera.framerate = 30

highResCap = PiRGBAArray(camera)  # new 4-byte-per-pixel version above
lowResCap = PiRGBAArray(camera, size=(320, 240))


lowResStream = camera.capture_continuous(lowResCap, format="bgra", use_video_port=True, splitter_port=2, resize=(320, 240))
time.sleep(2.0)
print("done warming up")
lowres_fc = 0
rawCaptureHiRes = PiRGBArray(camera, size=(3280, 2464))
while True:
    lrs = next(lowResStream)
    lrFrame = lrs.array
    lowres_fc+=1
    print("High res frame gen time: ",datetime.now().time())
    if lowres_fc%15==0:
        camera.resolution = (3280,2464)
        camera.capture(rawCaptureHiRes, splitter_port=1, format="bgr", use_video_port=True)
        print("GOT HIGH RES", str(rawCaptureHiRes.array.shape))
        img2 = cv2.cvtColor(rawCaptureHiRes.array, cv2.COLOR_BGR2GRAY)
        cv2.imwrite("testhrs.jpg", img2)
        camera.resolution = (320,240)
        print("High res frame save time: ",datetime.now().time())
    cv2.imshow('lores', lrFrame)
    if cv2.waitKey(1) == 27:
        break
6by9 commented

The sensor produces frames in one of a number of modes, and each mode can achieve a different maximum frame rate. See https://picamera.readthedocs.io/en/latest/fov.html#sensor-modes

When you request a high res frame, the sensor will stop, switch to the higher resolution/lower frame rate mode, capture the high res frame, stop the sensor again, switch to the lower resolution/higher frame rate mode, and then resume preview/low res capture.

You could use sensor_mode to force the sensor to stay in one mode all the time, but that will limit you on max frame rate (or max resolution).