Triggering the camera with a push button, raspberry Pi and python script
Getting images by triggering the camera with a push button and a raspberry pi 4:
Hi,
I'm developing a project where I have to acquire images and process them for object detection using YoloV5. At the moment I have a code that opens the camera and shows me an image, and if I press a random key of the keyboard it shows me the image of that moment. However, I don't want that and instead, I would want to get an image when I press a push button. How can I do it?
from pypylon import pylon
import cv2
import numpy as np
import torch
weight_small = 'C:/Weights/4th_train/best.pt'
model = torch.hub.load('ultralytics/yolov5', 'custom', path = weight_small, force_reload = False)
i = 0
camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateDevice(pylon.TlFactory.GetInstance().EnumerateDevices()))
camera.Open()
camera.AcquisitionMode.SetValue('Continuous')
try:
# Start grabbing images
camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly)
print("Camera grabbing")
while camera.IsGrabbing():
grab_result = camera.RetrieveResult(500, pylon.TimeoutHandling_ThrowException)
if grab_result.GrabSucceeded():
# Access the image data
image = grab_result.Array
results = model(image)
cv2.imshow('YOLO', np.squeeze(results.render()))
#count images taken
i += 1
if cv2.waitKey(0) & 0xFF == ord('q'):
break
grab_result.Release()
except KeyboardInterrupt:
pass
# Stop grabbing images
camera.StopGrabbing()
print("Stoped grabing")
# Close the camera
camera.Close()
cv2.destroyAllWindows()
I'm new to pylon so there might be some errors in the code. Any help on this would be appreciated :)
Is your camera operational in Basler pylon viewer on your platform
Yes
Hardware setup & camera model(s) used
Raspberry Pi 4 8GB ARM64 Camera: Basler aca1300-30gm Interface used to connect the camera: GigE
Runtime information:
python: 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0]
platform: linux/aarch64/6.6.20+rpt-rpi-v8
pypylon: 3.0.1 / 7.4.0.38864
Hi, do you want to press a pushbutton, connected to the Pi, and let the Pi execute a software trigger, or do you want to connect the Raspberry IOs/Push Button directly to the Camera for hardware trigger?
For software trigger, please find the example under: "samples/grabstrategies.py"
@HighImp I want to press a pushbutton connected to the GPIO of the RPI and from that the camera should take a picture.
One possible implementation is roughly this
import RPi.GPIO as GPIO
import time
from pypylon import pylon
# Configure GPIO
BUTTON_PIN = 18 # Change this to your actual GPIO pin number
GPIO.setmode(GPIO.BCM)
GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP)
# Configure camera
camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice())
camera.Open()
# Set camera to software trigger mode
camera.TriggerMode.SetValue('On')
camera.TriggerSource.SetValue('Software')
def trigger_camera(channel):
print("Button pressed, sending software trigger to camera...")
camera.TriggerSoftware.Execute()
grabResult = camera.RetrieveResult(5000, pylon.TimeoutHandling_ThrowException)
if grabResult.GrabSucceeded():
# Access the image data
image = grabResult.Array
print("Image grabbed successfully.")
# Do something with the image (e.g., save it, process it, etc.)
else:
print("Failed to grab image.")
grabResult.Release()
# Add event detection on the button pin
GPIO.add_event_detect(BUTTON_PIN, GPIO.FALLING, callback=trigger_camera, bouncetime=300)
print("Waiting for button press...")
try:
# Start grabbing asynchronously.
camera.StartGrabbing(pylon.GrabStrategy_OneByOne, pylon.GrabLoop_ProvidedByInstantCamera)
while camera.IsGrabbing():
time.sleep(1)
except KeyboardInterrupt:
print("Exiting...")
# Clean up
GPIO.cleanup()
camera.StopGrabbing()
camera.Close()
One possible implementation is roughly this
import RPi.GPIO as GPIO import time from pypylon import pylon # Configure GPIO BUTTON_PIN = 18 # Change this to your actual GPIO pin number GPIO.setmode(GPIO.BCM) GPIO.setup(BUTTON_PIN, GPIO.IN, pull_up_down=GPIO.PUD_UP) # Configure camera camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice()) camera.Open() # Set camera to software trigger mode camera.TriggerMode.SetValue('On') camera.TriggerSource.SetValue('Software') def trigger_camera(channel): print("Button pressed, sending software trigger to camera...") camera.TriggerSoftware.Execute() grabResult = camera.RetrieveResult(5000, pylon.TimeoutHandling_ThrowException) if grabResult.GrabSucceeded(): # Access the image data image = grabResult.Array print("Image grabbed successfully.") # Do something with the image (e.g., save it, process it, etc.) else: print("Failed to grab image.") grabResult.Release() # Add event detection on the button pin GPIO.add_event_detect(BUTTON_PIN, GPIO.FALLING, callback=trigger_camera, bouncetime=300) print("Waiting for button press...") try: # Start grabbing asynchronously. camera.StartGrabbing(pylon.GrabStrategy_OneByOne, pylon.GrabLoop_ProvidedByInstantCamera) while camera.IsGrabbing(): time.sleep(1) except KeyboardInterrupt: print("Exiting...") # Clean up GPIO.cleanup() camera.StopGrabbing() camera.Close()
Thank you @thiesmoeller :)