Open jeffwitz opened 2 months ago
Dear all,
I'm not sure you'll have time to deal with this problem in the Harvester and I still think it's a major problem for people who want to use Harvester to do image processing which can be a bit long between buffer acquisitions, I've made an example with a simplistic class that solves the problem, that you can find here :
import numpy as np
import time
from typing import Optional,Tuple, List, Dict, Any
import cv2
from harvesters.core import Harvester
from threading import Thread, RLock
class GenicamHarvesterCamera():
def __init__(self) -> None:
self.camera = None
self.h = Harvester()
self.h.add_file('/opt/mvIMPACT_Acquire/lib/x86_64/mvGenTLProducer.cti')
self.h.update()
self.num_image = 0
self.channels = '1'
self._frame_grabber = None
self._lock = RLock()
self._frame = None
self._stop = False
def open(self) -> None:
self.ia = self.h.create()
self.ia.start()
self._frame_grabber = Thread(target=self._grab_frame)
self._stop = False
self._frame_grabber.start()
def _grab_frame(self) -> None:
while not self._stop:
with self.ia.fetch() as buffer:
component = buffer.payload.components[0]
# Extraire les données nécessaires de component
frame_data = {
'data': np.frombuffer(component.data, dtype=np.uint8).copy(),
'width': component.width,
'height': component.height,
'data_format': component.data_format
}
with self._lock:
# Stocker les données extraites de manière thread-safe
self._frame = frame_data
def get_image(self) -> Tuple[Dict[str, Any], np.ndarray]:
with self._lock:
# Utiliser les données stockées pour créer l'image
frame_data = self._frame
img = frame_data['data'].reshape((frame_data['height'], frame_data['width']))
img_data = self._process_image_data(img, frame_data['data_format'])
metadata = {
't(s)': time.time(),
'ImageUniqueID': self.num_image,
}
self.num_image += 1
return metadata, img_data
def _process_image_data(self, img, data_format) -> np.ndarray:
# Adapter cette méthode pour traiter les données d'image en fonction du format
if data_format == 'BayerRG8':
img_data = cv2.cvtColor(img, cv2.COLOR_BAYER_BG2BGR)
if self.channels == '1':
img_data = cv2.cvtColor(img_data, cv2.COLOR_BGR2GRAY)
elif self.channels == '3':
img_data = img_data.copy()
return img_data
def close(self):
self._stop = True
if self._frame_grabber is not None:
self._frame_grabber.join()
self.ia.stop()
self.ia.destroy()
self.h.reset()
if __name__=='__main__':
cam = GenicamHarvesterCamera()
cam.channels = '1'
cam.open()
cv2.namedWindow('frame', cv2.WINDOW_NORMAL)
sleep_bug = 0.1
while(True):
# do something with the image
time.sleep(sleep_bug) # you can change it with the Tread it never bugs anymore
cv2.imshow('frame', cam.get_image()[1])
if cv2.waitKey(1) & 0xFF == ord('q'):
cam.close()
cv2.destroyAllWindows()
break
This remains a workaround that I find unsatisfactory, and for this reason I hope, if you agree, that the issue will remain open.
If someone finds this thread, then they'll have a solution until this problem is dealt with in the library itself. Regards
@jeffwitz Can you try to increase the number of buffers in the image acquirer? Something like this:
ia = h.create()
ia.num_buffers=10
Describe the Issue I make a simple class that allows one to init a cam, open it, the get image from it and finally close it when needed. You can fond the code here :
To Reproduce Steps to reproduce the behavior: Launch this code with a camera that bugs.
Sample Code I can show a piece of code that demonstrates the reported phenomenon:
You can change the : sleep_bug if it is over 0.01, then it start to bug for me.
If yes, please provide a sample code:
If applicable, please paste the actual output (its whole traceback, etc) here: There is no errors, just corrupted buffers
Expected Behavior no corrupted buffers, as everything is done with
with
Configuration Computer Python 3.11.2 [GCC 12.2.0] harvesters : 1.4.2 OS: Debian GNU/Linux 12 (bookworm) x86_64 Kernel: 6.6.13+bpo-rt-amd64 CPU: AMD Ryzen 7 PRO 7840U w/ Radeon 780M Graphics (16) @ 5.132GHz GPU: AMD ATI c3:00.0 Phoenix1 GenTL Producer: /mvIMPACT_Acquire/lib/x86_64/mvGenTLProducer.cti CameraReproducibility
This phenomenon can be stably reproduced:
If applicable, please provide your observation about the reproducibility. Does not affect the other gige cam I have.
Actions You Have Taken Explain it to you.
If it doesn't work, we will launch a thread that will implement is own buffer management in order work safely, it is not the thing we want to to, but a lot of time without success has passed ...
Additional context