Hi there! Did a few searches and couldn’t find a similar problem on these forums, hope I’m not asking a common question/ didn’t use the right search terms.
I’m writing an autofocus script for a Raspberry Pi camera. In the script, Laplachian edge detection outputs a variable to act as a rough approximate for focus, and once the variable reaches a certain threshold, it triggers an LED to blink at different speeds. Faster LED, better focus. All this is because don’t want this camera to have a screen, but am using a manual focus lens.
I need to stream at 640x480 for the Raspberry Pi to process the edge detection quick enough for immediate focus feedback, but I want to capture at higher resolutions. (I can seemingly only go to 1920x1080, even though the Pi HQ camera I’m using has a higher resolution for still images–but that’s a problem for later.)
My code is super simple, but I think I’m misunderstanding how the camera stream interacts with image capture. In the code I’m trying to stop the 480p video stream, start a 1080p video stream, capture a frame, and then start the 480p stream again.
If there’s another way to approach this, or a way to fix my existing code, it would be super welcome. Thanks so much for your time!
Code below:
from gpiozero import Button, LED
from time import sleep
import os
#load physical buttons
button = Button(23, hold_time=1)
led = LED(24)
#boot confirmation
print('loaded modules')
led.on()
sleep(.5)
led.off()
sleep(.5)
led.on()
sleep(.5)
led.off()
import cv2
import numpy as np
#boot confirmation
print('loaded modules')
led.on()
sleep(.5)
led.off()
sleep(.5)
led.on()
sleep(.5)
led.off()
#video capture
cap = cv2.VideoCapture(0)
#filename counter
img_counter = 0
#main loop
while True:
#capture video
ret, frame = cap.read()
#grayscale for easier processing
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
#get focus and print
laplacian_var = cv2.Laplacian(gray, cv2.CV_64F).var()
print(laplacian_var)
#led on sharp
if laplacian_var > 80:
led.on()
sleep(.1)
led.off()
#led starting to focus
if laplacian_var > 30 and laplacian_var < 79:
led.on()
sleep(.5)
led.off()
#capture image
if button.is_pressed:
img_name = 'img_{}.jpg'.format(img_counter)
os.chdir(r'/home/pi/photos')
cap.release()
cap.set(3, 1920)
cap.set(4, 1080)
ret, frame = cap.read()
cv2.imwrite(img_name, frame)
print('{} written!'.format(img_name))
img_counter +=1
cap.release()
cap.set(3, 640)
cap.set(4, 480)
if button.is_held:
led.on()
sleep(2)
led.off()
break
cap.release()
Thanks again!