basler / pypylon

The official python wrapper for the pylon Camera Software Suite
http://www.baslerweb.com
BSD 3-Clause "New" or "Revised" License
540 stars 209 forks source link

Triggering the camera with a push button, raspberry Pi and python script #755

Open DiogoFerreira77 opened 1 month ago

DiogoFerreira77 commented 1 month ago

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
HighImp commented 3 weeks ago

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"

DiogoFerreira77 commented 1 week ago

@HighImp I want to press a pushbutton connected to the GPIO of the RPI and from that the camera should take a picture.

thiesmoeller commented 1 week ago

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()
DiogoFerreira77 commented 1 week ago

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 :)