Skip to content

Commit

Permalink
Merge pull request #568 from mprib/mprib/issue567
Browse files Browse the repository at this point in the history
Mprib/issue567
  • Loading branch information
mprib authored Dec 6, 2023
2 parents ab286ae + 190897b commit 95cfdb3
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 54 deletions.
31 changes: 26 additions & 5 deletions pyxy3d/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,20 +129,23 @@ def load_extrinsic_stream_manager(self):

def process_extrinsic_streams(self, fps_target=None):
def worker():
output_path = Path(self.workspace_guide.extrinsic_dir, "CHARUCO", "xy_CHARUCO.csv")
output_path.unlink() # make sure this doesn't exist to begin with.

self.load_extrinsic_stream_manager()
self.extrinsic_stream_manager.process_streams(fps_target=fps_target)

output_path = Path(self.extrinsic_dir, "CHARUCO", "xy_CHARUCO.csv")
logger.info(f"Processing of extrinsic calibration begun...waiting for output to populate: {output_path}")
while not output_path.exists():
sleep(0.5)
logger.info(
f"Waiting for 2D tracked points to populate at {output_path}"
)

self.extrinsic_process_thread = QThread()
self.extrinsic_process_thread.run = worker
self.extrinsic_process_thread.finished.connect(self.extrinsic_2D_complete.emit)
self.extrinsic_process_thread.start()
# self.extrinsic_process_thread = QThread()
# self.extrinsic_process_thread.run = worker
# self.extrinsic_process_thread.finished.connect(self.extrinsic_2D_complete.emit)
# self.extrinsic_process_thread.start()


def load_intrinsic_stream_manager(self):
Expand Down Expand Up @@ -222,6 +225,7 @@ def scale_intrinsic_stream(self, port, new_scale):

def calibrate_camera(self, port):
def worker():
# self.intrinsic_stream_manager.pause_stream(port)
logger.info(f"Calibrating camera at port {port}")
self.intrinsic_stream_manager.calibrate_camera(port)
self.push_camera_data(port)
Expand Down Expand Up @@ -288,6 +292,23 @@ def estimate_extrinsics(self):
"""

def worker():
output_path = Path(self.workspace_guide.extrinsic_dir, "CHARUCO", "xy_CHARUCO.csv")
if output_path.exists():
output_path.unlink() # make sure this doesn't exist to begin with.

self.load_extrinsic_stream_manager()
self.extrinsic_stream_manager.process_streams(fps_target=100)

logger.info(f"Processing of extrinsic calibration begun...waiting for output to populate: {output_path}")

while not output_path.exists():
sleep(0.5)
logger.info( f"Waiting for 2D tracked points to populate at {output_path}")

# note that this processing will wait until it is complete
self.process_extrinsic_streams(fps_target=100)
logger.info("Processing if extrinsic caliberation streams complete...")

self.extrinsic_calibration_xy = Path(
self.workspace, "calibration", "extrinsic", "CHARUCO", "xy_CHARUCO.csv"
)
Expand Down
23 changes: 10 additions & 13 deletions pyxy3d/gui/camera_management/playback_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,10 @@ def __init__(self, controller: Controller, port: int, parent=None):
self.frame_image = QLabel(self)
self.frame_index_label = QLabel(self)
self.play_button = QPushButton("", self)
play_icon = self.style().standardIcon(QStyle.SP_MediaPlay)
self.play_button.setIcon(play_icon)
self.play_icon = self.style().standardIcon(QStyle.SP_MediaPlay)
self.pause_icon = self.style().standardIcon(QStyle.SP_MediaPause)

self.play_button.setIcon(self.play_icon)
self.slider = CustomSlider()
self.slider.setMaximum(self.total_frames - 1)

Expand Down Expand Up @@ -177,21 +179,19 @@ def play_video(self):
if self.is_playing:
self.is_playing = False
self.controller.pause_intrinsic_stream(self.port)
play_icon = self.style().standardIcon(QStyle.SP_MediaPlay)
self.play_button.setIcon(play_icon)
self.play_button.setIcon(self.play_icon)
else:
self.is_playing = True
self.controller.unpause_intrinsic_stream(self.port)
pause_icon = self.style().standardIcon(QStyle.SP_MediaPause)
self.play_button.setIcon(pause_icon)
self.play_button.setIcon(self.pause_icon)

def slider_moved(self, position):
self.controller.stream_jump_to(self.port, position)
if position == self.total_frames - 1:
self.controller.pause_intrinsic_stream(self.port)
self.is_playing = False
self.play_button.setEnabled(False)
self.play_button.setText("Play") # now paused so only option is play
self.play_button.setIcon(self.play_icon)
else:
if not self.play_button.isEnabled():
self.play_button.setEnabled(True)
Expand All @@ -213,9 +213,8 @@ def update_index(self, port, position):
self.controller.pause_intrinsic_stream(self.port)
self.is_playing = False
self.play_button.setEnabled(False)
self.play_button.setText(
"Play"
) # now paused so only option is play
# now paused so only option is play
self.play_button.setIcon(self.play_icon)

def update_image(self, port, pixmap):
logger.info(f"Running `update_image` in playback widget for port {self.port}")
Expand All @@ -236,10 +235,8 @@ def on_scale_change(self, value):
self.controller.stream_jump_to(self.port, self.index)

def calibrate(self):

self.controller.calibrate_camera(self.port)
self.toggle_distortion_changed(2)
self.toggle_distortion.setChecked(True)
# self.controller.stream_jump_to(self.port, self.index)

def clear_calibration_data(self):
self.controller.clear_calibration_data(self.port)
Expand Down
51 changes: 26 additions & 25 deletions pyxy3d/gui/frame_emitters/playback_frame_emitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,36 +56,37 @@ def run(self):
if not self.keep_collecting.is_set():
break

self.frame = frame_packet.frame_with_points
if frame_packet.frame is not None: # stream end signal when None frame placed on out queue
self.frame = frame_packet.frame_with_points

logger.info(f"Frame size is {self.frame.shape}")
logger.info(
f"Grid Capture History size is {self.grid_capture_history.shape}"
)
self.frame = cv2.addWeighted(self.frame, 1, self.grid_capture_history, 1, 0)
logger.info(f"Frame size is {self.frame.shape}")
logger.info(
f"Grid Capture History size is {self.grid_capture_history.shape}"
)
self.frame = cv2.addWeighted(self.frame, 1, self.grid_capture_history, 1, 0)

self._apply_undistortion()
self._apply_undistortion()

# cv2.imshow("emitted frame", self.frame)
# key = cv2.waitKey(1)
# if key == ord('q'):
# break
# cv2.imshow("emitted frame", self.frame)
# key = cv2.waitKey(1)
# if key == ord('q'):
# break


logger.info(f"Frame size is {self.frame.shape} following undistortion")
self.frame = resize_to_square(self.frame)
self.frame = apply_rotation(self.frame, self.stream.rotation_count)
image = cv2_to_qlabel(self.frame)
pixmap = QPixmap.fromImage(image)

if self.pixmap_edge_length:
pixmap = pixmap.scaled(
int(self.pixmap_edge_length),
int(self.pixmap_edge_length),
Qt.AspectRatioMode.KeepAspectRatio,
)
self.ImageBroadcast.emit(self.port, pixmap)
self.FrameIndexBroadcast.emit(self.port, frame_packet.frame_index)
logger.info(f"Frame size is {self.frame.shape} following undistortion")
self.frame = resize_to_square(self.frame)
self.frame = apply_rotation(self.frame, self.stream.rotation_count)
image = cv2_to_qlabel(self.frame)
pixmap = QPixmap.fromImage(image)

if self.pixmap_edge_length:
pixmap = pixmap.scaled(
int(self.pixmap_edge_length),
int(self.pixmap_edge_length),
Qt.AspectRatioMode.KeepAspectRatio,
)
self.ImageBroadcast.emit(self.port, pixmap)
self.FrameIndexBroadcast.emit(self.port, frame_packet.frame_index)

logger.info(
f"Thread loop within frame emitter at port {self.stream.port} successfully ended"
Expand Down
1 change: 0 additions & 1 deletion pyxy3d/gui/workspace_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ def connect_widgets(self):

def on_calibrate_btn_clicked(self):
logger.info("Calling controller to process extrinsic streams into 2D data")
self.controller.process_extrinsic_streams(fps_target=100)
# Call the extrinsic calibration method in the controller
self.controller.estimate_extrinsics()

Expand Down
2 changes: 1 addition & 1 deletion pyxy3d/intrinsic_stream_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def load_stream_tools(self):
port=camera.port,
rotation_count=camera.rotation_count,
tracker=self.tracker,
break_on_last=True,
break_on_last=False,
)

self.streams[camera.port] = stream
Expand Down
13 changes: 4 additions & 9 deletions tests/test_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,23 +60,18 @@ def test_extrinsic_calibration():
# calibration requires a capture volume object which is composed of both a camera array,
# and a set of point estimates
controller.load_camera_array()
controller.load_extrinsic_stream_manager()

# want to make sure that no previously stored data is leaking into this test

for cam in controller.camera_array.cameras.values():
cam.rotation = None
cam.translation = None

assert(not controller.camera_array.all_extrinsics_calibrated())
controller.process_extrinsic_streams(fps_target=100)

xy_path = Path(workspace,"calibration", "extrinsic", "CHARUCO", "xy_CHARUCO.csv")


while not xy_path.exists():
sleep(1)
logger.info(f"Waiting on data to populate in {xy_path}")
# xy_path = Path(workspace,"calibration", "extrinsic", "CHARUCO", "xy_CHARUCO.csv")
# while not xy_path.exists():
# sleep(1)
# logger.info(f"Waiting on data to populate in {xy_path}")

# with the charuco points tracked and saved out, the calibration can now proceed
controller.estimate_extrinsics()
Expand Down

0 comments on commit 95cfdb3

Please sign in to comment.