basler / pypylon

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

_genicam.RuntimeException: Failed to open 'Basler acA2500-14gc. The device is controlled by another application #682

Closed thomaseude3 closed 10 months ago

thomaseude3 commented 10 months ago

Hello !

I am currently working on an application with PyQt6, using a Basler acA2500-14gc camera. I have built a framework that displays the live video stream from the camera on a PyQt6 window, and I have also successfully implemented buttons to capture images from this video stream with the following functions:

To open the camera:

self.camera = pylon.InstantCamera()
self.camera.Attach(pylon.TlFactory.GetInstance().CreateFirstDevice())
self.camera.Open()
self.camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly)

To take a photo:

grab = self.camera.RetrieveResult(1000, pylon.TimeoutHandling_ThrowException)

I do this for two different buttons, and then display these two photos on a new PyQt6 window. In this new window, I want to ask the user if the images are satisfactory, so they have two options (yes and no). The "yes" option will process the image with OpenCV image processing functions, and the "no" option should return to the initial window to capture a new image. Here is where my problem arises because it tells me that the camera is already in use:

_genicam.RuntimeException: Failed to open 'Basler acA2500-14gc. The device is controlled by another application.

However, I have connected the "no" option to the following lines to make sure to close the camera and reopen it later:

dev = self.camera.DetachDevice()
pylon.TlFactory.GetInstance().DestroyDevice(dev)
if not self.camera.IsOpen():
    self.camera = pylon.InstantCamera()
    self.camera.Attach(pylon.TlFactory.GetInstance().CreateFirstDevice())
    self.camera.Open()
    self.camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly)
    self.timer.start(50)  # Restart the timer to update the live video display
self.accept()  # Close the dialog box

This function is supposed to close and then reopen the camera to resume the live video stream in the first window. However, I still get the error message, even though my live video code is as follows:

def update_video(self):
    if self.camera.IsOpen():  # Check if the camera is still open
        grab = self.camera.RetrieveResult(1000, pylon.TimeoutHandling_ThrowException)
        if grab.GrabSucceeded():
            image = grab.Array

            height, width = image.shape
            bytes_per_line = 1 * width

            # Convert the image to QImage format
            image_qt = QImage(image.data, width, height, bytes_per_line, QImage.Format.Format_Grayscale8)

            # Display the image in the QLabel by adjusting its scale to fit the QLabel's size
            pixmap = QPixmap.fromImage(image_qt)
            self.image_label.setPixmap(pixmap.scaled(self.image_label.size(), Qt.AspectRatioMode.KeepAspectRatio))
            self.image_label.setScaledContents(True)

        grab.Release()
    else:
        self.timer.stop()

Could you help me with this issue? Thanks to everyone!

HighImp commented 10 months ago

Hi Thomas,

let me try a pseudo code to see if I understand your problem correctly:

enumerate and open camera
call "update_video"

while user dont click okay:
    detach and destroy cam,
    enumerate and open camera
    call "update_video"

Is there a reason why you need to close the camera between shots? And if so, it might be easier to close the camera right after capturing the image to be sure the camera is closed. Also, you have chosen a very hard method to close the camera. It should be enough to just call camera.Close() instead of detaching and destroying the object, and just call "Camera.Open" if you want the camera back opened.

thomaseude3 commented 10 months ago

Hi ! thanks for your response, finally, I did for the live video stream :

'if self.camera.IsOpen():

       grab = self.camera.RetrieveResult(1000, pylon.TimeoutHandling_ThrowException)`

and

else: self.camera = pylon.InstantCamera() self.camera.Attach(pylon.TlFactory.GetInstance().CreateFirstDevice()) self.camera.Open() self.camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly) grab = self.camera.RetrieveResult(1000, pylon.TimeoutHandling_ThrowException)

As the camera was already opened in each case, I could take the pictures with the function :

grab = self.camera.RetrieveResult(1000, pylon.TimeoutHandling_ThrowException) image_folder = "acquisition_image" if grab.GrabSucceeded(): .......... Thank you my problem is resolved !