Skip to content

Camera not closing properly after successful run #847

@xcode003

Description

@xcode003

Describe what you want to implement and what the issue & the steps to reproduce it are:

I'm aiming to capture and save image frames in a continuously updating fixed size queue

When calling my script buffer.py the camera frames are successfully grabbed and displayed, but when I escape an error is thrown:
"Error stopping grabbing: Node not existing (file 'genicam_wrap.cpp', line 16822)"

The next time I run the script the code does not run and a persistent error comes up:
"pure virtual method called
terminate called without an active exception
Aborted (core dumped)"

I'm thinking it's because some module is not being closed properly, but I'm not sure where or how

with SafePylonCamera() as cam:
    print(f"{fps} FPS at {res_width}x{res_height}")
    cam.start_grabbing()

    # --------------------- OUTPUT FOLDER SETUP ---------------------
    buffer_folder = "./buffer"
    if os.path.isdir(buffer_folder):
        shutil.rmtree(buffer_folder)
    os.makedirs(buffer_folder)
    # ---------------------------------------------------------------

    prev_time = time.time()
    og_time = prev_time
    while cam.is_grabbing():
        cur_time = time.time()
        print(f'Camera running at {round(1.0/(cur_time - prev_time),1)} frames per second')
        frame = cam.retrieve_frame((cur_time - prev_time) >= 1.0 / fps) #condition passed in; if not time yet, returns None
        if frame is not None:
            prev_time = cur_time
            frame = cv2.resize(frame, (res_width, res_height))

            delta = round(time.time() - og_time, 3)
            filename = os.path.join(buffer_folder, f"{delta}.png")
            cv2.imwrite(filename, frame)
            
            # Maintain buffer size
            all_frames = os.listdir(buffer_folder)
            ranked_indices = sorted([(float(re.match(r"\d+.\d*", filename).group()),i) for i, filename in enumerate(all_frames)])
            if len(all_frames) > length:
                os.remove(os.path.join(buffer_folder, all_frames[ranked_indices[0][1]]))
cv2.imshow("Camera", frame)
            
            if cv2.waitKey(1) == 27:
                print("----Interrupt via ESC----")
                break
        else:
            print('Missed frame')
class SafePylonCamera:
    def __init__(self, strategy=pylon.GrabStrategy_LatestImageOnly, timeout=5000):
        self.camera = None
        self.converter = None
        self.strategy = strategy
        self.timeout = timeout
        self._grabbing = False

        # Register cleanup
        atexit.register(self.close)
        signal.signal(signal.SIGINT, self._signal_handler)
        signal.signal(signal.SIGTERM, self._signal_handler)

    def open(self):
        self.camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice())
        self.camera.Open()
        self.converter = pylon.ImageFormatConverter()
        self.converter.OutputPixelFormat = pylon.PixelType_BGR8packed
        self.converter.OutputBitAlignment = pylon.OutputBitAlignment_MsbAligned
        print("[SafePylonCamera] Camera opened.")

    def start_grabbing(self):
        if self.camera and not self._grabbing:
            self.camera.StartGrabbing(self.strategy)
            self._grabbing = True
            print("[SafePylonCamera] Started grabbing.")

    def retrieve_frame(self,condition):
        if condition and self.camera and self._grabbing:
            result = self.camera.RetrieveResult(self.timeout, pylon.TimeoutHandling_ThrowException)
            if result.GrabSucceeded():
                image = self.converter.Convert(result)
                frame = image.GetArray()
                result.Release()
                return frame
            result.Release()
        return None

    def is_grabbing(self):
        return self.camera and self._grabbing and self.camera.IsGrabbing()

    def stop_grabbing(self):
        if self.camera and self.camera.IsGrabbing():
            self.camera.StopGrabbing()
            print("[SafePylonCamera] Stopped grabbing.")
        self._grabbing = False

    def close(self):
        if self.camera:
            self.stop_grabbing()
            if self.camera.IsOpen():
                self.camera.Close()
                print("[SafePylonCamera] Camera closed.")
            self.camera = None
        cv2.destroyAllWindows()
        gc.collect()

    def _signal_handler(self, sig, frame):
        print(f"\n[SafePylonCamera] Signal {sig} received. Cleaning up.")
        self.close()
        sys.exit(0)

    def __enter__(self):
        self.open()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()

Is your camera operational in Basler pylon viewer on your platform

Yes

Hardware setup used

Basler is connected via USB to a GMKtec Nuc running Ubuntu OS

Camera(s) used

to be updated

Runtime information:

to be updated

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions