basler / pypylon-samples

BSD 3-Clause "New" or "Revised" License
40 stars 14 forks source link

Grab sequence of images with different exposure times #2

Open dvirmarsh opened 1 year ago

dvirmarsh commented 1 year ago

Hey, I own a Basler DART USB camera and want to capture a series of images with varying exposure times to create an HDR image. Is there a command available to perform this task without using loops? Thanks, Dvir

thiesmoeller commented 1 year ago

On the dart series it is only possible with tight loop. Ace has sequencer feature to realize this on the camera

Recommended to use Softwaretrigger on the dart.

Setup software trigger Start grabbing Loop

dvirmarsh commented 1 year ago

I have wrote this function: def capture_hdr_images(camera, exposure_times):

images = []
for exposure_time in exposure_times:
    camera.ExposureTime.SetValue(exposure_time)  # set exposure time
    camera.ExecuteSoftwareTrigger()
    grab_result = camera.RetrieveResult(5000, py.TimeoutHandling_ThrowException)
    images.append(grab_result.Array)
return images

But when looking at the images array, I see that the images intensity do not match the exposure times, I think that the camera takes the images before the exposure time was changed, could it be fixed? Thanks in advance

thiesmoeller commented 1 year ago

Can you show your setup code to check for possible issue in trigger setup

dvirmarsh commented 1 year ago

This is the code:

def capture_hdr_images(camera, exposure_times):

images = []
for exposure_time in exposure_times:
    camera.ExposureTime.SetValue(exposure_time)  # set exposure time
    camera.ExecuteSoftwareTrigger()
    grab_result = camera.RetrieveResult(5000, py.TimeoutHandling_ThrowException)
    images.append(grab_result.Array)
return images

tlf = py.TlFactory.GetInstance() devices = tlf.EnumerateDevices() devices_SN = [d.GetSerialNumber() for d in devices] camera_index = devices_SN.index('40238137')

cam = py.InstantCamera(tlf.CreateDevice(devices[camera_index])) cam.Open() cam.StartGrabbing(py.GrabStrategy_LatestImageOnly)

images = capture_hdr_images(cam, [20, 100, 1000, 10000])

fig, axs = plt.subplots(2, 2) axs[0, 0].imshow(images[0]) axs[0, 0].set_title('exposure time 20')

axs[0, 1].imshow(images[1]) axs[0, 1].set_title('exposure time 100')

axs[1, 0].imshow(images[2]) axs[1, 0].set_title('exposure time 1000')

axs[1, 1].imshow(images[3]) axs[1, 1].set_title('exposure time 10000') plt.show() Figure_1

The figure is attached.

thiesmoeller commented 1 year ago

you were missing the configuration for the software trigger. With out this, the camera will start free running.

added the code before start grabbing and also added a check, that the camera is ready for a frame trigger. This is not required in your case, but would be important if you reduce the ROI of the camera. In this case, you might have the video data already available, but the camera needs some more milliseconds to be ready for next frame.

Code is not tested ;-)

and you can use

```python
<your code>

to make your src code pretty

```python
def capture_hdr_images(camera, exposure_times):
    images = []
    for exposure_time in exposure_times:
        camera.ExposureTime.SetValue(exposure_time)  # set exposure time
        # wait for camera ready to execute software trigger
        if camera.WaitForFrameTriggerReady(200, pylon.TimeoutHandling_ThrowException):
           camera.TriggerSoftware.Execute()

        grab_result = camera.RetrieveResult(5000, py.TimeoutHandling_ThrowException)
        images.append(grab_result.Array)
    return images

tlf = py.TlFactory.GetInstance()
devices = tlf.EnumerateDevices()
devices_SN = [d.GetSerialNumber() for d in devices]
camera_index = devices_SN.index('40238137')

cam = py.InstantCamera(tlf.CreateDevice(devices[camera_index]))
cam.Open()`

# setup software trigger
cam.TriggerSelector.SetValue("FrameStart")
cam.TriggerSource.SetValue("Software")
cam.TriggerMode.SetValue("On")

cam.StartGrabbing(py.GrabStrategy_LatestImageOnly)

images = capture_hdr_images(cam, [20, 100, 1000, 10000])

fig, axs = plt.subplots(2, 2)
axs[0, 0].imshow(images[0])
axs[0, 0].set_title('exposure time 20')

axs[0, 1].imshow(images[1])
axs[0, 1].set_title('exposure time 100')

axs[1, 0].imshow(images[2])
axs[1, 0].set_title('exposure time 1000')

axs[1, 1].imshow(images[3])
axs[1, 1].set_title('exposure time 10000')
plt.show()
dvirmarsh commented 1 year ago

Works! Thanks for the help!