Open ManoelVictor9 opened 7 months ago
In the companion repository pypylon-samples we have a demo for HW triggering. https://github.com/basler/pypylon-samples/blob/main/notebooks/USB_hardware_trigger_and_chunks.ipynb
And you can search under docs.baslerweb.com for triggered acquisition.
In the companion repository pypylon-samples we have a demo for HW triggering. https://github.com/basler/pypylon-samples/blob/main/notebooks/USB_hardware_trigger_and_chunks.ipynb
And you can search under docs.baslerweb.com for triggered acquisition.
Thanks for the help, but I've used these examples before and it didn't work well, I still don't know exactly how to implement the HW triggering in my code, could you tell me where I can change it and how I do it?
you need to set just 3 parameters:
cam.TriggerSelector = "FrameStart" cam.TriggerSource = "Line1" cam.TriggerMode = "On"
you need to set just 3 parameters:
camera.TriggerSelector.SetValue(TriggerSelector_FrameStart); camera.TriggerMode.SetValue(TriggerMode_On); camera.TriggerSource.SetValue(TriggerSource_Line1);
Sure, I tried that, but what is the variable that changes when I press the button? Bcs at the moment the variable is a flag when I press the space bar
...
if capture_flag: if len(resized_images) < num_images: resized_images.append(img.copy()) else: resized_images[current_image_index] = img.copy() current_image_index = (current_image_index + 1) % num_images capture_flag = False
...
if key == 27: break elif key == ord(' '): #capture the next image capture_flag = True camera.StopGrabbing()
Hi Manoel, I hope I understood your problem, you want to replace the spacebar click directly with an external trigger, right?
To solve the problem that you are waiting for an image and handling the cv2 function at the same time, the best way is to use the ImageEventHandler.
Nevertheless, I tried to change your code a bit to achieve your goal in a somewhat hacky way by using the WaitObject.
Please forgive me for rearranging a few lines and translating your comments, my Portuguese is terrible ;-)
A note for readability: please surround all your code with Python Markdown in github comments, so the indentations will survive.
Best regards
from pypylon import pylon
import cv2
import numpy as np
camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice())
# changing this to True changes the Trigger to Line1 instead of the SpaceKey
EXTERNAL_TRIGGER = False
try:
# setup camera aoi
camera.Open()
camera.Width.Value = camera.Width.Max
camera.Height.Value = camera.Height.Max
# set camera to frame trigger mode on Line1
camera.TriggerSelector.Value = "FrameStart"
if EXTERNAL_TRIGGER:
camera.TriggerSource.Value = "Line1"
else:
camera.TriggerSource.Value = "Software"
camera.TriggerMode.Value = "On"
except Exception as e:
print(f"Error when configuring the camera: {e}")
# constant values
num_images = 4
screen_width, screen_height = 1300, 760
# runtime values
resized_images = []
current_image_index = 0
combined_image = np.zeros((screen_height, screen_width, 3), dtype=np.uint8)
# configure image converter
converter = pylon.ImageFormatConverter()
converter.OutputPixelFormat = pylon.PixelType_BGR8packed
converter.OutputBitAlignment = pylon.OutputBitAlignment_MsbAligned
camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly)
while camera.IsGrabbing():
while current_image_index < num_images:
cv2.imshow('Combined Images', combined_image)
key = cv2.waitKey(1)
if key == 27: # Esc key to exit
camera.StopGrabbing()
break
elif not EXTERNAL_TRIGGER and key == ord(" "):
camera.ExecuteSoftwareTrigger()
# you cant check your key entry and wait for the next image in one thread at the same time,
# so you can use this wait-object to check for new images and skip the 5 sec Timeout during RecieveResult
if not camera.GetGrabResultWaitObject().Wait(10):
continue
try:
# use the context handler, so you dont have to call "grabResult.Release" at the end
with camera.RetrieveResult(5000, pylon.TimeoutHandling_ThrowException) as grabResult:
assert grabResult.GrabSucceeded()
# Accessing image data
image = converter.Convert(grabResult)
img = image.GetArray()
except pylon.TimeoutException as timeout_error:
raise AssertionError("Timeout error, this should not happen, "
"because we waited for the image in the wait object before!") from timeout_error
except AssertionError as assertion_error:
raise AssertionError("Unsuccessful grab, this should not happen at all!") from assertion_error
# we dont need the capture flag variable anymore,
# because of every image is grabbed on purpose, just add every incoming image
if len(resized_images) < num_images:
resized_images.append(img.copy())
else:
resized_images[current_image_index] = img.copy()
current_image_index = (current_image_index + 1) % num_images
for i in range(len(resized_images)):
h, w, _ = resized_images[i].shape
h_ratio = screen_height // 2
w_ratio = screen_width // 2
row = i // 2
col = i % 2
resized_images[i] = cv2.resize(resized_images[i], (w_ratio, h_ratio))
combined_image[row * h_ratio: (row + 1) * h_ratio, col * w_ratio: (col + 1) * w_ratio, :] = resized_images[
i]
cv2.waitKey(0)
cv2.destroyAllWindows()
camera.Close()
Hi Manoel, I hope I understood your problem, you want to replace the spacebar click directly with an external trigger, right?
To solve the problem that you are waiting for an image and handling the cv2 function at the same time, the best way is to use the ImageEventHandler.
Nevertheless, I tried to change your code a bit to achieve your goal in a somewhat hacky way by using the WaitObject.
Please forgive me for rearranging a few lines and translating your comments, my Portuguese is terrible ;-) A note for readability: please surround all your code with Python Markdown in github comments, so the indentations will survive.
Best regards
from pypylon import pylon import cv2 import numpy as np camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice()) # changing this to True changes the Trigger to Line1 instead of the SpaceKey EXTERNAL_TRIGGER = False try: # setup camera aoi camera.Open() camera.Width.Value = camera.Width.Max camera.Height.Value = camera.Height.Max # set camera to frame trigger mode on Line1 camera.TriggerSelector.Value = "FrameStart" if EXTERNAL_TRIGGER: camera.TriggerSource.Value = "Line1" else: camera.TriggerSource.Value = "Software" camera.TriggerMode.Value = "On" except Exception as e: print(f"Error when configuring the camera: {e}") # constant values num_images = 4 screen_width, screen_height = 1300, 760 # runtime values resized_images = [] current_image_index = 0 combined_image = np.zeros((screen_height, screen_width, 3), dtype=np.uint8) # configure image converter converter = pylon.ImageFormatConverter() converter.OutputPixelFormat = pylon.PixelType_BGR8packed converter.OutputBitAlignment = pylon.OutputBitAlignment_MsbAligned camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly) while camera.IsGrabbing(): while current_image_index < num_images: cv2.imshow('Combined Images', combined_image) key = cv2.waitKey(1) if key == 27: # Esc key to exit camera.StopGrabbing() break elif not EXTERNAL_TRIGGER and key == ord(" "): camera.ExecuteSoftwareTrigger() # you cant check your key entry and wait for the next image in one thread at the same time, # so you can use this wait-object to check for new images and skip the 5 sec Timeout during RecieveResult if not camera.GetGrabResultWaitObject().Wait(10): continue try: # use the context handler, so you dont have to call "grabResult.Release" at the end with camera.RetrieveResult(5000, pylon.TimeoutHandling_ThrowException) as grabResult: assert grabResult.GrabSucceeded() # Accessing image data image = converter.Convert(grabResult) img = image.GetArray() except pylon.TimeoutException as timeout_error: raise AssertionError("Timeout error, this should not happen, " "because we waited for the image in the wait object before!") from timeout_error except AssertionError as assertion_error: raise AssertionError("Unsuccessful grab, this should not happen at all!") from assertion_error # we dont need the capture flag variable anymore, # because of every image is grabbed on purpose, just add every incoming image if len(resized_images) < num_images: resized_images.append(img.copy()) else: resized_images[current_image_index] = img.copy() current_image_index = (current_image_index + 1) % num_images for i in range(len(resized_images)): h, w, _ = resized_images[i].shape h_ratio = screen_height // 2 w_ratio = screen_width // 2 row = i // 2 col = i % 2 resized_images[i] = cv2.resize(resized_images[i], (w_ratio, h_ratio)) combined_image[row * h_ratio: (row + 1) * h_ratio, col * w_ratio: (col + 1) * w_ratio, :] = resized_images[ i] cv2.waitKey(0) cv2.destroyAllWindows() camera.Close()
It worked perfectly, Thank you so Much!
Describe what you want to implement and what the issue & the steps to reproduce it are:
Hi! The objective of my code is to capture images divided into 4 quadrants in a constant loop, I currently use the space key to capture, but I need to do it using a hardware trigger on "Line1" with "RisingEdge" and after days and days of research, I was unable to carry out this implementation. Thanks, any help would be appreciated!
Code:
from pypylon import pylon import cv2 import numpy as np
camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice())
try: camera.Open() camera.WidthMax.SetValue(camera.WidthMax.GetMax()) camera.HeightMax.SetValue(camera.HeightMax.GetMax()) except Exception as e: print(f"Erro ao definir a largura e a altura da câmera: {e}") finally: camera.Close()
camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly) converter = pylon.ImageFormatConverter()
converter.OutputPixelFormat = pylon.PixelType_BGR8packed converter.OutputBitAlignment = pylon.OutputBitAlignment_MsbAligned
num_images = 4
resized_images = []
capture_flag = False
current_image_index = 0
screen_width, screen_height = 1300, 760
while camera.IsGrabbing(): grabResult = camera.RetrieveResult(5000, pylon.TimeoutHandling_ThrowException)
if grabResult.GrabSucceeded():
Acessando os dados da imagem
grabResult.Release()
key = cv2.waitKey(1) if key == 27: # Tecla 'esc' para sair break elif key == ord(' '): # Tecla de espaço para capturar a próxima imagem capture_flag = True camera.StopGrabbing()
cv2.waitKey(0) cv2.destroyAllWindows()
Image exemple: